Skip to content

Commit 6bafcea

Browse files
mp911dechristophstrobl
authored andcommitted
DATAMONGO-2586 - Add support for reactive auditing.
We now provide a fully reactive variant for auditing with EnableReactiveMongoAuditing. Original Pull Request: #877
1 parent 2c1a3cf commit 6bafcea

File tree

10 files changed

+300
-105
lines changed

10 files changed

+300
-105
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/EnableMongoAuditing.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
boolean modifyOnCreate() default true;
6262

6363
/**
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.
64+
* Configures a {@link DateTimeProvider} bean name that allows customizing the timestamp to be used for setting
65+
* creation and modification dates.
6666
*
6767
* @return empty {@link String} by default.
6868
*/
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.mongodb.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.ReactiveAuditorAware;
28+
29+
/**
30+
* Annotation to enable auditing in MongoDB using reactive infrastructure via annotation configuration.
31+
*
32+
* @author Mark Paluch
33+
* @since 3.1
34+
*/
35+
@Inherited
36+
@Documented
37+
@Target(ElementType.TYPE)
38+
@Retention(RetentionPolicy.RUNTIME)
39+
@Import(ReactiveMongoAuditingRegistrar.class)
40+
public @interface EnableReactiveMongoAuditing {
41+
42+
/**
43+
* Configures the {@link ReactiveAuditorAware} bean to be used to lookup the current principal.
44+
*
45+
* @return empty {@link String} by default.
46+
*/
47+
String auditorAwareRef() default "";
48+
49+
/**
50+
* Configures whether the creation and modification dates are set. Defaults to {@literal true}.
51+
*
52+
* @return {@literal true} by default.
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 {@literal true} by default.
60+
*/
61+
boolean modifyOnCreate() default true;
62+
63+
/**
64+
* Configures a {@link DateTimeProvider} bean name that allows customizing the timestamp to be used for setting
65+
* creation and modification dates.
66+
*
67+
* @return empty {@link String} by default.
68+
*/
69+
String dateTimeProviderRef() default "";
70+
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java

Lines changed: 1 addition & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
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;
@@ -28,14 +27,8 @@
2827
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
2928
import org.springframework.data.auditing.config.AuditingConfiguration;
3029
import org.springframework.data.config.ParsingUtils;
31-
import org.springframework.data.mapping.context.MappingContext;
32-
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
33-
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
34-
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
3530
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
36-
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
3731
import org.springframework.util.Assert;
38-
import org.springframework.util.ClassUtils;
3932

4033
/**
4134
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMongoAuditing} annotation.
@@ -46,9 +39,6 @@
4639
*/
4740
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
4841

49-
private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono",
50-
MongoAuditingRegistrar.class.getClassLoader());
51-
5242
/*
5343
* (non-Javadoc)
5444
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
@@ -91,7 +81,7 @@ protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingCon
9181

9282
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
9383

94-
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContextLookup.class);
84+
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
9585
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
9686

9787
builder.addConstructorArgValue(definition.getBeanDefinition());
@@ -116,68 +106,6 @@ protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandle
116106

117107
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
118108
AuditingEntityCallback.class.getName(), registry);
119-
120-
if (PROJECT_REACTOR_AVAILABLE) {
121-
registerReactiveAuditingEntityCallback(registry, auditingHandlerDefinition.getSource());
122-
}
123109
}
124110

125-
private void registerReactiveAuditingEntityCallback(BeanDefinitionRegistry registry, Object source) {
126-
127-
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
128-
129-
builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
130-
builder.getRawBeanDefinition().setSource(source);
131-
132-
registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(),
133-
registry);
134-
}
135-
136-
/**
137-
* Simple helper to be able to wire the {@link MappingContext} from a {@link MappingMongoConverter} bean available in
138-
* the application context.
139-
*
140-
* @author Oliver Gierke
141-
*/
142-
static class MongoMappingContextLookup
143-
implements FactoryBean<MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty>> {
144-
145-
private final MappingMongoConverter converter;
146-
147-
/**
148-
* Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}.
149-
*
150-
* @param converter must not be {@literal null}.
151-
*/
152-
public MongoMappingContextLookup(MappingMongoConverter converter) {
153-
this.converter = converter;
154-
}
155-
156-
/*
157-
* (non-Javadoc)
158-
* @see org.springframework.beans.factory.FactoryBean#getObject()
159-
*/
160-
@Override
161-
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getObject() throws Exception {
162-
return converter.getMappingContext();
163-
}
164-
165-
/*
166-
* (non-Javadoc)
167-
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
168-
*/
169-
@Override
170-
public Class<?> getObjectType() {
171-
return MappingContext.class;
172-
}
173-
174-
/*
175-
* (non-Javadoc)
176-
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
177-
*/
178-
@Override
179-
public boolean isSingleton() {
180-
return true;
181-
}
182-
}
183111
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2013-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.mongodb.config;
17+
18+
import org.springframework.beans.factory.FactoryBean;
19+
import org.springframework.data.mapping.context.PersistentEntities;
20+
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
21+
22+
/**
23+
* Simple helper to be able to wire the {@link PersistentEntities} from a {@link MappingMongoConverter} bean available
24+
* in the application context.
25+
*
26+
* @author Oliver Gierke
27+
* @author Mark Paluch
28+
*/
29+
class PersistentEntitiesFactoryBean implements FactoryBean<PersistentEntities> {
30+
31+
private final MappingMongoConverter converter;
32+
33+
/**
34+
* Creates a new {@link PersistentEntitiesFactoryBean} for the given {@link MappingMongoConverter}.
35+
*
36+
* @param converter must not be {@literal null}.
37+
*/
38+
public PersistentEntitiesFactoryBean(MappingMongoConverter converter) {
39+
this.converter = converter;
40+
}
41+
42+
/*
43+
* (non-Javadoc)
44+
* @see org.springframework.beans.factory.FactoryBean#getObject()
45+
*/
46+
@Override
47+
public PersistentEntities getObject() throws Exception {
48+
return PersistentEntities.of(converter.getMappingContext());
49+
}
50+
51+
/*
52+
* (non-Javadoc)
53+
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
54+
*/
55+
@Override
56+
public Class<?> getObjectType() {
57+
return PersistentEntities.class;
58+
}
59+
60+
/*
61+
* (non-Javadoc)
62+
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
63+
*/
64+
@Override
65+
public boolean isSingleton() {
66+
return true;
67+
}
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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.mongodb.config;
17+
18+
import java.lang.annotation.Annotation;
19+
20+
import org.springframework.beans.factory.config.BeanDefinition;
21+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
22+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
23+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
24+
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
25+
import org.springframework.core.type.AnnotationMetadata;
26+
import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler;
27+
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
28+
import org.springframework.data.auditing.config.AuditingConfiguration;
29+
import org.springframework.data.config.ParsingUtils;
30+
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
31+
import org.springframework.util.Assert;
32+
33+
/**
34+
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableReactiveMongoAuditing} annotation.
35+
*
36+
* @author Mark Paluch
37+
* @since 3.1
38+
*/
39+
class ReactiveMongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
40+
41+
/*
42+
* (non-Javadoc)
43+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
44+
*/
45+
@Override
46+
protected Class<? extends Annotation> getAnnotation() {
47+
return EnableReactiveMongoAuditing.class;
48+
}
49+
50+
/*
51+
* (non-Javadoc)
52+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
53+
*/
54+
@Override
55+
protected String getAuditingHandlerBeanName() {
56+
return "reactiveMongoAuditingHandler";
57+
}
58+
59+
/*
60+
* (non-Javadoc)
61+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
62+
*/
63+
@Override
64+
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
65+
66+
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
67+
68+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveIsNewAwareAuditingHandler.class);
69+
70+
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
71+
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
72+
73+
builder.addConstructorArgValue(definition.getBeanDefinition());
74+
return configureDefaultAuditHandlerAttributes(configuration, builder);
75+
}
76+
77+
/*
78+
* (non-Javadoc)
79+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)
80+
*/
81+
@Override
82+
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
83+
BeanDefinitionRegistry registry) {
84+
85+
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
86+
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
87+
88+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
89+
90+
builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
91+
builder.getRawBeanDefinition().setSource(auditingHandlerDefinition.getSource());
92+
93+
registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(),
94+
registry);
95+
}
96+
97+
}

0 commit comments

Comments
 (0)