From 351d982c80264e35480ab9dd6794ad10422acf7e Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Thu, 21 Jul 2022 15:45:16 +0200 Subject: [PATCH] OZG-2542 ElasticSearchEventListener implementiert --- pluto-server/pom.xml | 15 ++- .../ozg/pluto/PlutoServerApplication.java | 4 + .../ElasticsearchIndexInitializer.java | 26 +++++ .../elastic/ElasticsearchProperties.java | 15 +++ .../common/elastic/ElasticsearchITCase.java | 24 +++++ .../ElasticsearchIndexInitializerITCase.java | 95 +++++++++++++++++++ ...lasticsearchIndexerEnabledInitializer.java | 4 +- .../elastic/ElasticsearchInitializer.java | 8 +- .../elastic/ElasticsearchServiceITCase.java | 55 +++++++++++ 9 files changed, 233 insertions(+), 13 deletions(-) create mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializer.java create mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchProperties.java create mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchITCase.java create mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializerITCase.java create mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchServiceITCase.java diff --git a/pluto-server/pom.xml b/pluto-server/pom.xml index d9f7b12ec..1a6ac7b29 100644 --- a/pluto-server/pom.xml +++ b/pluto-server/pom.xml @@ -27,9 +27,7 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <mongock.version>5.0.35</mongock.version> - <mongodb.testcontainer.version>1.15.3</mongodb.testcontainer.version> - <solr.testcontainer.version>1.16.2</solr.testcontainer.version> - <elasticsearch.testcontainer.version>1.17.3</elasticsearch.testcontainer.version> + <testcontainer.version>1.17.3</testcontainer.version> </properties> <dependencies> @@ -92,10 +90,11 @@ </dependency> <dependency> - <groupId>org.springframework.data</groupId> - <artifactId>spring-data-elasticsearch</artifactId> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> + <!-- aspectJ --> <dependency> <groupId>org.aspectj</groupId> @@ -216,19 +215,19 @@ <dependency> <groupId>org.testcontainers</groupId> <artifactId>mongodb</artifactId> - <version>${mongodb.testcontainer.version}</version> + <version>${testcontainer.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>solr</artifactId> - <version>${solr.testcontainer.version}</version> + <version>${testcontainer.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>elasticsearch</artifactId> - <version>${elasticsearch.testcontainer.version}</version> + <version>${testcontainer.version}</version> <scope>test</scope> </dependency> diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java index c3e9cbd21..db39b754c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java @@ -7,6 +7,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.security.authentication.AuthenticationTrustResolver; @@ -20,6 +22,8 @@ import io.mongock.runner.springboot.EnableMongock; @EnableAspectJAutoProxy(proxyTargetClass = true) @EnableMongock @ConfigurationPropertiesScan("de.itvsh.ozg.pluto.common.*") +@EnableMongoRepositories(basePackages = { "de.itvsh.ozg.pluto.vorgang", "de.itvsh.ozg.pluto.attached_item", "de.itvsh.ozg.pluto.command" }) +@EnableElasticsearchRepositories(basePackages = "de.itvsh.ozg.pluto.common.elastic") public class PlutoServerApplication { public static void main(String[] args) { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializer.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializer.java new file mode 100644 index 000000000..711f06530 --- /dev/null +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializer.java @@ -0,0 +1,26 @@ +package de.itvsh.ozg.pluto.common.elastic; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import de.itvsh.ozg.pluto.vorgang.VorgangService; + +@Component +@ConditionalOnProperty(prefix = "kop.elasticsearch", name = "initEnabled") +@Async +public class ElasticsearchIndexInitializer implements ApplicationListener<ContextRefreshedEvent> { + @Autowired + private VorgangService vorgangService; + + @Autowired + private ElasticsearchService searchService; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + vorgangService.getAll().forEach(vorgang -> searchService.addVorgang(vorgang)); + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchProperties.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchProperties.java new file mode 100644 index 000000000..1fd6b1420 --- /dev/null +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchProperties.java @@ -0,0 +1,15 @@ +package de.itvsh.ozg.pluto.common.elastic; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@ConfigurationProperties(prefix = "kop.elasticsearch") +public class ElasticsearchProperties { + private String host; + private String collectionName; + private boolean initEnabled = false; +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchITCase.java new file mode 100644 index 000000000..ac8621f0c --- /dev/null +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchITCase.java @@ -0,0 +1,24 @@ +package de.itvsh.ozg.pluto.common.elastic; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +import de.itvsh.kop.common.test.DataITCase; +import de.itvsh.kop.common.test.DbInitializer; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited + +@DataITCase +@ContextConfiguration(initializers = { ElasticsearchInitializer.class, DbInitializer.class }) +@ActiveProfiles({ "itcase", "with_db" }) +public @interface ElasticsearchITCase { + +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializerITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializerITCase.java new file mode 100644 index 000000000..4e4114294 --- /dev/null +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexInitializerITCase.java @@ -0,0 +1,95 @@ +package de.itvsh.ozg.pluto.common.elastic; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.io.IOException; + +import org.apache.solr.client.solrj.SolrServerException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +import de.itvsh.kop.common.test.DbInitializer; +import de.itvsh.kop.common.test.ITCase; +import de.itvsh.ozg.pluto.vorgang.Vorgang; +import de.itvsh.ozg.pluto.vorgang.VorgangService; +import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; + +class ElasticsearchIndexInitializerITCase { + private static final int FOR_500_MS = 500; + + @Nested + @ITCase + class TestNotConfigured { + @MockBean + private ElasticsearchService elasticsearchService; + + @MockBean + private VorgangService vorgangService; + + @Test + void shouldNotStartIndexer() throws SolrServerException, IOException { + verify(vorgangService, after(FOR_500_MS).never()).getAll(); + verify(elasticsearchService, after(FOR_500_MS).never()).addVorgang(any()); + } + } + + @Nested + @ElasticsearchITCase + class TestConfiguredNotEnabled { + + @MockBean + private ElasticsearchService elasticService; + + @MockBean + private VorgangService vorgangService; + + @Test + void shouldNotStartIndexer() throws SolrServerException, IOException { + verify(vorgangService, after(FOR_500_MS).never()).getAll(); + verify(elasticService, after(FOR_500_MS).never()).updateVorgang(any()); + } + } + + @Nested + @ITCase + @ContextConfiguration(initializers = { DbInitializer.class, ElasticsearchIndexerEnabledInitializer.class }) + @ActiveProfiles({ "itcase", "with_db" }) + class TestConfiguredEnabled { + @MockBean + private ElasticsearchService elasticService; + + @Autowired + private ElasticsearchIndexInitializer elasticsearchInitializer; + + @Autowired + private MongoOperations mongoOperations; + + @BeforeEach + void init() { + mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); + + mongoOperations.createCollection(Vorgang.COLLECTION_NAME); + } + + @Test + void shouldNotStartIndexerWhenNoVorgang() throws SolrServerException, IOException { + verify(elasticService, after(FOR_500_MS).never()).addVorgang(any()); + } + + @Test + void shouldStartIndexer() throws SolrServerException, IOException { + mongoOperations.save(VorgangTestFactory.create()); + + elasticsearchInitializer.onApplicationEvent(null); + + verify(elasticService, after(FOR_500_MS)).addVorgang(any()); + } + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexerEnabledInitializer.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexerEnabledInitializer.java index a8024d2e5..8f6ec24da 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexerEnabledInitializer.java +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchIndexerEnabledInitializer.java @@ -4,11 +4,11 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ConfigurableApplicationContext; import org.testcontainers.elasticsearch.ElasticsearchContainer; -public class ElasticsearchIndexerEnabledInitializer extends ElasticsearchInitializer { +class ElasticsearchIndexerEnabledInitializer extends ElasticsearchInitializer { @Override protected void setProperties(ElasticsearchContainer container, ConfigurableApplicationContext applicationContext) { super.setProperties(container, applicationContext); - TestPropertyValues.of("kop.elasticsearch.initEnabled=true"); + TestPropertyValues.of("kop.elasticsearch.initEnabled=true").applyTo(applicationContext.getEnvironment()); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchInitializer.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchInitializer.java index b8ed48af0..8180a45a8 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchInitializer.java +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchInitializer.java @@ -4,18 +4,20 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.testcontainers.elasticsearch.ElasticsearchContainer; +import org.testcontainers.utility.DockerImageName; import lombok.AccessLevel; import lombok.Getter; -public class ElasticsearchInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { - private static final String ELASTICSEARCH_VERSIION = "docker.elastic.co/elasticsearch/elasticsearch:8.3.2"; +class ElasticsearchInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { + private static final String ELASTICSEARCH_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch"; + private static final String ELASTICSEARCH_VERSION = "8.3.2"; @Getter(value = AccessLevel.PROTECTED) private ElasticsearchContainer elasticsearchContainer; @Override public void initialize(ConfigurableApplicationContext applicationContext) { - elasticsearchContainer = new ElasticsearchContainer(ELASTICSEARCH_VERSIION); + elasticsearchContainer = new ElasticsearchContainer(DockerImageName.parse(ELASTICSEARCH_IMAGE).withTag(ELASTICSEARCH_VERSION)); elasticsearchContainer.start(); setProperties(elasticsearchContainer, applicationContext); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchServiceITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchServiceITCase.java new file mode 100644 index 000000000..d71b50762 --- /dev/null +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/elastic/ElasticsearchServiceITCase.java @@ -0,0 +1,55 @@ +package de.itvsh.ozg.pluto.common.elastic; + +import static org.mockito.Mockito.*; + +import java.io.IOException; +import java.util.Optional; + +import org.apache.solr.client.solrj.SolrServerException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.mongodb.core.MongoOperations; + +import de.itvsh.ozg.pluto.command.Command; +import de.itvsh.ozg.pluto.command.CommandService; +import de.itvsh.ozg.pluto.command.CommandTestFactory; +import de.itvsh.ozg.pluto.vorgang.Vorgang; +import de.itvsh.ozg.pluto.vorgang.VorgangService; + +@ElasticsearchITCase +public class ElasticsearchServiceITCase { + @Autowired + private ElasticsearchService elasticsearchService; + + @Autowired + private VorgangService vorgangService; + + @Autowired + private MongoOperations mongoOperations; + + @MockBean + private CommandService commandService; + + @Autowired + private ElasticsearchProperties elasticsearchProperties; + + @BeforeEach + void init() { + Command cmd = CommandTestFactory.createBuilder().build(); + when(commandService.findCommand(CommandTestFactory.ID)).thenReturn(Optional.of(cmd)); + + mongoOperations.remove(Vorgang.class); + } + + @Nested + class TestAddVorgang { + @Test + void shouldAdd() throws SolrServerException, IOException { + elasticsearchService.addVorgang(null); + } + } + +} -- GitLab