DATAGRAPH-1031 Use custom IsNewStrategy in auditing.

also :
Add check on date intervals in tests.
Rename test to reintegrate it to tests run by CI.
Update docs.

(cherry picked from commit bdaf6f7)
This commit is contained in:
Frantisek Hartman
2017-09-27 08:52:31 +02:00
committed by Nicolas Mervaillie
parent dcbd5a6b4c
commit a72f467125
7 changed files with 142 additions and 12 deletions

View File

@@ -13,19 +13,18 @@
package org.springframework.data.neo4j.repository.config;
import java.lang.annotation.Annotation;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
import org.springframework.data.auditing.config.AuditingConfiguration;
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.neo4j.annotation.EnableNeo4jAuditing;
import org.springframework.util.Assert;
import java.lang.annotation.Annotation;
/**
* @author Frantisek Hartman
*/
@@ -46,7 +45,7 @@ public class Neo4jAuditingRegistrar extends AuditingBeanDefinitionRegistrarSuppo
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(Neo4jIsNewAwareAuditingHandler.class);
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(Neo4jMappingContextFactoryBean.class);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2002-2017 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product may include a number of subcomponents with
* separate copyright notices and license terms. Your use of the source
* code for these subcomponents is subject to the terms and
* conditions of the subcomponent's license, as noted in the LICENSE file.
*/
package org.springframework.data.neo4j.repository.config;
import java.util.Collections;
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.support.IsNewStrategy;
import org.springframework.data.support.IsNewStrategyFactory;
import org.springframework.util.Assert;
/**
* IsNewAwareAuditingHandler which overrides markAudited to provide our own Neo4jMappingContextIsNewStrategyFactory
*
* @author Frantisek Hartman
*/
public class Neo4jIsNewAwareAuditingHandler extends IsNewAwareAuditingHandler {
private IsNewStrategyFactory isNewStrategyFactory;
public Neo4jIsNewAwareAuditingHandler(MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>> mappingContext) {
this(new PersistentEntities(Collections.singletonList(mappingContext)));
}
public Neo4jIsNewAwareAuditingHandler(PersistentEntities entities) {
super(entities);
isNewStrategyFactory = new Neo4jMappingContextIsNewStrategyFactory(entities);
}
public void markAudited(Object object) {
Assert.notNull(object, "Source object must not be null!");
if (this.isAuditable(object)) {
IsNewStrategy strategy = this.isNewStrategyFactory.getIsNewStrategy(object.getClass());
if (strategy.isNew(object)) {
this.markCreated(object);
} else {
this.markModified(object);
}
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2002-2017 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product may include a number of subcomponents with
* separate copyright notices and license terms. Your use of the source
* code for these subcomponents is subject to the terms and
* conditions of the subcomponent's license, as noted in the LICENSE file.
*/
package org.springframework.data.neo4j.repository.config;
import java.util.Collections;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.support.IsNewStrategy;
import org.springframework.lang.Nullable;
/**
* Custom MappingContextIsNewStrategyFactory with overriden doGetIsNewStrategy
*
* @author Frantisek Hartman
*/
public class Neo4jMappingContextIsNewStrategyFactory extends MappingContextIsNewStrategyFactory {
private final PersistentEntities context;
public Neo4jMappingContextIsNewStrategyFactory(MappingContext<? extends PersistentEntity<?, ?>, ?> context) {
this(new PersistentEntities(Collections.singletonList(context)));
}
public Neo4jMappingContextIsNewStrategyFactory(PersistentEntities entities) {
super(entities);
this.context = entities;
}
@Nullable
@Override
protected IsNewStrategy doGetIsNewStrategy(Class<?> type) {
return new IsNewStrategy() {
@Override
public boolean isNew(Object o) {
PersistentEntity<?, ? extends PersistentProperty<?>> entity = context.getRequiredPersistentEntity(type);
PersistentProperty<? extends PersistentProperty<?>> property = entity.getRequiredIdProperty();
Object value = property.getOwner().getPropertyAccessor(o).getProperty(property);
return value == null || (value instanceof Long && ((Long) value) < 0);
}
};
}
}

View File

@@ -13,6 +13,13 @@
package org.springframework.data.neo4j.auditing;
import static java.util.Optional.*;
import static org.assertj.core.api.Assertions.*;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.ogm.session.SessionFactory;
@@ -29,17 +36,12 @@ import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Optional;
import static java.util.Optional.of;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Frantisek Hartman
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class JavaConfigurationAuditingTest extends MultiDriverTestClass {
public class JavaConfigurationAuditingTests extends MultiDriverTestClass {
@Configuration
@EnableNeo4jAuditing(modifyOnCreate = false)
@@ -81,7 +83,7 @@ public class JavaConfigurationAuditingTest extends MultiDriverTestClass {
assertThat(loaded).isPresent();
User found = loaded.get();
assertThat(found.getCreated()).isNotNull();
assertThat(found.getCreated()).isNotNull().isCloseTo(LocalDateTime.now(), within(1, ChronoUnit.SECONDS));
assertThat(found.getCreatedBy()).isEqualTo("userId");
assertThat(found.getModified()).isNull();
@@ -101,7 +103,7 @@ public class JavaConfigurationAuditingTest extends MultiDriverTestClass {
User found = loaded.get();
assertThat(found.getModified()).isNotNull();
assertThat(found.getModified()).isNotNull().isCloseTo(LocalDateTime.now(), within(1, ChronoUnit.SECONDS));
assertThat(found.getModifiedBy()).isEqualTo("userId");
}
}

View File

@@ -20,6 +20,7 @@ include::preface.adoc[]
include::new-features.adoc[]
include::{spring-data-commons-docs}/dependencies.adoc[]
include::{spring-data-commons-docs}/repositories.adoc[]
include::{spring-data-commons-docs}/auditing.adoc[]
:leveloffset: -1
@@ -31,6 +32,9 @@ include::reference/introduction.adoc[]
include::reference/getting-started.adoc[]
include::reference/ogm-support.adoc[]
include::reference/neo4j-repositories.adoc[]
include::reference/projections.adoc[]
include::reference/auditing.adoc[]
:leveloffset: -1
[[ogm-reference-documentation]]

View File

@@ -14,6 +14,7 @@
* More flexible configuration.
* Better Java 8 support : all type queries can now return stream results and `Optional`. Better date / time management.
* Internal metadata handling has been refactored for better reliability.
* Auditing support (since 5.0.1)
When migrating from 4.x, please see the <<migration,migration guide>>.

View File

@@ -0,0 +1,7 @@
[[reference_programming-auditing]]
=== Auditing
Spring Data Neo4j integrates into the Spring Data auditing infrastructure
to keep track of who created or changed an entity and the point in time this happened.
Please refer to the <<auditing,auditing>> section of the Spring Data reference.