Kaushal28
Kaushal28

Reputation: 5557

How to implement Auditing with DynamoDB in Spring Boot?

I've dynamoDB database, in which I've a table named user. I want to log auditing (CreatedBy, LastModifiedBy, CreatedDate, LastModifiedDate)in this table.

I've found JPA auditing (from here) and MongoDB auditing with annotations @EnableJpaAuditing and @EnableMongoAuditing respectively. But obviously they are not working with dynamoDB.

Here is my abstract class for auditing:

    @DynamoDBDocument
public abstract class PQSSAbstractAuditingEntity implements Serializable{
    @CreatedBy
    @JsonIgnore
    @DynamoDBAttribute
    private String createdBy;

    @LastModifiedBy
    @JsonIgnore
    @DynamoDBAttribute
    private String lastModifiedBy;

    @CreatedDate
    @JsonIgnore
    @DynamoDBAttribute
    private Date createdDate;

    @LastModifiedDate
    @JsonIgnore
    @DynamoDBAttribute
    private Date lastModifiedDate = new Date();

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public String getLastModifiedBy() {
        return lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public Date getLastModifiedDate() {
        return lastModifiedDate;
    }

    public void setLastModifiedDate(Date lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
}

I've assigned dates to respective fields but I've to set createdBy and lastModifiedBy depending on the logged in user. So I've to fetch the dynamically at runtime, when ever new entry is added into the database. I know how to set these fields statically but the problem is how to make annotations aware of these changes at run time.

As I mentioned, I've found AuditAware for JPA and mongo. I need the same for dynamoDB.

Any help will be appreciated. As I'm new to Spring boot.

Upvotes: 2

Views: 3514

Answers (2)

lhaidacher
lhaidacher

Reputation: 161

The question is already some years old but if somebody has also that problem, following solution works..

The problem is, that @EnableDynamoDBAuditing and @EnableDynamoDBRepositories don't work properly together. To solve this problem you have to add both annotations to you configuration class, create AuditorAware and DateTimeProvider beans and add all your entities/documents to your DynamoDBMappingContext manually.

PersistenceConfiguration.java

@Configuration
@EnableDynamoDBAuditing(auditorAwareRef = "userAuditing", dateTimeProviderRef = "dateAuditing")
@EnableDynamoDBRepositories(basePackages = "your.repository.package.name")
public class PersistenceConfiguration {

    @Bean
    public AuditorAware<String> userAuditing() {
        return () -> Optional.of("TestUser"); //get username from SecurityContext
    }

    @Bean
    public DateTimeProvider dateAuditing() {
        return CurrentDateTimeProvider.INSTANCE;
    }

    @Bean
    public DynamoDBMappingContext dynamoDBMappingContext() {
        DynamoDBMappingContext mappingContext = new DynamoDBMappingContext();

        //add your 'entities' manually 
        mappingContext.getPersistentEntity(YourEntity.class); 

        return mappingContext;
    }

    // do further configuration stuff...
}

YourEntity.java

@DynamoDBTable(tableName = "YourEntity")
public class YourEntity {
   @CreatedDate
   @DynamoDBAttribute
   @DynamoDBTypeConverted(converter = LocalDateTimeConverter.class)
   private LocalDateTime createdOn;

   @CreatedBy
   @DynamoDBAttribute
   private String createdBy;

   @LastModifiedDate
   @DynamoDBAttribute
   @DynamoDBTypeConverted(converter = LocalDateTimeConverter.class)
   private LocalDateTime updatedOn;

   @LastModifiedBy
   @DynamoDBAttribute
   private String updatedBy;

   // add further properties...
}

I know that there are some other solutions like @DynamoDBAutoGeneratedTimestamp and the usage of their strategies, but in my mind that's the cleanest solution regarding the use of spring.

Upvotes: 4

notionquest
notionquest

Reputation: 39186

The annotaion @DynamoDBAutoGeneratedTimestamp can be used along with DynamoDBAutoGenerateStrategy to audit the item.

Strategy CREATE (Use this for Create audit):-

@DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.CREATE)
 public Date getCreatedDate() { return createdDate; }
 public void setCreatedDate(Date createdDate) { this.createdDate = createdDate; }

Strategy ALWAYS (Use this if you want last modified date):-

 @DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.ALWAYS)
 public Date getLastUpdatedDate() { return lastUpdatedDate; }
 public void setLastUpdatedDate(Date lastUpdatedDate) { this.lastUpdatedDate = lastUpdatedDate; }

If you want both create timestamp and last modified timestamps, please create two different attributes. One attribute should use CREATE strategy and other one should use ALWAYS strategy.

AutoGeneratedTimeStamp

Upvotes: 2

Related Questions