Skip to content

Commit ddee81f

Browse files
authored
DATAES-886 - Complete reactive auditing.
Original PR: spring-projects#496
1 parent bdcecd0 commit ddee81f

File tree

9 files changed

+241
-135
lines changed

9 files changed

+241
-135
lines changed

src/main/asciidoc/reference/elasticsearch-auditing.adoc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
=== Preparing entities
55

6-
In order for the auditing code to be able to decide wether an entity instance is new, the entity must implement the `Persistable<ID>` interface which is defined as follows:
6+
In order for the auditing code to be able to decide whether an entity instance is new, the entity must implement the `Persistable<ID>` interface which is defined as follows:
77

88
[source,java]
99
----
@@ -52,7 +52,7 @@ public class Person implements Persistable<Long> {
5252

5353
=== Activating auditing
5454

55-
After the entities have been set up and providing the `AuditorAware` the Auditing must be activated by setting the `@EnableElasticsearchAuditing` on a configuration class:
55+
After the entities have been set up and providing the `AuditorAware` - or `ReactiveAuditorAware` - the Auditing must be activated by setting the `@EnableElasticsearchAuditing` on a configuration class:
5656

5757
[source,java]
5858
----
@@ -64,5 +64,16 @@ class MyConfiguration {
6464
}
6565
----
6666

67+
When using the reactive stack this must be:
68+
[source,java]
69+
----
70+
@Configuration
71+
@EnableReactiveElasticsearchRepositories
72+
@EnableReactiveElasticsearchAuditing
73+
class MyConfiguration {
74+
// configuration code
75+
}
76+
----
77+
6778
If your code contains more than one `AuditorAware` bean for different types, you must provide the name of the bean to use as an argument to the `auditorAwareRef` parameter of the
6879
`@EnableElasticsearchAuditing` annotation.

src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java

Lines changed: 3 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,16 @@
1717

1818
import java.lang.annotation.Annotation;
1919

20-
import org.springframework.beans.factory.FactoryBean;
2120
import org.springframework.beans.factory.config.BeanDefinition;
2221
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2322
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2423
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2524
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
26-
import org.springframework.core.type.AnnotationMetadata;
2725
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
2826
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
2927
import org.springframework.data.auditing.config.AuditingConfiguration;
3028
import org.springframework.data.config.ParsingUtils;
31-
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
3229
import org.springframework.data.elasticsearch.core.event.AuditingEntityCallback;
33-
import org.springframework.data.elasticsearch.core.event.ReactiveAuditingEntityCallback;
34-
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
35-
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
36-
import org.springframework.data.mapping.context.MappingContext;
37-
import org.springframework.data.repository.util.ReactiveWrappers;
3830
import org.springframework.util.Assert;
3931

4032
/**
@@ -45,137 +37,40 @@
4537
*/
4638
class ElasticsearchAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
4739

48-
/*
49-
* (non-Javadoc)
50-
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
51-
*/
5240
@Override
5341
protected Class<? extends Annotation> getAnnotation() {
5442
return EnableElasticsearchAuditing.class;
5543
}
5644

57-
/*
58-
* (non-Javadoc)
59-
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
60-
*/
6145
@Override
6246
protected String getAuditingHandlerBeanName() {
6347
return "elasticsearchAuditingHandler";
6448
}
6549

66-
/*
67-
* (non-Javadoc)
68-
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
69-
*/
70-
@Override
71-
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
72-
73-
Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!");
74-
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
75-
76-
super.registerBeanDefinitions(annotationMetadata, registry);
77-
}
78-
79-
/*
80-
* (non-Javadoc)
81-
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
82-
*/
8350
@Override
8451
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
8552

8653
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
8754

8855
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
8956

90-
BeanDefinitionBuilder definition = BeanDefinitionBuilder
91-
.genericBeanDefinition(ElasticsearchMappingContextLookup.class);
57+
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
9258
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
9359

9460
builder.addConstructorArgValue(definition.getBeanDefinition());
9561
return configureDefaultAuditHandlerAttributes(configuration, builder);
9662
}
9763

