From 8e1fd3f8758d5f67be01d29cb57b093db165abdb Mon Sep 17 00:00:00 2001 From: Artem Sidorkin Date: Tue, 27 Jul 2021 19:16:58 +0300 Subject: [PATCH] Improved saga instance repository test. --- .../ReactiveSagaInstanceRepositoryJdbc.java | 8 +-- ...eactiveSagaInstanceRepositoryJdbcTest.java | 48 ------------- .../build.gradle | 7 ++ ...InstanceRepositoryJdbcIntegrationTest.java | 70 ++++++++++++++++--- 4 files changed, 68 insertions(+), 65 deletions(-) delete mode 100644 eventuate-tram-sagas-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbcTest.java diff --git a/eventuate-tram-sagas-reactive-orchestration/src/main/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbc.java b/eventuate-tram-sagas-reactive-orchestration/src/main/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbc.java index a43787b..dc6033b 100644 --- a/eventuate-tram-sagas-reactive-orchestration/src/main/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbc.java +++ b/eventuate-tram-sagas-reactive-orchestration/src/main/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbc.java @@ -85,8 +85,7 @@ private Mono saveDestinationsAndResources(SagaInstance sagaInstance) { public Mono find(String sagaType, String sagaId) { Flux destinationAndResources = eventuateJdbcStatementExecutor.queryForList(sagaInstanceRepositorySql.getSelectFromSagaInstanceParticipantsSql(), (row, rowMetadata) -> new DestinationAndResource(row.get("destination").toString(), row.get("resource").toString()), - sagaId, sagaType); - + sagaType, sagaId); Mono> result = destinationAndResources.collectList().flatMap(dar -> eventuateJdbcStatementExecutor.queryForList(sagaInstanceRepositorySql.getSelectFromSagaInstanceSql(), @@ -96,10 +95,7 @@ public Mono find(String sagaType, String sagaId) { new SerializedSagaData(row.get("saga_data_type").toString(), row.get("saga_data_json").toString()), new HashSet<>(dar)), sagaType, sagaId).collectList()); - return result.flatMap(sagaInstances -> { - if (sagaInstances.isEmpty()) return Mono.error(new RuntimeException(String.format("Cannot find saga instance %s %s", sagaType, sagaId))); - else return Mono.just(sagaInstances.get(0)); - }); + return result.flatMapMany(Flux::fromIterable).single(); } diff --git a/eventuate-tram-sagas-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbcTest.java b/eventuate-tram-sagas-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbcTest.java deleted file mode 100644 index 720a940..0000000 --- a/eventuate-tram-sagas-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/reactive/orchestration/ReactiveSagaInstanceRepositoryJdbcTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.eventuate.tram.sagas.reactive.orchestration; - -import io.eventuate.common.id.ApplicationIdGenerator; -import io.eventuate.common.jdbc.EventuateSchema; -import io.eventuate.common.reactive.jdbc.EventuateReactiveJdbcStatementExecutor; -import io.eventuate.tram.sagas.common.SagaInstanceRepositorySql; -import io.eventuate.tram.sagas.orchestration.DestinationAndResource; -import io.eventuate.tram.sagas.orchestration.SagaInstance; -import org.junit.Test; -import org.mockito.InOrder; -import reactor.core.publisher.Flux; - -import java.util.Collections; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ReactiveSagaInstanceRepositoryJdbcTest { - - @Test - public void testFindUsesExpectedQueriesInCorrectOrder() { - EventuateSchema eventuateSchema = new EventuateSchema(); - SagaInstanceRepositorySql sagaInstanceRepositorySql = - new SagaInstanceRepositorySql(eventuateSchema); - - EventuateReactiveJdbcStatementExecutor eventuateJdbcStatementExecutor = - mock(EventuateReactiveJdbcStatementExecutor.class); - - when(eventuateJdbcStatementExecutor.queryForList(eq(sagaInstanceRepositorySql.getSelectFromSagaInstanceParticipantsSql()), any(), eq("sagaId"), eq("sagaType"))) - .thenReturn(Flux.just(new DestinationAndResource("destination", "resource"))); - - when(eventuateJdbcStatementExecutor.queryForList(eq(sagaInstanceRepositorySql.getSelectFromSagaInstanceSql()), any(), eq("sagaType"), eq("sagaId"))) - .thenReturn(Flux.just(new SagaInstance("sagaType", "sagaId", "stateName", "lastRequestId", null, Collections.singleton(new DestinationAndResource("destination", "resource"))))); - - ReactiveSagaInstanceRepository sagaInstanceRepository = - new ReactiveSagaInstanceRepositoryJdbc(eventuateJdbcStatementExecutor, new ApplicationIdGenerator(), eventuateSchema); - - sagaInstanceRepository.find("sagaType", "sagaId").block(); - - InOrder inOrder = inOrder(eventuateJdbcStatementExecutor); - - inOrder.verify(eventuateJdbcStatementExecutor).queryForList(eq(sagaInstanceRepositorySql.getSelectFromSagaInstanceParticipantsSql()), any(), eq("sagaId"), eq("sagaType")); - inOrder.verify(eventuateJdbcStatementExecutor).queryForList(eq(sagaInstanceRepositorySql.getSelectFromSagaInstanceSql()), any(), eq("sagaType"), eq("sagaId")); - } -} diff --git a/eventuate-tram-sagas-spring-reactive-orchestration/build.gradle b/eventuate-tram-sagas-spring-reactive-orchestration/build.gradle index e97f3da..6467dba 100644 --- a/eventuate-tram-sagas-spring-reactive-orchestration/build.gradle +++ b/eventuate-tram-sagas-spring-reactive-orchestration/build.gradle @@ -9,3 +9,10 @@ dependencies { testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" testCompile "io.eventuate.common:eventuate-common-id:$eventuateCommonVersion" } + +test { + def profile = System.env['SPRING_PROFILES_ACTIVE'] + if (profile != null && profile != "" && !profile.toLowerCase().contains("mysql")) { + exclude '**/**' + } +} \ No newline at end of file diff --git a/eventuate-tram-sagas-spring-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/orchestration/ReactiveSagaInstanceRepositoryJdbcIntegrationTest.java b/eventuate-tram-sagas-spring-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/orchestration/ReactiveSagaInstanceRepositoryJdbcIntegrationTest.java index d1e4150..0547f4e 100644 --- a/eventuate-tram-sagas-spring-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/orchestration/ReactiveSagaInstanceRepositoryJdbcIntegrationTest.java +++ b/eventuate-tram-sagas-spring-reactive-orchestration/src/test/java/io/eventuate/tram/sagas/orchestration/ReactiveSagaInstanceRepositoryJdbcIntegrationTest.java @@ -16,20 +16,25 @@ import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringRunner; -import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; @RunWith(SpringRunner.class) @SpringBootTest(classes = ReactiveSagaInstanceRepositoryJdbcIntegrationTest.Config.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) @EnableAutoConfiguration public class ReactiveSagaInstanceRepositoryJdbcIntegrationTest { - private String sagaType = UUID.randomUUID().toString(); - private SagaInstance sagaInstance = - new SagaInstance(sagaType, null, "SomeState", "lastRequestId", new SerializedSagaData("sagaDatType", "{}"), Collections.emptySet()); + private String sagaType = generateId(); + private String sagaState = generateId(); + private String lastRequestId = generateId(); + private String sagaDataType = generateId(); + private String destination = generateId(); + private String resource = generateId(); @Configuration @Import(EventuateCommonReactiveDatabaseConfiguration.class) @@ -44,21 +49,64 @@ public ReactiveSagaInstanceRepository sagaInstanceRepository(EventuateReactiveJd @Autowired private ReactiveSagaInstanceRepository sagaInstanceRepository; + private SagaInstance sagaInstance; + @Test public void shouldSaveLoadUpdate() { - assertNotNull(sagaInstance.getStateName()); + sagaInstance = createSagaInstance(); sagaInstanceRepository.save(sagaInstance).block(); - SagaInstance result = sagaInstanceRepository.find(sagaType, sagaInstance.getId()).block(); - assertNotNull(result); - assertEquals(sagaInstance.getStateName(), result.getStateName()); + sagaInstance = sagaInstanceRepository.find(sagaType, sagaInstance.getId()).block(); + assertSavedSagaInstance(); + updateSagaInstance(); + assertUpdatedSagaInstance(); + } + + private void assertSavedSagaInstance() { + assertEquals(sagaState, sagaInstance.getStateName()); + assertEquals(lastRequestId, sagaInstance.getLastRequestId()); + assertEquals(sagaDataType, sagaInstance.getSerializedSagaData().getSagaDataType()); + assertEquals("{}", sagaInstance.getSerializedSagaData().getSagaDataJSON()); + Set destinationAndResources = sagaInstance.getDestinationsAndResources(); + assertEquals(singleton(new DestinationAndResource(destination, resource)), destinationAndResources); + DestinationAndResource destinationAndResource = destinationAndResources.stream().findAny().get(); + assertEquals(destination, destinationAndResource.getDestination()); + assertEquals(resource, destinationAndResource.getResource()); + } + + private void updateSagaInstance() { sagaInstance.setStateName("UpdatedState"); + sagaInstance.setLastRequestId("UpdateLastId"); + sagaInstance.setSerializedSagaData(new SerializedSagaData("UpdatedSagaType", "{\"value\" : \"updatedValue\"}")); + sagaInstance.getDestinationsAndResources().add(new DestinationAndResource("newDestination", "newResource")); sagaInstanceRepository.update(sagaInstance).block(); - result = sagaInstanceRepository.find(sagaType, sagaInstance.getId()).block(); - assertEquals("UpdatedState", result.getStateName()); + sagaInstance = sagaInstanceRepository.find(sagaType, sagaInstance.getId()).block(); + } + + private void assertUpdatedSagaInstance() { + assertEquals("UpdatedState", sagaInstance.getStateName()); + assertEquals("UpdateLastId", sagaInstance.getLastRequestId()); + assertEquals("UpdatedSagaType", sagaInstance.getSerializedSagaData().getSagaDataType()); + assertEquals("{\"value\" : \"updatedValue\"}", sagaInstance.getSerializedSagaData().getSagaDataJSON()); + + Set destinationAndResources = sagaInstance.getDestinationsAndResources(); + assertEquals(new HashSet<>(asList(new DestinationAndResource(destination, resource), new DestinationAndResource("newDestination", "newResource"))), destinationAndResources); } @Test(expected = RuntimeException.class) public void shouldThrowExceptionWhenInstanceNotFound() { sagaInstanceRepository.find(sagaType, "unknown").block(); } + + private SagaInstance createSagaInstance() { + return new SagaInstance(sagaType, + null, + sagaState, + lastRequestId, + new SerializedSagaData(sagaDataType, "{}"), + singleton(new DestinationAndResource(destination, resource))); + } + + private String generateId() { + return UUID.randomUUID().toString(); + } } \ No newline at end of file