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.
This commit is contained in:
committed by
Nicolas Mervaillie
parent
4992f4760a
commit
bdaf6f7e8d
@@ -46,7 +46,7 @@ public class Neo4jAuditingRegistrar extends AuditingBeanDefinitionRegistrarSuppo
|
|||||||
|
|
||||||
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
|
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);
|
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(Neo4jMappingContextFactoryBean.class);
|
||||||
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||||
|
|||||||
@@ -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 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;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 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;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,13 @@
|
|||||||
|
|
||||||
package org.springframework.data.neo4j.auditing;
|
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.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.neo4j.ogm.session.SessionFactory;
|
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.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
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
|
* @author Frantisek Hartman
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
public class JavaConfigurationAuditingTest extends MultiDriverTestClass {
|
public class JavaConfigurationAuditingTests extends MultiDriverTestClass {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableNeo4jAuditing(modifyOnCreate = false)
|
@EnableNeo4jAuditing(modifyOnCreate = false)
|
||||||
@@ -81,7 +83,7 @@ public class JavaConfigurationAuditingTest extends MultiDriverTestClass {
|
|||||||
assertThat(loaded).isPresent();
|
assertThat(loaded).isPresent();
|
||||||
|
|
||||||
User found = loaded.get();
|
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.getCreatedBy()).isEqualTo("userId");
|
||||||
|
|
||||||
assertThat(found.getModified()).isNull();
|
assertThat(found.getModified()).isNull();
|
||||||
@@ -101,7 +103,7 @@ public class JavaConfigurationAuditingTest extends MultiDriverTestClass {
|
|||||||
|
|
||||||
User found = loaded.get();
|
User found = loaded.get();
|
||||||
|
|
||||||
assertThat(found.getModified()).isNotNull();
|
assertThat(found.getModified()).isNotNull().isCloseTo(LocalDateTime.now(), within(1, ChronoUnit.SECONDS));
|
||||||
assertThat(found.getModifiedBy()).isEqualTo("userId");
|
assertThat(found.getModifiedBy()).isEqualTo("userId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ include::preface.adoc[]
|
|||||||
include::new-features.adoc[]
|
include::new-features.adoc[]
|
||||||
include::{spring-data-commons-docs}/dependencies.adoc[]
|
include::{spring-data-commons-docs}/dependencies.adoc[]
|
||||||
include::{spring-data-commons-docs}/repositories.adoc[]
|
include::{spring-data-commons-docs}/repositories.adoc[]
|
||||||
|
include::{spring-data-commons-docs}/auditing.adoc[]
|
||||||
:leveloffset: -1
|
:leveloffset: -1
|
||||||
|
|
||||||
|
|
||||||
@@ -31,6 +32,9 @@ include::reference/introduction.adoc[]
|
|||||||
include::reference/getting-started.adoc[]
|
include::reference/getting-started.adoc[]
|
||||||
include::reference/ogm-support.adoc[]
|
include::reference/ogm-support.adoc[]
|
||||||
include::reference/neo4j-repositories.adoc[]
|
include::reference/neo4j-repositories.adoc[]
|
||||||
|
include::reference/projections.adoc[]
|
||||||
|
include::reference/auditing.adoc[]
|
||||||
|
|
||||||
:leveloffset: -1
|
:leveloffset: -1
|
||||||
|
|
||||||
[[ogm-reference-documentation]]
|
[[ogm-reference-documentation]]
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
* More flexible configuration.
|
* More flexible configuration.
|
||||||
* Better Java 8 support : all type queries can now return stream results and `Optional`. Better date / time management.
|
* 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.
|
* 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>>.
|
When migrating from 4.x, please see the <<migration,migration guide>>.
|
||||||
|
|
||||||
|
|||||||
7
src/main/asciidoc/reference/auditing.adoc
Normal file
7
src/main/asciidoc/reference/auditing.adoc
Normal 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.
|
||||||
Reference in New Issue
Block a user