98-
/*
99-
* (non-Javadoc)
100-
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)
101-
*/
10264
@Override
10365
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
10466
BeanDefinitionRegistry registry) {
10567

10668
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
10769
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
10870

109-
BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder
110-
.rootBeanDefinition(AuditingEntityCallback.class);
111-
listenerBeanDefinitionBuilder
112-
.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
113-
114-
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
115-
AuditingEntityCallback.class.getName(), registry);
116-
117-
if (ReactiveWrappers.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR)) {
118-
registerReactiveAuditingEntityCallback(registry, auditingHandlerDefinition.getSource());
119-
}
120-
}
121-
122-
private void registerReactiveAuditingEntityCallback(BeanDefinitionRegistry registry, Object source) {
123-
124-
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
125-
71+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AuditingEntityCallback.class);
12672
builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
127-
builder.getRawBeanDefinition().setSource(source);
128-
129-
registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(),
130-
registry);
131-
}
132-
133-
/**
134-
* Simple helper to be able to wire the {@link MappingContext} from a {@link MappingElasticsearchConverter} bean
135-
* available in the application context.
136-
*
137-
* @author Oliver Gierke
138-
*/
139-
static class ElasticsearchMappingContextLookup implements
140-
FactoryBean<MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty>> {
141-
142-
private final MappingElasticsearchConverter converter;
143-
144-
/**
145-
* Creates a new {@link ElasticsearchMappingContextLookup} for the given {@link MappingElasticsearchConverter}.
146-
*
147-
* @param converter must not be {@literal null}.
148-
*/
149-
public ElasticsearchMappingContextLookup(MappingElasticsearchConverter converter) {
150-
this.converter = converter;
151-
}
152-
153-
/*
154-
* (non-Javadoc)
155-
* @see org.springframework.beans.factory.FactoryBean#getObject()
156-
*/
157-
@Override
158-
public MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> getObject()
159-
throws Exception {
160-
return converter.getMappingContext();
161-
}
162-
163-
/*
164-
* (non-Javadoc)
165-
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
166-
*/
167-
@Override
168-
public Class<?> getObjectType() {
169-
return MappingContext.class;
170-
}
17173

172-
/*
173-
* (non-Javadoc)
174-
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
175-
*/
176-
@Override
177-
public boolean isSingleton() {
178-
return true;
179-
}
74+
registerInfrastructureBeanWithId(builder.getBeanDefinition(), AuditingEntityCallback.class.getName(), registry);
18075
}
18176
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.elasticsearch.config;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Inherited;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import org.springframework.context.annotation.Import;
26+
import org.springframework.data.auditing.DateTimeProvider;
27+
import org.springframework.data.domain.AuditorAware;
28+
29+
/**
30+
* Annotation to enable auditing in Elasticsearch using reactive infrastructure via annotation configuration.
31+
*
32+
* @author Peter-Josef Meisch
33+
* @since 4.1
34+
*/
35+
@Inherited
36+
@Documented
37+
@Target(ElementType.TYPE)
38+
@Retention(RetentionPolicy.RUNTIME)
39+
@Import(ReactiveElasticsearchAuditingRegistrar.class)
40+
public @interface EnableReactiveElasticsearchAuditing {
41+
42+
/**
43+
* Configures the {@link AuditorAware} bean to be used to lookup the current principal.
44+
*
45+
* @return
46+
*/
47+
String auditorAwareRef() default "";
48+
49+
/**
50+
* Configures whether the creation and modification dates are set. Defaults to {@literal true}.
51+
*
52+
* @return
53+
*/
54+
boolean setDates() default true;
55+
56+
/**
57+
* Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}.
58+
*
59+
* @return
60+
*/
61+
boolean modifyOnCreate() default true;
62+
63+
/**
64+
* Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be
65+
* used for setting creation and modification dates.
66+
*
67+
* @return
68+
*/
69+
String dateTimeProviderRef() default "";
70+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.elasticsearch.config;
17+
18+
import org.springframework.beans.factory.FactoryBean;
19+
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
20+
import org.springframework.data.mapping.context.PersistentEntities;
21+
22+
/**
23+
* Simple helper to be able to wire the {@link PersistentEntities} from a {@link MappingElasticsearchConverter} bean
24+
* available in the application context.
25+
*
26+
* @author Oliver Gierke
27+
* @author Mark Paluch
28+
* @author Christoph Strobl
29+
* @author Peter-Josef Meisch
30+
* @since 4.1
31+
*/
32+
class PersistentEntitiesFactoryBean implements FactoryBean<PersistentEntities> {
33+
34+
private final MappingElasticsearchConverter converter;
35+
36+
/**
37+
* Creates a new {@link PersistentEntitiesFactoryBean} for the given {@link MappingElasticsearchConverter}.
38+
*
39+
* @param converter must not be {@literal null}.
40+
*/
41+
public PersistentEntitiesFactoryBean(MappingElasticsearchConverter converter) {
42+
this.converter = converter;
43+
}
44+
45+
@Override
46+
public PersistentEntities getObject() {
47+
return PersistentEntities.of(converter.getMappingContext());
48+
}
49+
50+
@Override
51+
public Class<?> getObjectType() {
52+
return PersistentEntities.class;
53+
}
54+
}

0 commit comments

Comments
 (0)