Skip to content

Commit

Permalink
fix circular dependency for AerospikePersistenceEntityIndexCreator (#357
Browse files Browse the repository at this point in the history
)

* fix circular dependency for AerospikePersistenceEntityIndexCreator

* fix circular dependency for AerospikePersistenceEntityIndexCreator
  • Loading branch information
Aloren authored Mar 31, 2022
1 parent c7a2c97 commit fe9bbae
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 48 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
<maven.compiler.target>1.8</maven.compiler.target>
<springdata.commons>2.6.3</springdata.commons>
<springdata.keyvalue>2.6.3</springdata.keyvalue>
<spring-cloud-starter-bootstrap>3.0.4</spring-cloud-starter-bootstrap>
<spring-boot-starter-test>2.5.6</spring-boot-starter-test>
<spring-cloud-starter-bootstrap>3.1.1</spring-cloud-starter-bootstrap>
<spring-boot-starter-test>2.6.5</spring-boot-starter-test>
<maven.javadoc.plugin>3.3.0</maven.javadoc.plugin>
<maven.gpg.plugin>1.6</maven.gpg.plugin>
<aerospike>5.1.11</aerospike>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -55,9 +57,10 @@ public QueryEngine queryEngine(IAerospikeClient aerospikeClient,
}

@Bean
public AerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator(AerospikeMappingContext aerospikeMappingContext,
public AerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator(ObjectProvider<AerospikeMappingContext> aerospikeMappingContext,
AerospikeIndexResolver aerospikeIndexResolver,
@Lazy AerospikeTemplate template) {
return new AerospikePersistenceEntityIndexCreator(aerospikeMappingContext, template);
return new AerospikePersistenceEntityIndexCreator(aerospikeMappingContext, aerospikeDataSettings().isCreateIndexesOnStartup(), aerospikeIndexResolver, template);
}

@Bean(name = "aerospikeIndexRefresher")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -87,8 +89,9 @@ protected ClientPolicy getClientPolicy() {

@Bean
public ReactiveAerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator(
AerospikeMappingContext aerospikeMappingContext,
ObjectProvider<AerospikeMappingContext> aerospikeMappingContext,
AerospikeIndexResolver aerospikeIndexResolver,
@Lazy ReactiveAerospikeTemplate template) {
return new ReactiveAerospikePersistenceEntityIndexCreator(aerospikeMappingContext, template);
return new ReactiveAerospikePersistenceEntityIndexCreator(aerospikeMappingContext, aerospikeDataSettings().isCreateIndexesOnStartup(), aerospikeIndexResolver, template);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -86,7 +87,6 @@ public AerospikeMappingContext aerospikeMappingContext() throws Exception {
context.setInitialEntitySet(getInitialEntitySet());
context.setSimpleTypeHolder(AerospikeSimpleTypes.HOLDER);
context.setFieldNamingStrategy(fieldNamingStrategy());
context.setCreateIndexesOnStartup(isCreateIndexesOnStartup());
return context;
}

Expand All @@ -106,6 +106,12 @@ public FilterExpressionsBuilder filterExpressionsBuilder() {
return new FilterExpressionsBuilder();
}


@Bean(name = "aerospikeIndexResolver")
public AerospikeIndexResolver aerospikeIndexResolver() {
return new AerospikeIndexResolver();
}

protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
String basePackage = getMappingBasePackage();
Set<Class<?>> initialEntitySet = new HashSet<>();
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class AerospikeDataSettings {
boolean scansEnabled = false;
@Builder.Default
boolean sendKey = true;
@Builder.Default
boolean createIndexesOnStartup = true;

/*
* (non-Javadoc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,9 +33,11 @@ public class AerospikePersistenceEntityIndexCreator extends BaseAerospikePersist

private final AerospikeTemplate template;

public AerospikePersistenceEntityIndexCreator(AerospikeMappingContext aerospikeMappingContext,
public AerospikePersistenceEntityIndexCreator(ObjectProvider<AerospikeMappingContext> mappingContext,
boolean createIndexesOnStartup,
AerospikeIndexResolver aerospikeIndexResolver,
AerospikeTemplate template) {
super(aerospikeMappingContext);
super(mappingContext, createIndexesOnStartup, aerospikeIndexResolver);
this.template = template;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -36,42 +39,62 @@
@RequiredArgsConstructor
public abstract class BaseAerospikePersistenceEntityIndexCreator implements ApplicationListener<MappingContextEvent<?, ?>> , SmartLifecycle {

private final AerospikeIndexResolver aerospikeIndexDetector = new AerospikeIndexResolver();
private final AerospikeMappingContext aerospikeMappingContext;
private final Set<AerospikeIndexDefinition> initialIndexes = new HashSet<>();
private final ObjectProvider<AerospikeMappingContext> mappingContext;
private final boolean createIndexesOnStartup;
private final AerospikeIndexResolver aerospikeIndexResolver;
private final Set<IndexesEvent> 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<AerospikeIndexDefinition> indexes = aerospikeIndexDetector.detectIndexes(persistentEntity);
PersistentEntity<?, ?> entity = event.getPersistentEntity();
if (!(entity instanceof BasicAerospikePersistentEntity)) {
return;
}
BasicAerospikePersistentEntity<?> persistentEntity = (BasicAerospikePersistentEntity<?>) entity;
Set<AerospikeIndexDefinition> 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);
}
}

@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<AerospikeIndexDefinition> indexes);

@Override
Expand All @@ -82,4 +105,11 @@ public void stop() {
public boolean isRunning() {
return initialized.get();
}

@Value
private static class IndexesEvent {
Set<AerospikeIndexDefinition> indexes;
MappingContextEvent<?, ?> event;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -34,9 +35,11 @@ public class ReactiveAerospikePersistenceEntityIndexCreator extends BaseAerospik

private final ReactiveAerospikeTemplate template;

public ReactiveAerospikePersistenceEntityIndexCreator(AerospikeMappingContext aerospikeMappingContext,
public ReactiveAerospikePersistenceEntityIndexCreator(ObjectProvider<AerospikeMappingContext> mappingContext,
boolean createIndexesOnStartup,
AerospikeIndexResolver aerospikeIndexResolver,
ReactiveAerospikeTemplate template) {
super(aerospikeMappingContext);
super(mappingContext, createIndexesOnStartup, aerospikeIndexResolver);
this.template = template;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<logger name="org.springframework.data.aerospike" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<logger name="com.playtika.test.aerospike.EmbeddedAerospikeBootstrapConfiguration" level="DEBUG" additivity="false">
<logger name="com.playtika.test.aerospike.EmbeddedAerospikeBootstrapConfiguration" level="WARN" additivity="false">
<appender-ref ref="aerospike"/>
</logger>
</configuration>

0 comments on commit fe9bbae

Please sign in to comment.