diff --git a/_build-and-test-all.sh b/_build-and-test-all.sh index a7b884c..e981415 100755 --- a/_build-and-test-all.sh +++ b/_build-and-test-all.sh @@ -19,6 +19,12 @@ else ${DOCKER_COMPOSE?} rm -v --force fi +NO_RM=false + +if [ "$1" = "--no-rm" ] ; then + NO_RM=true + shift +fi ${DOCKER_COMPOSE?} up -d mongodb @@ -54,5 +60,7 @@ set -e ./gradlew -a $* :e2e-test:cleanTest :e2e-test:test -P ignoreE2EFailures=false -${DOCKER_COMPOSE?} stop -${DOCKER_COMPOSE?} rm -v --force +if [ $NO_RM = false ] ; then + ${DOCKER_COMPOSE?} stop + ${DOCKER_COMPOSE?} rm -v --force +fi diff --git a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountChangeInfo.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountChangeInfo.java index b9ccf0d..b988eb1 100644 --- a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountChangeInfo.java +++ b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountChangeInfo.java @@ -1,5 +1,8 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.accounts; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + public class AccountChangeInfo { private String changeId; @@ -15,4 +18,14 @@ public class AccountChangeInfo { this.amount = amount; this.balanceDelta = balanceDelta; } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } diff --git a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfo.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfo.java index 1ed1de4..5a25615 100644 --- a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfo.java +++ b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfo.java @@ -1,6 +1,9 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.accounts; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; /** * Created by cer on 11/21/14. @@ -13,13 +16,13 @@ public class AccountInfo { private String description; private long balance; private List changes; - private List transactions; + private Map transactions; private String version; private AccountInfo() { } - public AccountInfo(String id, String customerId, String title, String description, long balance, List changes, List transactions, String version) { + public AccountInfo(String id, String customerId, String title, String description, long balance, List changes, Map transactions, String version) { this.id = id; this.customerId = customerId; @@ -52,11 +55,11 @@ public class AccountInfo { } public List getChanges() { - return changes; + return changes == null ? Collections.EMPTY_LIST : changes; } public List getTransactions() { - return transactions; + return transactions == null ? Collections.EMPTY_LIST : new ArrayList<>(transactions.values()); } public String getVersion() { diff --git a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java index e7e52d3..834b961 100644 --- a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java +++ b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java @@ -16,11 +16,9 @@ import static org.springframework.data.mongodb.core.query.Criteria.where; public class AccountInfoUpdateService { private Logger logger = LoggerFactory.getLogger(getClass()); - private AccountInfoRepository accountInfoRepository; private MongoTemplate mongoTemplate; - public AccountInfoUpdateService(AccountInfoRepository accountInfoRepository, MongoTemplate mongoTemplate) { - this.accountInfoRepository = accountInfoRepository; + public AccountInfoUpdateService(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } @@ -28,29 +26,26 @@ public class AccountInfoUpdateService { public void create(String accountId, String customerId, String title, BigDecimal initialBalance, String description, String version) { try { - accountInfoRepository.save(new AccountInfo( - accountId, - customerId, - title, - description, - toIntegerRepr(initialBalance), - Collections.emptyList(), - Collections.emptyList(), - version)); + WriteResult x = mongoTemplate.upsert(new Query(where("id").is(accountId).and("version").exists(false)), + new Update() + .set("customerId", customerId) + .set("title", title) + .set("description", description) + .set("balance", toIntegerRepr(initialBalance)) + .set("version", version), + AccountInfo.class); logger.info("Saved in mongo"); } catch (Throwable t) { - logger.error("Error during saving: "); logger.error("Error during saving: ", t); throw new RuntimeException(t); } } - public void addTransaction(String eventId, String fromAccountId, AccountTransactionInfo ti) { - mongoTemplate.updateMulti(new Query(where("id").is(fromAccountId).and("version").lt(eventId)), + public void addTransaction(String eventId, String accountId, AccountTransactionInfo ti) { + mongoTemplate.upsert(new Query(where("id").is(accountId)), new Update(). - push("transactions", ti). - set("version", eventId), + set("transactions." + eventId, ti), AccountInfo.class); } diff --git a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountTransactionInfo.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountTransactionInfo.java index 6a0f9a8..8660536 100644 --- a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountTransactionInfo.java +++ b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountTransactionInfo.java @@ -2,6 +2,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.ac import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; import java.util.Date; @@ -21,6 +22,12 @@ public class AccountTransactionInfo { this(transactionId, fromAccountId, toAccountId, amount, new Date(), ""); } + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + public AccountTransactionInfo(String transactionId, String fromAccountId, String toAccountId, long amount, Date date, String description) { this.transactionId = transactionId; this.fromAccountId = fromAccountId; diff --git a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideAccountConfiguration.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideAccountConfiguration.java index e34e727..018d760 100644 --- a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideAccountConfiguration.java +++ b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideAccountConfiguration.java @@ -18,8 +18,8 @@ public class QuerySideAccountConfiguration { } @Bean - public AccountInfoUpdateService accountInfoUpdateService(AccountInfoRepository accountInfoRepository, MongoTemplate mongoTemplate) { - return new AccountInfoUpdateService(accountInfoRepository, mongoTemplate); + public AccountInfoUpdateService accountInfoUpdateService(MongoTemplate mongoTemplate) { + return new AccountInfoUpdateService(mongoTemplate); } @Bean diff --git a/java-spring/accounts-query-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateServiceTest.java b/java-spring/accounts-query-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateServiceTest.java new file mode 100644 index 0000000..fabe490 --- /dev/null +++ b/java-spring/accounts-query-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateServiceTest.java @@ -0,0 +1,96 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.accounts; + +import io.eventuate.javaclient.spring.jdbc.EventuateJdbcEventStoreConfiguration; +import io.eventuate.javaclient.spring.jdbc.IdGenerator; +import io.eventuate.javaclient.spring.jdbc.IdGeneratorImpl; +import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountCreditedEvent; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.*; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = AccountInfoUpdateServiceTest.AccountInfoUpdateServiceTestConfiguration.class) +@IntegrationTest +public class AccountInfoUpdateServiceTest { + + @Configuration + @EnableAutoConfiguration + @Import({QuerySideAccountConfiguration.class, EventuateJdbcEventStoreConfiguration.class}) + public static class AccountInfoUpdateServiceTestConfiguration { + + } + + @Autowired + private AccountInfoUpdateService accountInfoUpdateService; + + @Autowired + private AccountQueryService accountQueryService; + + @Test + public void shouldSaveAccountInfo() throws ExecutionException, InterruptedException { + IdGenerator x = new IdGeneratorImpl(); + String accountId = x.genId().asString(); + String customerId = x.genId().asString(); + String version = x.genId().asString(); + + String title = "Checking account"; + BigDecimal initialBalance = new BigDecimal("1345"); + String description = "Some account"; + + accountInfoUpdateService.create(accountId, customerId, title, initialBalance, description, version); + + AccountInfo accountInfo = accountQueryService.findByAccountId(accountId).get(); + + assertEquals(accountId, accountInfo.getId()); + assertEquals(customerId, accountInfo.getCustomerId()); + assertEquals(title, accountInfo.getTitle()); + assertEquals(description, accountInfo.getDescription()); + assertEquals(initialBalance.longValue() * 100, accountInfo.getBalance()); + assertTrue(accountInfo.getChanges().isEmpty()); + assertTrue(accountInfo.getTransactions().isEmpty()); + assertEquals(version, accountInfo.getVersion()); + + + String changeId = x.genId().asString(); + + String transactionId = x.genId().asString(); + + AccountChangeInfo change = new AccountChangeInfo(changeId, transactionId, AccountCreditedEvent.class.getSimpleName(), + 500, +1); + + accountInfoUpdateService.updateBalance(accountId, changeId, 500, + change); + + accountInfo = accountQueryService.findByAccountId(accountId).get(); + assertEquals(initialBalance.add(new BigDecimal(5)).longValue() * 100, accountInfo.getBalance()); + assertFalse(accountInfo.getChanges().isEmpty()); + + assertEquals(change, accountInfo.getChanges().get(0)); + + String eventId = x.genId().asString(); + + AccountTransactionInfo ti = new AccountTransactionInfo(transactionId, accountId, accountId, 5, new Date(), "A transfer"); + + accountInfoUpdateService.addTransaction(eventId, accountId, ti); + + accountInfo = accountQueryService.findByAccountId(accountId).get(); + assertFalse(accountInfo.getTransactions().isEmpty()); + + assertEquals(ti, accountInfo.getTransactions().get(0)); + } + +} \ No newline at end of file diff --git a/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/BankingTestConfiguration.java b/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/BankingTestConfiguration.java index 1d252e9..096e451 100644 --- a/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/BankingTestConfiguration.java +++ b/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/BankingTestConfiguration.java @@ -3,11 +3,13 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend; import io.eventuate.javaclient.spring.jdbc.EventuateJdbcEventStoreConfiguration; import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts.AccountConfiguration; import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.MoneyTransferConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration @Import({AccountConfiguration.class, MoneyTransferConfiguration.class, EventuateJdbcEventStoreConfiguration.class}) +@EnableAutoConfiguration public class BankingTestConfiguration { } diff --git a/java-spring/buildSrc/src/main/groovy/EventuateDependencyPlugin.groovy b/java-spring/buildSrc/src/main/groovy/EventuateDependencyPlugin.groovy index 4a7804a..c531a8c 100644 --- a/java-spring/buildSrc/src/main/groovy/EventuateDependencyPlugin.groovy +++ b/java-spring/buildSrc/src/main/groovy/EventuateDependencyPlugin.groovy @@ -6,9 +6,10 @@ class EventuateDependencyPlugin implements Plugin { @Override void apply(Project project) { project.dependencies { - if (project.hasProperty("eventuateLocal")) + if (project.hasProperty("eventuateLocal")) { compile "io.eventuate.local.java:eventuate-local-java-jdbc:${project.eventuateLocalVersion}" - else + compile "io.eventuate.local.java:eventuate-local-java-embedded-cdc-autoconfigure:${project.eventuateLocalVersion}" + } else compile "io.eventuate.client.java:eventuate-client-java-http-stomp-spring:${project.eventuateClientVersion}" } } diff --git a/java-spring/common-backend/src/main/resources/logback.xml b/java-spring/common-backend/src/main/resources/logback.xml index d4123dc..ce0479c 100644 --- a/java-spring/common-backend/src/main/resources/logback.xml +++ b/java-spring/common-backend/src/main/resources/logback.xml @@ -16,7 +16,7 @@ - + diff --git a/java-spring/docker-compose-eventuate-local.yml b/java-spring/docker-compose-eventuate-local.yml index d0f9a75..0f347d8 100644 --- a/java-spring/docker-compose-eventuate-local.yml +++ b/java-spring/docker-compose-eventuate-local.yml @@ -18,8 +18,11 @@ apigateway: SPRING_DATASOURCE_USERNAME: SPRING_DATASOURCE_PASSWORD: SPRING_DATASOURCE_DRIVER_CLASS_NAME: - EVENTUATELOCAL_AGGREGATESTORE_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_KAFKA_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_ZOOKEEPER_CONNECTION_STRING: SPRING_DATA_MONGODB_URI: mongodb://mongodb/mydb + EVENTUATELOCAL_EMBEDDED_CDC_DB_USER_NAME: + EVENTUATELOCAL_EMBEDDED_CDC_DB_PASSWORD: accountscommandside: image: java:openjdk-8u91-jdk @@ -34,7 +37,10 @@ accountscommandside: SPRING_DATASOURCE_USERNAME: SPRING_DATASOURCE_PASSWORD: SPRING_DATASOURCE_DRIVER_CLASS_NAME: - EVENTUATELOCAL_AGGREGATESTORE_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_KAFKA_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_ZOOKEEPER_CONNECTION_STRING: + EVENTUATELOCAL_EMBEDDED_CDC_DB_USER_NAME: + EVENTUATELOCAL_EMBEDDED_CDC_DB_PASSWORD: transactionscommandside: image: java:openjdk-8u91-jdk @@ -49,7 +55,10 @@ transactionscommandside: SPRING_DATASOURCE_USERNAME: SPRING_DATASOURCE_PASSWORD: SPRING_DATASOURCE_DRIVER_CLASS_NAME: - EVENTUATELOCAL_AGGREGATESTORE_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_KAFKA_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_ZOOKEEPER_CONNECTION_STRING: + EVENTUATELOCAL_EMBEDDED_CDC_DB_USER_NAME: + EVENTUATELOCAL_EMBEDDED_CDC_DB_PASSWORD: accountsqueryside: @@ -67,8 +76,11 @@ accountsqueryside: SPRING_DATASOURCE_USERNAME: SPRING_DATASOURCE_PASSWORD: SPRING_DATASOURCE_DRIVER_CLASS_NAME: - EVENTUATELOCAL_AGGREGATESTORE_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_KAFKA_BOOTSTRAP_SERVERS: SPRING_DATA_MONGODB_URI: mongodb://mongodb/mydb + EVENTUATELOCAL_ZOOKEEPER_CONNECTION_STRING: + EVENTUATELOCAL_EMBEDDED_CDC_DB_USER_NAME: + EVENTUATELOCAL_EMBEDDED_CDC_DB_PASSWORD: customerscommandside: image: java:openjdk-8u91-jdk @@ -83,7 +95,10 @@ customerscommandside: SPRING_DATASOURCE_USERNAME: SPRING_DATASOURCE_PASSWORD: SPRING_DATASOURCE_DRIVER_CLASS_NAME: - EVENTUATELOCAL_AGGREGATESTORE_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_KAFKA_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_ZOOKEEPER_CONNECTION_STRING: + EVENTUATELOCAL_EMBEDDED_CDC_DB_USER_NAME: + EVENTUATELOCAL_EMBEDDED_CDC_DB_PASSWORD: customersqueryside: image: java:openjdk-8u91-jdk @@ -100,8 +115,11 @@ customersqueryside: SPRING_DATASOURCE_USERNAME: SPRING_DATASOURCE_PASSWORD: SPRING_DATASOURCE_DRIVER_CLASS_NAME: - EVENTUATELOCAL_AGGREGATESTORE_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_KAFKA_BOOTSTRAP_SERVERS: + EVENTUATELOCAL_ZOOKEEPER_CONNECTION_STRING: SPRING_DATA_MONGODB_URI: mongodb://mongodb/mydb + EVENTUATELOCAL_EMBEDDED_CDC_DB_USER_NAME: + EVENTUATELOCAL_EMBEDDED_CDC_DB_PASSWORD: mongodb: image: mongo:3.0.4 diff --git a/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java b/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java index 9f10477..0c2cd64 100644 --- a/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java +++ b/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java @@ -28,6 +28,7 @@ import java.util.concurrent.CompletableFuture; import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil.eventually; import static net.chrisrichardson.eventstorestore.javaexamples.testutil.customers.CustomersTestUtils.generateCustomerInfo; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; public class EndToEndTest { @@ -115,15 +116,26 @@ public class EndToEndTest { // TOOD - check state of money transfer - List transactionInfoList = restTemplate.exchange(accountsQuerySideBaseUrl("/accounts/"+fromAccountId+"/history"), - HttpMethod.GET, - new HttpEntity(BasicAuthUtils.basicAuthHeaders("test_user@mail.com")), - new ParameterizedTypeReference>() {}).getBody(); + eventually( + () -> CompletableFuture.completedFuture(restTemplate.exchange(accountsQuerySideBaseUrl("/accounts/"+fromAccountId+"/history"), + HttpMethod.GET, + new HttpEntity(BasicAuthUtils.basicAuthHeaders("test_user@mail.com")), + new ParameterizedTypeReference>() {}).getBody()), + transactionInfoList -> { + if (!(transactionInfoList.stream().filter(ti -> ti.getTransactionId().equals(moneyTransfer.getMoneyTransferId()) && + ti.getFromAccountId().equals(fromAccountId) && + ti.getToAccountId().equals(toAccountId) && + ti.getAmount() == toCents(amountToTransfer).longValue()).findFirst().isPresent())) { + fail(String.format("%s does not contain %s %s %s", + moneyTransfer.getMoneyTransferId(), + fromAccount, + toAccount, + toCents(amountToTransfer).longValue())); + } + + } + ); - assertTrue(transactionInfoList.stream().filter(ti -> ti.getTransactionId().equals(moneyTransfer.getMoneyTransferId()) && - ti.getFromAccountId().equals(fromAccountId) && - ti.getToAccountId().equals(toAccountId) && - ti.getAmount() == toCents(amountToTransfer).longValue()).findFirst().isPresent()); } @Test @@ -163,14 +175,14 @@ public class EndToEndTest { return dollarAmount.multiply(new BigDecimal(100)); } - private void assertAccountBalance(final String fromAccountId, final BigDecimal expectedBalanceInDollars) { + private void assertAccountBalance(final String accountId, final BigDecimal expectedBalanceInDollars) { final BigDecimal inCents = toCents(expectedBalanceInDollars); - eventually( + eventually( new Producer() { @Override public CompletableFuture produce() { return CompletableFuture.completedFuture(BasicAuthUtils.doBasicAuthenticatedRequest(restTemplate, - accountsQuerySideBaseUrl("/accounts/" + fromAccountId), + accountsQuerySideBaseUrl("/accounts/" + accountId), HttpMethod.GET, GetAccountResponse.class)); } @@ -178,8 +190,8 @@ public class EndToEndTest { new Verifier() { @Override public void verify(GetAccountResponse accountInfo) { - Assert.assertEquals(fromAccountId, accountInfo.getAccountId()); - Assert.assertEquals(inCents, accountInfo.getBalance()); + Assert.assertEquals(accountId, accountInfo.getAccountId()); + Assert.assertEquals(accountId, inCents, accountInfo.getBalance()); } }); } diff --git a/java-spring/gradle.properties b/java-spring/gradle.properties index c155186..8c03167 100644 --- a/java-spring/gradle.properties +++ b/java-spring/gradle.properties @@ -5,6 +5,6 @@ eventuateMavenRepoUrl=http://mavenrepo.eventuate.io/release springBootVersion=1.3.5.RELEASE -eventuateClientVersion=0.6.0.RELEASE -eventuateLocalVersion=0.1.0.RELEASE +eventuateClientVersion=0.8.0.RELEASE +eventuateLocalVersion=0.2.0.RELEASE diff --git a/java-spring/monolithic-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebIntegrationTest.java b/java-spring/monolithic-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebIntegrationTest.java index f9ea3b1..f222860 100644 --- a/java-spring/monolithic-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebIntegrationTest.java +++ b/java-spring/monolithic-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebIntegrationTest.java @@ -35,6 +35,7 @@ import static net.chrisrichardson.eventstorestore.javaexamples.testutil.customer import static net.chrisrichardson.eventstorestore.javaexamples.testutil.customers.CustomersTestUtils.generateToAccountInfo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = BankingWebTestConfiguration.class) @@ -102,23 +103,31 @@ public class BankingWebIntegrationTest { assertAccountBalance(fromAccountId, finalFromAccountBalance); assertAccountBalance(toAccountId, finalToAccountBalance); - List transactionInfoList = restTemplate.exchange(baseUrl("/accounts/"+fromAccountId+"/history"), - HttpMethod.GET, - new HttpEntity(BasicAuthUtils.basicAuthHeaders("test_user@mail.com")), - new ParameterizedTypeReference>() {}).getBody(); + eventually( + () -> CompletableFuture.completedFuture(restTemplate.exchange(baseUrl("/accounts/"+fromAccountId+"/history"), + HttpMethod.GET, + new HttpEntity(BasicAuthUtils.basicAuthHeaders("test_user@mail.com")), + new ParameterizedTypeReference>() {}).getBody()), + transactionInfoList -> { + Optional txn = transactionInfoList.stream() + .filter(ti -> ti.getTransactionId().equals(moneyTransfer.getMoneyTransferId())) + .findFirst(); - Optional first = transactionInfoList.stream().filter(ti -> ti.getTransactionId().equals(moneyTransfer.getMoneyTransferId())).findFirst(); + if (!txn.isPresent()) { + fail(String.format("%s does not contain %s", transactionInfoList, moneyTransfer.getMoneyTransferId())); + } - assertTrue(first.isPresent()); + AccountTransactionInfo ti = txn.get(); - AccountTransactionInfo ti = first.get(); + assertEquals(fromAccountId, ti.getFromAccountId()); + assertEquals(toAccountId, ti.getToAccountId()); + assertEquals(toAccountId, ti.getToAccountId()); + assertEquals(fromAccountId, ti.getFromAccountId()); + assertEquals(toCents(amountToTransfer).longValue(), ti.getAmount()); + } + ); - assertEquals(fromAccountId, ti.getFromAccountId()); - assertEquals(toAccountId, ti.getToAccountId()); - assertEquals(toAccountId, ti.getToAccountId()); - assertEquals(fromAccountId, ti.getFromAccountId()); - assertEquals(toCents(amountToTransfer).longValue(), ti.getAmount()); } diff --git a/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/TestUtil.java b/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/TestUtil.java index f39dfe7..b8f8307 100644 --- a/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/TestUtil.java +++ b/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/TestUtil.java @@ -55,7 +55,7 @@ public class TestUtil { } public static void eventually(final Producer producer, final Verifier verifier) { - final int n = 50; + final int n = 150; Object possibleException = Observable.timer(0, 200, TimeUnit.MILLISECONDS).flatMap(new Func1>>() { @Override