From fe9bbaec5684c41212be66b4ccd20255bcb4e0af Mon Sep 17 00:00:00 2001 From: Anastasiia Smirnova Date: Thu, 31 Mar 2022 13:24:17 +0200 Subject: [PATCH] fix circular dependency for AerospikePersistenceEntityIndexCreator (#357) * fix circular dependency for AerospikePersistenceEntityIndexCreator * fix circular dependency for AerospikePersistenceEntityIndexCreator --- pom.xml | 4 +- .../AbstractAerospikeDataConfiguration.java | 7 ++- ...actReactiveAerospikeDataConfiguration.java | 7 ++- .../AerospikeDataConfigurationSupport.java | 9 +++- .../config/AerospikeDataSettings.java | 2 + ...erospikePersistenceEntityIndexCreator.java | 7 ++- ...erospikePersistenceEntityIndexCreator.java | 54 ++++++++++++++----- ...erospikePersistenceEntityIndexCreator.java | 7 ++- .../mapping/AerospikeMappingContext.java | 14 ----- ...pikePersistenceEntityIndexCreatorTest.java | 12 +++-- ...pikePersistenceEntityIndexCreatorTest.java | 11 ++-- src/test/resources/logback-test.xml | 2 +- 12 files changed, 88 insertions(+), 48 deletions(-) diff --git a/pom.xml b/pom.xml index 8b63c807f..d4f7611c1 100644 --- a/pom.xml +++ b/pom.xml @@ -25,8 +25,8 @@ 1.8 2.6.3 2.6.3 - 3.0.4 - 2.5.6 + 3.1.1 + 2.6.5 3.3.0 1.6 5.1.11 diff --git a/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java b/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java index 20defcf02..042b39976 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java +++ b/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java @@ -16,12 +16,14 @@ package org.springframework.data.aerospike.config; import com.aerospike.client.IAerospikeClient; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.data.aerospike.convert.MappingAerospikeConverter; import org.springframework.data.aerospike.core.AerospikeExceptionTranslator; import org.springframework.data.aerospike.core.AerospikeTemplate; +import org.springframework.data.aerospike.index.AerospikeIndexResolver; import org.springframework.data.aerospike.index.AerospikePersistenceEntityIndexCreator; import org.springframework.data.aerospike.mapping.AerospikeMappingContext; import org.springframework.data.aerospike.query.FilterExpressionsBuilder; @@ -55,9 +57,10 @@ public QueryEngine queryEngine(IAerospikeClient aerospikeClient, } @Bean - public AerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator(AerospikeMappingContext aerospikeMappingContext, + public AerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator(ObjectProvider aerospikeMappingContext, + AerospikeIndexResolver aerospikeIndexResolver, @Lazy AerospikeTemplate template) { - return new AerospikePersistenceEntityIndexCreator(aerospikeMappingContext, template); + return new AerospikePersistenceEntityIndexCreator(aerospikeMappingContext, aerospikeDataSettings().isCreateIndexesOnStartup(), aerospikeIndexResolver, template); } @Bean(name = "aerospikeIndexRefresher") diff --git a/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java b/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java index 8fc46cd05..166d3cce7 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java +++ b/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java @@ -19,12 +19,14 @@ import com.aerospike.client.async.EventLoops; import com.aerospike.client.policy.ClientPolicy; import com.aerospike.client.reactor.AerospikeReactorClient; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.data.aerospike.convert.MappingAerospikeConverter; import org.springframework.data.aerospike.core.AerospikeExceptionTranslator; import org.springframework.data.aerospike.core.ReactiveAerospikeTemplate; +import org.springframework.data.aerospike.index.AerospikeIndexResolver; import org.springframework.data.aerospike.index.ReactiveAerospikePersistenceEntityIndexCreator; import org.springframework.data.aerospike.mapping.AerospikeMappingContext; import org.springframework.data.aerospike.query.FilterExpressionsBuilder; @@ -87,8 +89,9 @@ protected ClientPolicy getClientPolicy() { @Bean public ReactiveAerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator( - AerospikeMappingContext aerospikeMappingContext, + ObjectProvider aerospikeMappingContext, + AerospikeIndexResolver aerospikeIndexResolver, @Lazy ReactiveAerospikeTemplate template) { - return new ReactiveAerospikePersistenceEntityIndexCreator(aerospikeMappingContext, template); + return new ReactiveAerospikePersistenceEntityIndexCreator(aerospikeMappingContext, aerospikeDataSettings().isCreateIndexesOnStartup(), aerospikeIndexResolver, template); } } diff --git a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java index d2b5545fb..4228b8f9c 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java +++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java @@ -28,6 +28,7 @@ import org.springframework.data.aerospike.convert.MappingAerospikeConverter; import org.springframework.data.aerospike.core.AerospikeExceptionTranslator; import org.springframework.data.aerospike.core.DefaultAerospikeExceptionTranslator; +import org.springframework.data.aerospike.index.AerospikeIndexResolver; import org.springframework.data.aerospike.mapping.AerospikeMappingContext; import org.springframework.data.aerospike.mapping.AerospikeSimpleTypes; import org.springframework.data.aerospike.mapping.Document; @@ -86,7 +87,6 @@ public AerospikeMappingContext aerospikeMappingContext() throws Exception { context.setInitialEntitySet(getInitialEntitySet()); context.setSimpleTypeHolder(AerospikeSimpleTypes.HOLDER); context.setFieldNamingStrategy(fieldNamingStrategy()); - context.setCreateIndexesOnStartup(isCreateIndexesOnStartup()); return context; } @@ -106,6 +106,12 @@ public FilterExpressionsBuilder filterExpressionsBuilder() { return new FilterExpressionsBuilder(); } + + @Bean(name = "aerospikeIndexResolver") + public AerospikeIndexResolver aerospikeIndexResolver() { + return new AerospikeIndexResolver(); + } + protected Set> getInitialEntitySet() throws ClassNotFoundException { String basePackage = getMappingBasePackage(); Set> initialEntitySet = new HashSet<>(); @@ -147,6 +153,7 @@ protected AerospikeDataSettings aerospikeDataSettings() { protected void configureDataSettings(AerospikeDataSettings.AerospikeDataSettingsBuilder builder) { builder.scansEnabled(false); builder.sendKey(true); + builder.createIndexesOnStartup(isCreateIndexesOnStartup()); } protected ClientPolicy getClientPolicy() { diff --git a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java index f840bd44c..4c31738a9 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java +++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java @@ -26,6 +26,8 @@ public class AerospikeDataSettings { boolean scansEnabled = false; @Builder.Default boolean sendKey = true; + @Builder.Default + boolean createIndexesOnStartup = true; /* * (non-Javadoc) diff --git a/src/main/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreator.java b/src/main/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreator.java index 8d338e59f..3e93e50bf 100644 --- a/src/main/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreator.java +++ b/src/main/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreator.java @@ -18,6 +18,7 @@ package org.springframework.data.aerospike.index; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.data.aerospike.IndexAlreadyExistsException; import org.springframework.data.aerospike.core.AerospikeTemplate; import org.springframework.data.aerospike.mapping.AerospikeMappingContext; @@ -32,9 +33,11 @@ public class AerospikePersistenceEntityIndexCreator extends BaseAerospikePersist private final AerospikeTemplate template; - public AerospikePersistenceEntityIndexCreator(AerospikeMappingContext aerospikeMappingContext, + public AerospikePersistenceEntityIndexCreator(ObjectProvider mappingContext, + boolean createIndexesOnStartup, + AerospikeIndexResolver aerospikeIndexResolver, AerospikeTemplate template) { - super(aerospikeMappingContext); + super(mappingContext, createIndexesOnStartup, aerospikeIndexResolver); this.template = template; } diff --git a/src/main/java/org/springframework/data/aerospike/index/BaseAerospikePersistenceEntityIndexCreator.java b/src/main/java/org/springframework/data/aerospike/index/BaseAerospikePersistenceEntityIndexCreator.java index 2d8048981..f8c292da4 100644 --- a/src/main/java/org/springframework/data/aerospike/index/BaseAerospikePersistenceEntityIndexCreator.java +++ b/src/main/java/org/springframework/data/aerospike/index/BaseAerospikePersistenceEntityIndexCreator.java @@ -18,11 +18,14 @@ package org.springframework.data.aerospike.index; import lombok.RequiredArgsConstructor; +import lombok.Value; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.ApplicationListener; import org.springframework.context.SmartLifecycle; import org.springframework.data.aerospike.mapping.AerospikeMappingContext; import org.springframework.data.aerospike.mapping.BasicAerospikePersistentEntity; +import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContextEvent; import java.util.HashSet; @@ -36,31 +39,35 @@ @RequiredArgsConstructor public abstract class BaseAerospikePersistenceEntityIndexCreator implements ApplicationListener> , SmartLifecycle { - private final AerospikeIndexResolver aerospikeIndexDetector = new AerospikeIndexResolver(); - private final AerospikeMappingContext aerospikeMappingContext; - private final Set initialIndexes = new HashSet<>(); + private final ObjectProvider mappingContext; + private final boolean createIndexesOnStartup; + private final AerospikeIndexResolver aerospikeIndexResolver; + private final Set initialIndexes = new HashSet<>(); private final AtomicBoolean initialized = new AtomicBoolean(false); @Override public void onApplicationEvent(MappingContextEvent event) { - if (!aerospikeMappingContext.isCreateIndexesOnStartup()) { + if (!createIndexesOnStartup) { return; } - if (!event.wasEmittedBy(aerospikeMappingContext)) { + Object source = event.getSource(); + if (!(source instanceof AerospikeMappingContext)) { return; } - - aerospikeMappingContext.setAerospikeIndexResolverEnvironment(aerospikeIndexDetector); - BasicAerospikePersistentEntity persistentEntity = (BasicAerospikePersistentEntity) event.getPersistentEntity(); - Set indexes = aerospikeIndexDetector.detectIndexes(persistentEntity); + PersistentEntity entity = event.getPersistentEntity(); + if (!(entity instanceof BasicAerospikePersistentEntity)) { + return; + } + BasicAerospikePersistentEntity persistentEntity = (BasicAerospikePersistentEntity) entity; + Set indexes = aerospikeIndexResolver.detectIndexes(persistentEntity); if (!indexes.isEmpty()) { if (!initialized.get()) { //gh-115: prevent creating indexes on startup phase when aerospike template have not been created yet - initialIndexes.addAll(indexes); + initialIndexes.add(new IndexesEvent(indexes, event)); return; } - log.debug("Creating {} indexes for entity[{}]...", indexes, event.getPersistentEntity().getName()); + log.debug("Creating {} indexes for entity[{}]...", indexes, entity.getName()); installIndexes(indexes); } } @@ -68,10 +75,26 @@ public void onApplicationEvent(MappingContextEvent event) { @Override public void start() { initialized.set(true); - installIndexes(initialIndexes); + initialIndexes + .forEach(event -> { + AerospikeMappingContext mappingContext = getMappingContext(); + if (event.getEvent().wasEmittedBy(mappingContext)) { + // process this event + installIndexes(event.getIndexes()); + } + }); + initialIndexes.clear(); } + private AerospikeMappingContext getMappingContext() { + AerospikeMappingContext mappingContext = this.mappingContext.getIfUnique(); + if(mappingContext == null) { + throw new IllegalStateException("AerospikeMappingContext bean is not available in context OR is not unique"); + } + return mappingContext; + } + protected abstract void installIndexes(Set indexes); @Override @@ -82,4 +105,11 @@ public void stop() { public boolean isRunning() { return initialized.get(); } + + @Value + private static class IndexesEvent { + Set indexes; + MappingContextEvent event; + } + } diff --git a/src/main/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreator.java b/src/main/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreator.java index b0937d091..8f24a9416 100644 --- a/src/main/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreator.java +++ b/src/main/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreator.java @@ -18,6 +18,7 @@ package org.springframework.data.aerospike.index; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.data.aerospike.IndexAlreadyExistsException; import org.springframework.data.aerospike.core.ReactiveAerospikeTemplate; import org.springframework.data.aerospike.mapping.AerospikeMappingContext; @@ -34,9 +35,11 @@ public class ReactiveAerospikePersistenceEntityIndexCreator extends BaseAerospik private final ReactiveAerospikeTemplate template; - public ReactiveAerospikePersistenceEntityIndexCreator(AerospikeMappingContext aerospikeMappingContext, + public ReactiveAerospikePersistenceEntityIndexCreator(ObjectProvider mappingContext, + boolean createIndexesOnStartup, + AerospikeIndexResolver aerospikeIndexResolver, ReactiveAerospikeTemplate template) { - super(aerospikeMappingContext); + super(mappingContext, createIndexesOnStartup, aerospikeIndexResolver); this.template = template; } diff --git a/src/main/java/org/springframework/data/aerospike/mapping/AerospikeMappingContext.java b/src/main/java/org/springframework/data/aerospike/mapping/AerospikeMappingContext.java index 0640ba60b..7fd24f045 100644 --- a/src/main/java/org/springframework/data/aerospike/mapping/AerospikeMappingContext.java +++ b/src/main/java/org/springframework/data/aerospike/mapping/AerospikeMappingContext.java @@ -40,7 +40,6 @@ public class AerospikeMappingContext extends private FieldNamingStrategy fieldNamingStrategy = DEFAULT_NAMING_STRATEGY; private ApplicationContext context; - private boolean createIndexesOnStartup; /** * Configures the {@link FieldNamingStrategy} to be used to determine the field name if no manual mapping is applied. @@ -73,17 +72,4 @@ public void setApplicationContext(ApplicationContext applicationContext) throws this.context = applicationContext; } - public void setCreateIndexesOnStartup(boolean createIndexesOnStartup) { - this.createIndexesOnStartup = createIndexesOnStartup; - } - - public boolean isCreateIndexesOnStartup() { - return createIndexesOnStartup; - } - - public void setAerospikeIndexResolverEnvironment(AerospikeIndexResolver aerospikeIndexResolver) { - if (context != null) { - aerospikeIndexResolver.setEnvironment(context.getEnvironment()); - } - } } diff --git a/src/test/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreatorTest.java b/src/test/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreatorTest.java index 16441510b..c66484608 100644 --- a/src/test/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreatorTest.java +++ b/src/test/java/org/springframework/data/aerospike/index/AerospikePersistenceEntityIndexCreatorTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.aerospike.IndexAlreadyExistsException; import org.springframework.data.aerospike.core.AerospikeTemplate; @@ -16,16 +17,17 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -@ExtendWith(MockitoExtension.class) class AerospikePersistenceEntityIndexCreatorTest { - @Mock - AerospikeTemplate template; + boolean createIndexesOnStartup = true; + AerospikeIndexResolver aerospikeIndexResolver = mock(AerospikeIndexResolver.class); + AerospikeTemplate template = mock(AerospikeTemplate.class); - @InjectMocks - AerospikePersistenceEntityIndexCreator creator; + AerospikePersistenceEntityIndexCreator creator = + new AerospikePersistenceEntityIndexCreator(null, createIndexesOnStartup, aerospikeIndexResolver, template); String name = "someName"; String fieldName = "fieldName"; diff --git a/src/test/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreatorTest.java b/src/test/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreatorTest.java index dc647e2be..9e3bc53e9 100644 --- a/src/test/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreatorTest.java +++ b/src/test/java/org/springframework/data/aerospike/index/ReactiveAerospikePersistenceEntityIndexCreatorTest.java @@ -16,16 +16,17 @@ import java.util.Set; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -@ExtendWith(MockitoExtension.class) class ReactiveAerospikePersistenceEntityIndexCreatorTest { - @Mock - ReactiveAerospikeTemplate template; + boolean createIndexesOnStartup = true; + AerospikeIndexResolver aerospikeIndexResolver = mock(AerospikeIndexResolver.class); + ReactiveAerospikeTemplate template = mock(ReactiveAerospikeTemplate.class); - @InjectMocks - ReactiveAerospikePersistenceEntityIndexCreator creator; + ReactiveAerospikePersistenceEntityIndexCreator creator = + new ReactiveAerospikePersistenceEntityIndexCreator(null, createIndexesOnStartup, aerospikeIndexResolver, template); String name = "someName"; String fieldName = "fieldName"; diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index d87435abe..162aceffe 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -15,7 +15,7 @@ - + \ No newline at end of file