diff --git a/.gitignore b/.gitignore index 8f19529..fbb607a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ local_developer_config /web/web.log +*.log +*.pid diff --git a/README.md b/README.md index 76d30d5..7bf0348 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This example application is the money transfer application described in my talk This talk describe a way of architecting highly scalable and available applications that is based on microservices, polyglot persistence, event sourcing (ES) and command query responsibility separation (CQRS). Applications consist of loosely coupled components that communicate using events. -These components can be deployed either as separate services or, as they are here, packaged as a monolithic application for simplified development and testing. +These components can be deployed either as separate services or packaged as a monolithic application for simplified development and testing. # About the examples @@ -19,12 +19,23 @@ For more information, please see the [wiki](../../wiki) # About the event store -The application use an embedded SQL-based event store. +The application use one of two event stores: + +* embedded SQL-based event store, which is great for integration tests +* event store server # Running the tests -To run the tests you need to set the following environment variable: +To run the tests you need to set some environment variable. + +First, you need to tell the query side code how to connect to MongoDB: ``` export SPRING_DATA_MONGODB_URI=mongodb://192.168.59.103/yourdb ``` + +Docker is a great way to run MongoDB. +For more information please see this [blog post](http://plainoldobjects.com/2015/01/14/need-to-install-mongodb-rabbitmq-or-mysql-use-docker-to-simplify-dev-and-test/). + +Second, in order for the tests in accounts-command-side-service, transactions-command-side-service and accounts-query-side-service to pass you need to set some environment variables that tell the service how to connect to the Event Store server. +But don't worry. The build is configured to ignore failures for those projects diff --git a/es-examples-docker/docker-compose.yml b/es-examples-docker/docker-compose.yml new file mode 100644 index 0000000..2b0b179 --- /dev/null +++ b/es-examples-docker/docker-compose.yml @@ -0,0 +1,5 @@ +mongodb: + image: dockerfile/mongodb + ports: + - "27017:27017" + diff --git a/es-examples-docker/mongodb-cli.sh b/es-examples-docker/mongodb-cli.sh new file mode 100755 index 0000000..dcf4e6d --- /dev/null +++ b/es-examples-docker/mongodb-cli.sh @@ -0,0 +1,4 @@ +#! /bin/bash + +docker run --link esexamplesdocker_mongodb_1:mongodb -i -t dockerfile/mongodb:latest /usr/bin/mongo --host mongodb + diff --git a/handy-curl-commands.sh b/handy-curl-commands.sh new file mode 100644 index 0000000..f7424c7 --- /dev/null +++ b/handy-curl-commands.sh @@ -0,0 +1,36 @@ +#! /bin/bash -e + + +# Create account 1 + +account1=$(curl -v --data '{"initialBalance" : 500}' -H "content-type: application/json" http://localhost:8080/accounts) + +# {"accountId":"0000014ae4caf314-ae7453bbb71e0000"} + +curl -v http://localhost:8081/accounts/0000014ae4caf314-ae7453bbb71e0000 + +# {"accountId":"0000014ae4caf314-ae7453bbb71e0000","balance":50000} + +# Create account 2 + +account2=$(curl -v --data '{"initialBalance" : 300}' -H "content-type: application/json" http://localhost:8080/accounts) + +# {"accountId":"0000014ae4cc8415-ae7453bbb71e0000"} + +curl -v http://localhost:8081/accounts/0000014ae4cc8415-ae7453bbb71e0000 + +# + + +transfer=$(curl -v --data '{"amount" : 150, "fromAccountId" : "0000014ae4caf314-ae7453bbb71e0000", "toAccountId" : "0000014ae4cc8415-ae7453bbb71e0000"}' -H "content-type: application/json" http://localhost:8082/transfers) + +# {"moneyTransferId":"0000014ae4cef030-ae7453bbb71e0000"} + + + + + + + + + diff --git a/java-spring/README.md b/java-spring/README.md index 057919f..7434865 100644 --- a/java-spring/README.md +++ b/java-spring/README.md @@ -1,5 +1,7 @@ This is the Java/Spring version of the Event Sourcing/CQRS money transfer example application. +# About the application + This application consists of three microservices: * Account Service - the command side business logic for Accounts @@ -8,25 +10,28 @@ This application consists of three microservices: The Account Service consists of the following modules: - * commandside-backend-accounts - the Account aggregate - * commandside-web-accounts - a REST API for creating and retrieving Accounts + * accounts-command-side-backend - the Account aggregate + * accounts-command-side-web - a REST API for creating and retrieving Accounts + * accounts-command-side-service - a standalone microservice The Money Transfer Service consists of the following modules: - * commandside-backend-transactions - the MoneyTransfer aggregate - * commandside-web-transactions - a REST API for creating and retrieving Money Transfers + * transactions-command-side-backend - the MoneyTransfer aggregate + * transactions-command-side-web - a REST API for creating and retrieving Money Transfers + * transactions-command-side-service - a standalone microservice The Query Service consists the following modules: - * queryside-backend - MongoDB-based, denormalized view of Accounts and MoneyTransfers - * queryside-web - a REST API for querying the denormalized view + * accounts-query-side-backend - MongoDB-based, denormalized view of Accounts and MoneyTransfers + * accounts-query-side-web - a REST API for querying the denormalized view + * accounts-query-side-service - a standalone microservice -In order to be used with the embedded Event Store, the three services are currently packaged as a single monolithic web application: +# Deploying the application - * monolithic-web - all-in-one, monolithic packaging of the application +These services can be deployed either as either separate standalone services using the Event Store server, or they can be deployed as a monolithic application for simpified integration testing. -As well as the above modules there are also: +The three services can also be packaged as a single monolithic web application in order to be used with the embedded Event Store: - * common-backend - code that is shared between the command side and the query side, primarily events and value objects - * backend-integration-tests - integrations tests for the backend - \ No newline at end of file + * monolithic-service - all-in-one, monolithic packaging of the application + + diff --git a/java-spring/commandside-backend-accounts/build.gradle b/java-spring/accounts-command-side-backend/build.gradle similarity index 100% rename from java-spring/commandside-backend-accounts/build.gradle rename to java-spring/accounts-command-side-backend/build.gradle diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/Account.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/Account.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/Account.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/Account.java diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountCommand.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountCommand.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountCommand.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountCommand.java diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountConfiguration.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountConfiguration.java similarity index 72% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountConfiguration.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountConfiguration.java index 976af1c..5ab0ea7 100644 --- a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountConfiguration.java +++ b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountConfiguration.java @@ -1,21 +1,15 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts; import net.chrisrichardson.eventstore.EventStore; +import net.chrisrichardson.eventstore.javaapi.consumer.EnableJavaEventHandlers; import net.chrisrichardson.eventstore.repository.AggregateRepository; -import net.chrisrichardson.eventstore.subscriptions.EnableEventHandlers; -import net.chrisrichardson.eventstore.subscriptions.EventHandlerRegistrarFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration -@EnableEventHandlers +@EnableJavaEventHandlers public class AccountConfiguration { - - @Autowired - private EventHandlerRegistrarFactory eventHandlerRegistrarFactory; - @Bean public AccountWorkflow accountWorkflow() { return new AccountWorkflow(); diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountService.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountService.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountService.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountService.java diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountWorkflow.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountWorkflow.java similarity index 95% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountWorkflow.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountWorkflow.java index e4096be..b21e6dd 100644 --- a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountWorkflow.java +++ b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountWorkflow.java @@ -1,6 +1,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts; import net.chrisrichardson.eventstore.EntityIdentifier; +import net.chrisrichardson.eventstore.javaapi.consumer.EventHandlerContext; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.DebitRecordedEvent; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.MoneyTransferCreatedEvent; import net.chrisrichardson.eventstore.subscriptions.*; diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/CreditAccountCommand.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/CreditAccountCommand.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/CreditAccountCommand.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/CreditAccountCommand.java diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/DebitAccountCommand.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/DebitAccountCommand.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/DebitAccountCommand.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/DebitAccountCommand.java diff --git a/java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/OpenAccountCommand.java b/java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/OpenAccountCommand.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/OpenAccountCommand.java rename to java-spring/accounts-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/OpenAccountCommand.java diff --git a/java-spring/commandside-backend-accounts/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountEventTest.java b/java-spring/accounts-command-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountEventTest.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountEventTest.java rename to java-spring/accounts-command-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountEventTest.java diff --git a/java-spring/commandside-backend-accounts/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountTest.java b/java-spring/accounts-command-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountTest.java similarity index 100% rename from java-spring/commandside-backend-accounts/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountTest.java rename to java-spring/accounts-command-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/accounts/AccountTest.java diff --git a/java-spring/accounts-command-side-service/build.gradle b/java-spring/accounts-command-side-service/build.gradle new file mode 100644 index 0000000..a206d74 --- /dev/null +++ b/java-spring/accounts-command-side-service/build.gradle @@ -0,0 +1,21 @@ +apply plugin: VerifyMongoDBConfigurationPlugin +apply plugin: VerifyEventStoreEnvironmentPlugin + +apply plugin: 'spring-boot' + +dependencies { + compile project(":accounts-command-side-web") + + compile "org.springframework.boot:spring-boot-starter-web" + compile "org.springframework.boot:spring-boot-starter-actuator" + + compile "net.chrisrichardson.eventstore.client:eventstore-http-stomp-client:$eventStoreClientVersion" + + testCompile "org.springframework.boot:spring-boot-starter-test" + +} + +test { + ignoreFailures true +} + diff --git a/java-spring/accounts-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceConfiguration.java b/java-spring/accounts-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceConfiguration.java new file mode 100644 index 0000000..f7313ac --- /dev/null +++ b/java-spring/accounts-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceConfiguration.java @@ -0,0 +1,27 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import net.chrisrichardson.eventstore.client.config.EventStoreHttpClientConfiguration; +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CommandSideWebAccountsConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +@Configuration +@Import({CommandSideWebAccountsConfiguration.class, EventStoreHttpClientConfiguration.class }) +@EnableAutoConfiguration +@ComponentScan +public class AccountsCommandSideServiceConfiguration { + + + @Bean + public HttpMessageConverters customConverters() { + HttpMessageConverter additional = new MappingJackson2HttpMessageConverter(); + return new HttpMessageConverters(additional); + } + +} diff --git a/java-spring/accounts-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/AccountsCommandSideServiceMain.java b/java-spring/accounts-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/AccountsCommandSideServiceMain.java new file mode 100644 index 0000000..4ecadc8 --- /dev/null +++ b/java-spring/accounts-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/AccountsCommandSideServiceMain.java @@ -0,0 +1,11 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web.main; + +import net.chrisrichardson.eventstore.javaexamples.banking.web.AccountsCommandSideServiceConfiguration; +import org.springframework.boot.SpringApplication; + +public class AccountsCommandSideServiceMain { + + public static void main(String[] args) { + SpringApplication.run(AccountsCommandSideServiceConfiguration.class, args); + } +} diff --git a/java-spring/accounts-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceIntegrationTest.java b/java-spring/accounts-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceIntegrationTest.java new file mode 100644 index 0000000..396148d --- /dev/null +++ b/java-spring/accounts-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceIntegrationTest.java @@ -0,0 +1,55 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest; +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.client.RestTemplate; + +import java.math.BigDecimal; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = AccountsCommandSideServiceTestConfiguration.class) +@WebAppConfiguration +@IntegrationTest({"server.port=0", "management.port=0"}) +public class AccountsCommandSideServiceIntegrationTest { + + @Value("${local.server.port}") + private int port; + + private String baseUrl(String path) { + return "http://localhost:" + port + "/" + path; + } + + @Autowired + RestTemplate restTemplate; + + + @Test + public void shouldCreateAccountsAndTransferMoney() { + BigDecimal initialFromAccountBalance = new BigDecimal(500); + BigDecimal initialToAccountBalance = new BigDecimal(100); + BigDecimal amountToTransfer = new BigDecimal(150); + + final CreateAccountResponse fromAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest(initialFromAccountBalance), CreateAccountResponse.class).getBody(); + final String fromAccountId = fromAccount.getAccountId(); + + CreateAccountResponse toAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest(initialToAccountBalance), CreateAccountResponse.class).getBody(); + String toAccountId = toAccount.getAccountId(); + + Assert.assertNotNull(fromAccountId); + Assert.assertNotNull(toAccountId); + + + } + + + +} diff --git a/java-spring/accounts-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceTestConfiguration.java b/java-spring/accounts-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceTestConfiguration.java new file mode 100644 index 0000000..4276e00 --- /dev/null +++ b/java-spring/accounts-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsCommandSideServiceTestConfiguration.java @@ -0,0 +1,26 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import org.springframework.boot.autoconfigure.web.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import java.util.Arrays; +import java.util.List; + +@Configuration +@Import(AccountsCommandSideServiceConfiguration.class) +public class AccountsCommandSideServiceTestConfiguration { + + @Bean + public RestTemplate restTemplate(HttpMessageConverters converters) { + RestTemplate restTemplate = new RestTemplate(); + HttpMessageConverter httpMessageConverter = converters.getConverters().get(0); + List> httpMessageConverters = Arrays.asList(new MappingJackson2HttpMessageConverter()); + restTemplate.setMessageConverters((List>) httpMessageConverters); + return restTemplate; + } +} diff --git a/java-spring/commandside-web-accounts/build.gradle b/java-spring/accounts-command-side-web/build.gradle similarity index 53% rename from java-spring/commandside-web-accounts/build.gradle rename to java-spring/accounts-command-side-web/build.gradle index 167e1de..3f778ae 100644 --- a/java-spring/commandside-web-accounts/build.gradle +++ b/java-spring/accounts-command-side-web/build.gradle @@ -1,7 +1,7 @@ dependencies { - compile project(":commandside-backend-accounts") - compile project(":web-common") + compile project(":accounts-command-side-backend") + compile project(":common-web") compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" } diff --git a/java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/AccountController.java b/java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/AccountController.java similarity index 100% rename from java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/AccountController.java rename to java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/AccountController.java diff --git a/java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CommandSideWebAccountsConfiguration.java b/java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CommandSideWebAccountsConfiguration.java similarity index 100% rename from java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CommandSideWebAccountsConfiguration.java rename to java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CommandSideWebAccountsConfiguration.java diff --git a/java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountRequest.java b/java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountRequest.java similarity index 100% rename from java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountRequest.java rename to java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountRequest.java diff --git a/java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountResponse.java b/java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountResponse.java similarity index 100% rename from java-spring/commandside-web-accounts/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountResponse.java rename to java-spring/accounts-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/accounts/CreateAccountResponse.java diff --git a/java-spring/queryside-backend/build.gradle b/java-spring/accounts-query-side-backend/build.gradle similarity index 100% rename from java-spring/queryside-backend/build.gradle rename to java-spring/accounts-query-side-backend/build.gradle diff --git a/java-spring/queryside-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 similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountChangeInfo.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountChangeInfo.java diff --git a/java-spring/queryside-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 similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfo.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfo.java diff --git a/java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoRepository.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoRepository.java similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoRepository.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoRepository.java diff --git a/java-spring/queryside-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 similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java diff --git a/java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountNotFoundException.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountNotFoundException.java similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountNotFoundException.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountNotFoundException.java diff --git a/java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryService.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryService.java similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryService.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryService.java diff --git a/java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java diff --git a/java-spring/queryside-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 similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountTransactionInfo.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountTransactionInfo.java diff --git a/java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/MoneyUtil.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/MoneyUtil.java similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/MoneyUtil.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/MoneyUtil.java diff --git a/java-spring/queryside-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 similarity index 91% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideAccountConfiguration.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideAccountConfiguration.java index 1323119..5be41ea 100644 --- a/java-spring/queryside-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 @@ -1,7 +1,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.accounts; -import net.chrisrichardson.eventstore.subscriptions.EnableEventHandlers; +import net.chrisrichardson.eventstore.javaapi.consumer.EnableJavaEventHandlers; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.MongoTemplate; @@ -9,7 +9,7 @@ import org.springframework.data.mongodb.repository.config.EnableMongoRepositorie @Configuration @EnableMongoRepositories -@EnableEventHandlers +@EnableJavaEventHandlers public class QuerySideAccountConfiguration { @Bean diff --git a/java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideDependencyChecker.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideDependencyChecker.java similarity index 100% rename from java-spring/queryside-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideDependencyChecker.java rename to java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/QuerySideDependencyChecker.java diff --git a/java-spring/accounts-query-side-service/build.gradle b/java-spring/accounts-query-side-service/build.gradle new file mode 100644 index 0000000..0f05677 --- /dev/null +++ b/java-spring/accounts-query-side-service/build.gradle @@ -0,0 +1,20 @@ +apply plugin: VerifyMongoDBConfigurationPlugin +apply plugin: VerifyEventStoreEnvironmentPlugin + +apply plugin: 'spring-boot' + +dependencies { + compile project(":accounts-query-side-web") + + compile "org.springframework.boot:spring-boot-starter-web" + compile "org.springframework.boot:spring-boot-starter-actuator" + + compile "net.chrisrichardson.eventstore.client:eventstore-http-stomp-client:$eventStoreClientVersion" + + testCompile "org.springframework.boot:spring-boot-starter-test" + +} + +test { + ignoreFailures true +} diff --git a/java-spring/accounts-query-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceConfiguration.java b/java-spring/accounts-query-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceConfiguration.java new file mode 100644 index 0000000..8cc4760 --- /dev/null +++ b/java-spring/accounts-query-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceConfiguration.java @@ -0,0 +1,27 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import net.chrisrichardson.eventstore.client.config.EventStoreHttpClientConfiguration; +import net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.QuerySideWebConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +@Configuration +@Import({QuerySideWebConfiguration.class, EventStoreHttpClientConfiguration.class}) +@EnableAutoConfiguration +@ComponentScan +public class AccountsQuerySideServiceConfiguration { + + + @Bean + public HttpMessageConverters customConverters() { + HttpMessageConverter additional = new MappingJackson2HttpMessageConverter(); + return new HttpMessageConverters(additional); + } + +} diff --git a/java-spring/accounts-query-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/AccountsQuerySideServiceMain.java b/java-spring/accounts-query-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/AccountsQuerySideServiceMain.java new file mode 100644 index 0000000..0450a28 --- /dev/null +++ b/java-spring/accounts-query-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/AccountsQuerySideServiceMain.java @@ -0,0 +1,11 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web.main; + +import net.chrisrichardson.eventstore.javaexamples.banking.web.AccountsQuerySideServiceConfiguration; +import org.springframework.boot.SpringApplication; + +public class AccountsQuerySideServiceMain { + + public static void main(String[] args) { + SpringApplication.run(AccountsQuerySideServiceConfiguration.class, args); + } +} diff --git a/java-spring/accounts-query-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceIntegrationTest.java b/java-spring/accounts-query-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceIntegrationTest.java new file mode 100644 index 0000000..31c4985 --- /dev/null +++ b/java-spring/accounts-query-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceIntegrationTest.java @@ -0,0 +1,67 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.accounts.GetAccountResponse; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.client.RestTemplate; + +import java.math.BigDecimal; + +import net.chrisrichardson.eventstorestore.javaexamples.testutil.Producer; +import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier; +import rx.Observable; + +import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil.eventually; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = AccountsQuerySideServiceTestConfiguration.class) +@WebAppConfiguration +@IntegrationTest({"server.port=0", "management.port=0"}) +public class AccountsQuerySideServiceIntegrationTest { + + @Value("${local.server.port}") + private int port; + + private String baseUrl(String path) { + return "http://localhost:" + port + "/" + path; + } + + @Autowired + RestTemplate restTemplate; + + + @Test + public void shouldCreateAccountsAndTransferMoney() { + // TBD + } + + private BigDecimal toCents(BigDecimal dollarAmount) { + return dollarAmount.multiply(new BigDecimal(100)); + } + + private void assertAccountBalance(final String fromAccountId, final BigDecimal expectedBalanceInDollars) { + final BigDecimal inCents = toCents(expectedBalanceInDollars); + eventually( + new Producer() { + @Override + public Observable produce() { + return Observable.just(restTemplate.getForEntity(baseUrl("/accounts/" + fromAccountId), GetAccountResponse.class).getBody()); + } + }, + new Verifier() { + @Override + public void verify(GetAccountResponse accountInfo) { + Assert.assertEquals(fromAccountId, accountInfo.getAccountId()); + Assert.assertEquals(inCents, accountInfo.getBalance()); + } + }); + } + +} diff --git a/java-spring/accounts-query-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceTestConfiguration.java b/java-spring/accounts-query-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceTestConfiguration.java new file mode 100644 index 0000000..7a9d20b --- /dev/null +++ b/java-spring/accounts-query-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/AccountsQuerySideServiceTestConfiguration.java @@ -0,0 +1,26 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import org.springframework.boot.autoconfigure.web.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import java.util.Arrays; +import java.util.List; + +@Configuration +@Import(AccountsQuerySideServiceConfiguration.class) +public class AccountsQuerySideServiceTestConfiguration { + + @Bean + public RestTemplate restTemplate(HttpMessageConverters converters) { + RestTemplate restTemplate = new RestTemplate(); + HttpMessageConverter httpMessageConverter = converters.getConverters().get(0); + List> httpMessageConverters = Arrays.asList(new MappingJackson2HttpMessageConverter()); + restTemplate.setMessageConverters((List>) httpMessageConverters); + return restTemplate; + } +} diff --git a/java-spring/queryside-web/build.gradle b/java-spring/accounts-query-side-web/build.gradle similarity index 68% rename from java-spring/queryside-web/build.gradle rename to java-spring/accounts-query-side-web/build.gradle index 208bf40..d81b10a 100644 --- a/java-spring/queryside-web/build.gradle +++ b/java-spring/accounts-query-side-web/build.gradle @@ -1,7 +1,7 @@ dependencies { - compile project(":queryside-backend") - compile project(":web-common") + compile project(":accounts-query-side-backend") + compile project(":common-web") compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" compile "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion" diff --git a/java-spring/queryside-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/QuerySideWebConfiguration.java b/java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/QuerySideWebConfiguration.java similarity index 100% rename from java-spring/queryside-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/QuerySideWebConfiguration.java rename to java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/QuerySideWebConfiguration.java diff --git a/java-spring/queryside-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java b/java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java similarity index 100% rename from java-spring/queryside-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java rename to java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java diff --git a/java-spring/queryside-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/GetAccountResponse.java b/java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/GetAccountResponse.java similarity index 100% rename from java-spring/queryside-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/GetAccountResponse.java rename to java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/GetAccountResponse.java diff --git a/java-spring/backend-integration-tests/build.gradle b/java-spring/backend-integration-tests/build.gradle index dee4c2f..54fa5a6 100644 --- a/java-spring/backend-integration-tests/build.gradle +++ b/java-spring/backend-integration-tests/build.gradle @@ -2,12 +2,12 @@ apply plugin: VerifyMongoDBConfigurationPlugin dependencies { - testCompile project(":commandside-backend-accounts") - testCompile project(":commandside-backend-transactions") - testCompile project(":queryside-backend") + testCompile project(":accounts-command-side-backend") + testCompile project(":transactions-command-side-backend") + testCompile project(":accounts-query-side-backend") testCompile project(":testutil") testCompile "junit:junit:4.11" testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" testCompile "net.chrisrichardson.eventstore.client:eventstore-jdbc:$eventStoreClientVersion" -} \ No newline at end of file +} diff --git a/java-spring/build.gradle b/java-spring/build.gradle index 0857f8a..bed022e 100644 --- a/java-spring/build.gradle +++ b/java-spring/build.gradle @@ -24,5 +24,6 @@ subprojects { repositories { mavenCentral() maven { url "https://06c59145-4e83-4f22-93ef-6a7eee7aebaa.repos.chrisrichardson.net.s3.amazonaws.com" } + } } diff --git a/java-spring/buildSrc/src/main/groovy/VerifyEventStoreEnvironmentPlugin.groovy b/java-spring/buildSrc/src/main/groovy/VerifyEventStoreEnvironmentPlugin.groovy new file mode 100644 index 0000000..90e18ce --- /dev/null +++ b/java-spring/buildSrc/src/main/groovy/VerifyEventStoreEnvironmentPlugin.groovy @@ -0,0 +1,16 @@ +import org.gradle.api.* + + +class VerifyEventStoreEnvironmentPlugin implements Plugin { + void apply(Project project) { + project.test { + beforeSuite { x -> + if (x.parent == null) { + if (System.getenv("EVENT_STORE_URL") == null) + logger.warn("\nPLEASE make sure that Event Store-related environment variables including EVENT_STORE_URL are set, see sample-set-remote-env.sh !!!!\n") + } + } + } + } +} + diff --git a/java-spring/web-common/build.gradle b/java-spring/common-web/build.gradle similarity index 100% rename from java-spring/web-common/build.gradle rename to java-spring/common-web/build.gradle diff --git a/java-spring/web-common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/util/DeferredUtils.java b/java-spring/common-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/util/DeferredUtils.java similarity index 100% rename from java-spring/web-common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/util/DeferredUtils.java rename to java-spring/common-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/util/DeferredUtils.java diff --git a/java-spring/e2e-test/build.gradle b/java-spring/e2e-test/build.gradle new file mode 100644 index 0000000..28e672f --- /dev/null +++ b/java-spring/e2e-test/build.gradle @@ -0,0 +1,21 @@ +apply plugin: VerifyMongoDBConfigurationPlugin + +dependencies { + compile "org.scala-lang:scala-library:2.10.2" + + testCompile project(":accounts-command-side-web") + testCompile project(":transactions-command-side-web") + testCompile project(":accounts-query-side-web") + + testCompile "junit:junit:4.11" + testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" + testCompile scalaTestDependency + +} + +test { + ignoreFailures true +} + + + 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 new file mode 100644 index 0000000..2ea6bff --- /dev/null +++ b/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java @@ -0,0 +1,101 @@ +package net.chrisrichardson.eventstore.examples.bank.web; + + +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest; +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse; +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferRequest; +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferResponse; +import net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.accounts.GetAccountResponse; +import net.chrisrichardson.eventstore.json.EventStoreCommonObjectMapping; +import net.chrisrichardson.eventstorestore.javaexamples.testutil.Producer; +import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; +import rx.Observable; + +import java.math.BigDecimal; + +import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil.eventually; + +public class EndToEndTest { + + private String accountsCommandSideBaseUrl(String path) { + return "http://localhost:8080/" + path; + } + private String accountsQuerySideBaseUrl(String path) { + return "http://localhost:8081/" + path; + } + private String transactionsCommandSideBaseUrl(String path) { + return "http://localhost:8082/" + path; + } + + RestTemplate restTemplate = new RestTemplate(); + + { + + for (HttpMessageConverter mc : restTemplate.getMessageConverters()) { + if (mc instanceof MappingJackson2HttpMessageConverter) { + ((MappingJackson2HttpMessageConverter) mc).setObjectMapper(EventStoreCommonObjectMapping.getObjectMapper()); + } + } + } + + + @Test + public void shouldCreateAccountsAndTransferMoney() { + + BigDecimal initialFromAccountBalance = new BigDecimal(500); + BigDecimal initialToAccountBalance = new BigDecimal(100); + BigDecimal amountToTransfer = new BigDecimal(150); + + BigDecimal finalFromAccountBalance = initialFromAccountBalance.subtract(amountToTransfer); + BigDecimal finalToAccountBalance = initialToAccountBalance.add(amountToTransfer); + + final CreateAccountResponse fromAccount = restTemplate.postForEntity(accountsCommandSideBaseUrl("/accounts"), new CreateAccountRequest(initialFromAccountBalance), CreateAccountResponse.class).getBody(); + final String fromAccountId = fromAccount.getAccountId(); + + CreateAccountResponse toAccount = restTemplate.postForEntity(accountsCommandSideBaseUrl("/accounts"), new CreateAccountRequest(initialToAccountBalance), CreateAccountResponse.class).getBody(); + String toAccountId = toAccount.getAccountId(); + + Assert.assertNotNull(fromAccountId); + Assert.assertNotNull(toAccountId); + + assertAccountBalance(fromAccountId, initialFromAccountBalance); + assertAccountBalance(toAccountId, initialToAccountBalance); + + + final CreateMoneyTransferResponse moneyTransfer = restTemplate.postForEntity(transactionsCommandSideBaseUrl("/transfers"), + new CreateMoneyTransferRequest(fromAccountId, toAccountId, amountToTransfer), CreateMoneyTransferResponse.class).getBody(); + + assertAccountBalance(fromAccountId, finalFromAccountBalance); + assertAccountBalance(toAccountId, finalToAccountBalance); + + // TOOD - check state of money transfer + } + + private BigDecimal toCents(BigDecimal dollarAmount) { + return dollarAmount.multiply(new BigDecimal(100)); + } + + private void assertAccountBalance(final String fromAccountId, final BigDecimal expectedBalanceInDollars) { + final BigDecimal inCents = toCents(expectedBalanceInDollars); + eventually( + new Producer() { + @Override + public Observable produce() { + return Observable.just(restTemplate.getForEntity(accountsQuerySideBaseUrl("/accounts/" + fromAccountId), GetAccountResponse.class).getBody()); + } + }, + new Verifier() { + @Override + public void verify(GetAccountResponse accountInfo) { + Assert.assertEquals(fromAccountId, accountInfo.getAccountId()); + Assert.assertEquals(inCents, accountInfo.getBalance()); + } + }); + } + +} diff --git a/java-spring/gradle.properties b/java-spring/gradle.properties index 03a293b..e1b7905 100644 --- a/java-spring/gradle.properties +++ b/java-spring/gradle.properties @@ -5,5 +5,5 @@ scalaTestDependency=org.scalatest:scalatest_2.10:2.0 springBootVersion=1.1.10.RELEASE -eventStoreCommonVersion=0.2 -eventStoreClientVersion=0.2 +eventStoreClientVersion=0.5 +eventStoreCommonVersion=0.5 diff --git a/java-spring/monolithic-web/build.gradle b/java-spring/monolithic-service/build.gradle similarity index 72% rename from java-spring/monolithic-web/build.gradle rename to java-spring/monolithic-service/build.gradle index 9748591..63cff7c 100644 --- a/java-spring/monolithic-web/build.gradle +++ b/java-spring/monolithic-service/build.gradle @@ -3,9 +3,9 @@ apply plugin: VerifyMongoDBConfigurationPlugin apply plugin: 'spring-boot' dependencies { - compile project(":queryside-web") - compile project(":commandside-web-accounts") - compile project(":commandside-web-transactions") + compile project(":accounts-query-side-web") + compile project(":accounts-command-side-web") + compile project(":transactions-command-side-web") compile "org.springframework.boot:spring-boot-starter-web" compile "org.springframework.boot:spring-boot-starter-actuator" diff --git a/java-spring/monolithic-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebConfiguration.java b/java-spring/monolithic-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebConfiguration.java similarity index 100% rename from java-spring/monolithic-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebConfiguration.java rename to java-spring/monolithic-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebConfiguration.java diff --git a/java-spring/monolithic-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/BankingMain.java b/java-spring/monolithic-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/BankingMain.java similarity index 100% rename from java-spring/monolithic-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/BankingMain.java rename to java-spring/monolithic-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/BankingMain.java diff --git a/java-spring/monolithic-web/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 similarity index 100% rename from java-spring/monolithic-web/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebIntegrationTest.java rename to java-spring/monolithic-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebIntegrationTest.java diff --git a/java-spring/monolithic-web/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebTestConfiguration.java b/java-spring/monolithic-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebTestConfiguration.java similarity index 100% rename from java-spring/monolithic-web/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebTestConfiguration.java rename to java-spring/monolithic-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/BankingWebTestConfiguration.java diff --git a/java-spring/settings.gradle b/java-spring/settings.gradle index 5a17a60..0927fd7 100644 --- a/java-spring/settings.gradle +++ b/java-spring/settings.gradle @@ -1,20 +1,26 @@ include 'testutil' -include 'web-common' +include 'common-web' include 'common-backend' -include 'commandside-backend-accounts' -include 'commandside-backend-transactions' -include 'commandside-web-accounts' -include 'commandside-web-transactions' +include 'accounts-command-side-backend' +include 'transactions-command-side-backend' +include 'accounts-command-side-web' +include 'transactions-command-side-web' -include 'queryside-backend' -include 'queryside-web' +include 'accounts-query-side-backend' +include 'accounts-query-side-web' include 'backend-integration-tests' -include 'monolithic-web' +include 'monolithic-service' + +include 'accounts-command-side-service' +include 'accounts-query-side-service' +include 'transactions-command-side-service' + +include 'e2e-test' rootProject.name = 'java-spring-event-sourcing-example' diff --git a/java-spring/testutil/build.gradle b/java-spring/testutil/build.gradle index bb81caa..9740f4b 100644 --- a/java-spring/testutil/build.gradle +++ b/java-spring/testutil/build.gradle @@ -12,4 +12,4 @@ dependencies { testCompile "net.chrisrichardson.eventstore.client:eventstore-jdbc:$eventStoreClientVersion" -} \ No newline at end of file +} diff --git a/java-spring/commandside-backend-transactions/build.gradle b/java-spring/transactions-command-side-backend/build.gradle similarity index 100% rename from java-spring/commandside-backend-transactions/build.gradle rename to java-spring/transactions-command-side-backend/build.gradle diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/CreateMoneyTransferCommand.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/CreateMoneyTransferCommand.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/CreateMoneyTransferCommand.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/CreateMoneyTransferCommand.java diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferCommand.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferCommand.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferCommand.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferCommand.java diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferConfiguration.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferConfiguration.java similarity index 91% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferConfiguration.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferConfiguration.java index b1759e5..8579fed 100644 --- a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferConfiguration.java +++ b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferConfiguration.java @@ -7,10 +7,11 @@ import net.chrisrichardson.eventstore.subscriptions.config.EventStoreSubscriptio import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import net.chrisrichardson.eventstore.javaapi.consumer.EnableJavaEventHandlers; @Configuration @Import(EventStoreSubscriptionsConfiguration.class) -@EnableEventHandlers +@EnableJavaEventHandlers public class MoneyTransferConfiguration { @Bean diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferService.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferService.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferService.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferService.java diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferWorkflow.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferWorkflow.java similarity index 95% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferWorkflow.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferWorkflow.java index 29cc14c..7ffd396 100644 --- a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferWorkflow.java +++ b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferWorkflow.java @@ -1,11 +1,11 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions; +import net.chrisrichardson.eventstore.javaapi.consumer.EventHandlerContext; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountCreditedEvent; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountDebitFailedDueToInsufficientFundsEvent; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountDebitedEvent; import net.chrisrichardson.eventstore.subscriptions.CompoundEventHandler; -import net.chrisrichardson.eventstore.subscriptions.EventHandlerContext; import net.chrisrichardson.eventstore.subscriptions.EventHandlerMethod; import net.chrisrichardson.eventstore.subscriptions.EventSubscriber; import rx.Observable; diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordCreditCommand.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordCreditCommand.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordCreditCommand.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordCreditCommand.java diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitCommand.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitCommand.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitCommand.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitCommand.java diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitFailedCommand.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitFailedCommand.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitFailedCommand.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/RecordDebitFailedCommand.java diff --git a/java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/TransferState.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/TransferState.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/TransferState.java rename to java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/TransferState.java diff --git a/java-spring/commandside-backend-transactions/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferEventTest.java b/java-spring/transactions-command-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferEventTest.java similarity index 100% rename from java-spring/commandside-backend-transactions/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferEventTest.java rename to java-spring/transactions-command-side-backend/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransferEventTest.java diff --git a/java-spring/transactions-command-side-service/build.gradle b/java-spring/transactions-command-side-service/build.gradle new file mode 100644 index 0000000..9524660 --- /dev/null +++ b/java-spring/transactions-command-side-service/build.gradle @@ -0,0 +1,20 @@ +apply plugin: 'spring-boot' + +apply plugin: VerifyEventStoreEnvironmentPlugin + +dependencies { + compile project(":transactions-command-side-web") + + compile "org.springframework.boot:spring-boot-starter-web" + compile "org.springframework.boot:spring-boot-starter-actuator" + + compile "net.chrisrichardson.eventstore.client:eventstore-http-stomp-client:$eventStoreClientVersion" + + testCompile "org.springframework.boot:spring-boot-starter-test" + +} + +test { + ignoreFailures true +} + diff --git a/java-spring/transactions-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceConfiguration.java b/java-spring/transactions-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceConfiguration.java new file mode 100644 index 0000000..e0185ba --- /dev/null +++ b/java-spring/transactions-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceConfiguration.java @@ -0,0 +1,27 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import net.chrisrichardson.eventstore.client.config.EventStoreHttpClientConfiguration; +import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CommandSideWebTransactionsConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +@Configuration +@Import({CommandSideWebTransactionsConfiguration.class, EventStoreHttpClientConfiguration.class}) +@EnableAutoConfiguration +@ComponentScan +public class TransactionsCommandSideServiceConfiguration { + + + @Bean + public HttpMessageConverters customConverters() { + HttpMessageConverter additional = new MappingJackson2HttpMessageConverter(); + return new HttpMessageConverters(additional); + } + +} diff --git a/java-spring/transactions-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/TransactionsCommandSideServiceMain.java b/java-spring/transactions-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/TransactionsCommandSideServiceMain.java new file mode 100644 index 0000000..2980e56 --- /dev/null +++ b/java-spring/transactions-command-side-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/main/TransactionsCommandSideServiceMain.java @@ -0,0 +1,11 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web.main; + +import net.chrisrichardson.eventstore.javaexamples.banking.web.TransactionsCommandSideServiceConfiguration; +import org.springframework.boot.SpringApplication; + +public class TransactionsCommandSideServiceMain { + + public static void main(String[] args) { + SpringApplication.run(TransactionsCommandSideServiceConfiguration.class, args); + } +} diff --git a/java-spring/transactions-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceIntegrationTest.java b/java-spring/transactions-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceIntegrationTest.java new file mode 100644 index 0000000..0ec3a77 --- /dev/null +++ b/java-spring/transactions-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceIntegrationTest.java @@ -0,0 +1,35 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.client.RestTemplate; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = TransactionsCommandSideServiceTestConfiguration.class) +@WebAppConfiguration +@IntegrationTest({"server.port=0", "management.port=0"}) +public class TransactionsCommandSideServiceIntegrationTest { + + @Value("${local.server.port}") + private int port; + + private String baseUrl(String path) { + return "http://localhost:" + port + "/" + path; + } + + @Autowired + RestTemplate restTemplate; + + + @Test + public void shouldCreateAccountsAndTransferMoney() { + // TBD + } + +} diff --git a/java-spring/transactions-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceTestConfiguration.java b/java-spring/transactions-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceTestConfiguration.java new file mode 100644 index 0000000..03667ea --- /dev/null +++ b/java-spring/transactions-command-side-service/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/web/TransactionsCommandSideServiceTestConfiguration.java @@ -0,0 +1,26 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.web; + +import org.springframework.boot.autoconfigure.web.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import java.util.Arrays; +import java.util.List; + +@Configuration +@Import(TransactionsCommandSideServiceConfiguration.class) +public class TransactionsCommandSideServiceTestConfiguration { + + @Bean + public RestTemplate restTemplate(HttpMessageConverters converters) { + RestTemplate restTemplate = new RestTemplate(); + HttpMessageConverter httpMessageConverter = converters.getConverters().get(0); + List> httpMessageConverters = Arrays.asList(new MappingJackson2HttpMessageConverter()); + restTemplate.setMessageConverters((List>) httpMessageConverters); + return restTemplate; + } +} diff --git a/java-spring/commandside-web-transactions/build.gradle b/java-spring/transactions-command-side-web/build.gradle similarity index 52% rename from java-spring/commandside-web-transactions/build.gradle rename to java-spring/transactions-command-side-web/build.gradle index 0809b76..d772d5b 100644 --- a/java-spring/commandside-web-transactions/build.gradle +++ b/java-spring/transactions-command-side-web/build.gradle @@ -1,7 +1,7 @@ dependencies { - compile project(":commandside-backend-transactions") - compile project(":web-common") + compile project(":transactions-command-side-backend") + compile project(":common-web") compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" } diff --git a/java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CommandSideWebTransactionsConfiguration.java b/java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CommandSideWebTransactionsConfiguration.java similarity index 100% rename from java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CommandSideWebTransactionsConfiguration.java rename to java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CommandSideWebTransactionsConfiguration.java diff --git a/java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferRequest.java b/java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferRequest.java similarity index 100% rename from java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferRequest.java rename to java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferRequest.java diff --git a/java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferResponse.java b/java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferResponse.java similarity index 100% rename from java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferResponse.java rename to java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/CreateMoneyTransferResponse.java diff --git a/java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/MoneyTransferController.java b/java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/MoneyTransferController.java similarity index 100% rename from java-spring/commandside-web-transactions/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/MoneyTransferController.java rename to java-spring/transactions-command-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/commandside/transactions/MoneyTransferController.java diff --git a/kill-all-services.sh b/kill-all-services.sh new file mode 100755 index 0000000..0497b8e --- /dev/null +++ b/kill-all-services.sh @@ -0,0 +1,4 @@ +#! /bin/bash + +kill `cat account-cs.pid account-qs.pid transfers-cs.pid` +rm account-cs.pid account-qs.pid transfers-cs.pid diff --git a/run-all-services.sh b/run-all-services.sh new file mode 100755 index 0000000..6372d1c --- /dev/null +++ b/run-all-services.sh @@ -0,0 +1,31 @@ +#! /bin/bash -e + +# Execute this script in the java-spring or scala-spring directory +# Runs all of the services + +if [[ -f account-cs.pid ]]; then + echo pid file exists + exit 1 +fi + +java -jar accounts-command-side-service/build/libs/accounts-command-side-service.jar > account-cs.log & +echo $! > account-cs.pid + +java -jar accounts-query-side-service/build/libs/accounts-query-side-service.jar --server.port=8081 > account-qs.log & +echo $! > account-qs.pid + +java -jar transactions-command-side-service/build/libs/transactions-command-side-service.jar --server.port=8082 > transfers-cs.log & +echo $! > transfers-cs.pid + +echo -n waiting for services.... + +while [[ true ]]; do + nc -z -w 4 localhost 8080 && nc -z -w 4 localhost 8081 && nc -z -w 4 localhost 8082 + if [[ "$?" -eq "0" ]]; then + echo connected + break + fi + echo -n . + sleep 1 +done + diff --git a/run-e2e-test-all.sh b/run-e2e-test-all.sh new file mode 100755 index 0000000..ed625a7 --- /dev/null +++ b/run-e2e-test-all.sh @@ -0,0 +1,6 @@ +#! /bin/bash -e + +for dir in java-spring scala-spring; do + (cd $dir ; ../run-e2e-test.sh) +done + diff --git a/run-e2e-test.sh b/run-e2e-test.sh new file mode 100755 index 0000000..1f03c7c --- /dev/null +++ b/run-e2e-test.sh @@ -0,0 +1,16 @@ +#! /bin/bash -e + +# Must be run in the java-spring or scala-spring directories + +echo starting services + +../run-all-services.sh + +echo running test + +./gradlew :e2e-test:cleanTest :e2e-test:test + +echo killing services + +../kill-all-services.sh + diff --git a/sample-set-server-env.sh b/sample-set-server-env.sh new file mode 100755 index 0000000..622abb9 --- /dev/null +++ b/sample-set-server-env.sh @@ -0,0 +1,9 @@ +#! /bin/bash -e + +export EVENT_STORE_USER_ID=Aladdin +export EVENT_STORE_PASSWORD="open sesame" +export EVENT_STORE_URL=serverUrl +export EVENT_STORE_STOMP_SERVER_HOST=serverhost +export EVENT_STORE_STOMP_SERVER_PORT=serverPort + +export SPRING_DATA_MONGODB_URI=mongodb://192.168.59.103/mydb diff --git a/scala-spring/README.md b/scala-spring/README.md index 5e0690a..234fe74 100644 --- a/scala-spring/README.md +++ b/scala-spring/README.md @@ -1,5 +1,7 @@ This is the Scala/Spring version of the Event Sourcing/CQRS money transfer example application. +# About the application + This application consists of three microservices: * Account Service - the command side business logic for Accounts @@ -8,25 +10,28 @@ This application consists of three microservices: The Account Service consists of the following modules: - * commandside-backend-accounts - the Account aggregate - * commandside-web-accounts - a REST API for creating and retrieving Accounts - + * accounts-command-side-backend - the Account aggregate + * accounts-command-side-web - a REST API for creating and retrieving Accounts + * accounts-command-side-service - a standalone microservice + The Money Transfer Service consists of the following modules: - * commandside-backend-transactions - the MoneyTransfer aggregate - * commandside-web-transactions - a REST API for creating and retrieving Money Transfers + * transactions-command-side-backend - the MoneyTransfer aggregate + * transactions-command-side-web - a REST API for creating and retrieving Money Transfers + * transactions-command-side-service - a standalone microservice The Query Service consists the following modules: - * queryside-backend - MongoDB-based, denormalized view of Accounts and MoneyTransfers - * queryside-web - a REST API for querying the denormalized view + * accounts-query-side-backend - MongoDB-based, denormalized view of Accounts and MoneyTransfers + * accounts-query-side-web - a REST API for querying the denormalized view + * accounts-query-side-service - a standalone microservice -In order to be used with the embedded Event Store, the three services are currently packaged as a single monolithic web application: +# Deploying the application - * monolithic-web - all-in-one, monolithic packaging of the application +These services can be deployed either as either separate standalone services using the Event Store server, or they can be deployed as a monolithic application for simpified integration testing. -As well as the above modules there are also: +The three services can also be packaged as a single monolithic web application in order to be used with the embedded Event Store: - * common-backend - code that is shared between the command side and the query side, primarily events and value objects - * backend-integration-tests - integrations tests for the backend - \ No newline at end of file + * monolithic-service - all-in-one, monolithic packaging of the application + + diff --git a/scala-spring/commandside-backend-transactions/build.gradle b/scala-spring/accounts-command-side-backend/build.gradle similarity index 99% rename from scala-spring/commandside-backend-transactions/build.gradle rename to scala-spring/accounts-command-side-backend/build.gradle index 1e4e33d..e4686a5 100644 --- a/scala-spring/commandside-backend-transactions/build.gradle +++ b/scala-spring/accounts-command-side-backend/build.gradle @@ -2,4 +2,4 @@ dependencies { compile "org.scala-lang:scala-library:2.10.2" compile project(":common-backend") compile "net.chrisrichardson.eventstore.client:eventstore-client-event-handling:$eventStoreClientVersion" -} \ No newline at end of file +} diff --git a/scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/Account.scala b/scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/Account.scala similarity index 100% rename from scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/Account.scala rename to scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/Account.scala diff --git a/scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountCommands.scala b/scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountCommands.scala similarity index 100% rename from scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountCommands.scala rename to scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountCommands.scala diff --git a/scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountConfiguration.scala b/scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountConfiguration.scala similarity index 100% rename from scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountConfiguration.scala rename to scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountConfiguration.scala diff --git a/scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountService.scala b/scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountService.scala similarity index 100% rename from scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountService.scala rename to scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/AccountService.scala diff --git a/scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/TransferWorkflowAccountHandlers.scala b/scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/TransferWorkflowAccountHandlers.scala similarity index 89% rename from scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/TransferWorkflowAccountHandlers.scala rename to scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/TransferWorkflowAccountHandlers.scala index cae371a..8ac21ea 100644 --- a/scala-spring/commandside-backend-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/TransferWorkflowAccountHandlers.scala +++ b/scala-spring/accounts-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/accounts/TransferWorkflowAccountHandlers.scala @@ -20,7 +20,8 @@ class TransferWorkflowAccountHandlers(eventStore: EventStore) extends CompoundEv @EventHandlerMethod val performCredit = handlerForEvent[DebitRecordedEvent] { de => - existingEntity[Account](de.event.details.toAccountId) <== CreditAccountCommand(de.event.details.amount, de.entityId) + existingEntity[Account](de.event.details.toAccountId) <== + CreditAccountCommand(de.event.details.amount, de.entityId) } } diff --git a/scala-spring/accounts-command-side-service/build.gradle b/scala-spring/accounts-command-side-service/build.gradle new file mode 100644 index 0000000..9326417 --- /dev/null +++ b/scala-spring/accounts-command-side-service/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'scala' +apply plugin: 'spring-boot' +apply plugin: VerifyEventStoreEnvironmentPlugin + +dependencies { + compile "org.scala-lang:scala-library:2.10.2" + compile project(":accounts-command-side-web") + + compile "org.springframework.boot:spring-boot-starter-web" + compile "org.springframework.boot:spring-boot-starter-actuator" + + compile "net.chrisrichardson.eventstore.client:eventstore-http-stomp-client:$eventStoreClientVersion" + + testCompile "org.springframework.boot:spring-boot-starter-test" + testCompile scalaTestDependency + +} + +test { + ignoreFailures true +} + diff --git a/scala-spring/accounts-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceConfiguration.scala b/scala-spring/accounts-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceConfiguration.scala new file mode 100644 index 0000000..b86536d --- /dev/null +++ b/scala-spring/accounts-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceConfiguration.scala @@ -0,0 +1,14 @@ +package net.chrisrichardson.eventstore.examples.bank.web + +import net.chrisrichardson.eventstore.client.config.EventStoreHttpClientConfiguration +import net.chrisrichardson.eventstore.examples.bank.web.accounts.CommandSideWebAccountsConfiguration +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation._ + +@Configuration +@EnableAutoConfiguration +@Import(Array(classOf[CommandSideWebAccountsConfiguration], classOf[EventStoreHttpClientConfiguration])) +@ComponentScan +class AccountsCommandSideServiceConfiguration { + +} diff --git a/scala-spring/accounts-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/AccountsCommandSideServiceMain.scala b/scala-spring/accounts-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/AccountsCommandSideServiceMain.scala new file mode 100644 index 0000000..c10e188 --- /dev/null +++ b/scala-spring/accounts-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/AccountsCommandSideServiceMain.scala @@ -0,0 +1,10 @@ +package net.chrisrichardson.eventstore.examples.bank.web.main + +import net.chrisrichardson.eventstore.examples.bank.web.AccountsCommandSideServiceConfiguration +import org.springframework.boot.SpringApplication + +object AccountsCommandSideServiceMain { + + def main(args: Array[String]) : Unit = SpringApplication.run(classOf[AccountsCommandSideServiceConfiguration], args :_ *) + +} diff --git a/scala-spring/accounts-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceIntegrationTest.scala b/scala-spring/accounts-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceIntegrationTest.scala new file mode 100644 index 0000000..0fbe451 --- /dev/null +++ b/scala-spring/accounts-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceIntegrationTest.scala @@ -0,0 +1,32 @@ +package net.chrisrichardson.eventstore.examples.bank.web + +import net.chrisrichardson.eventstore.examples.bank.web.accounts.controllers.{CreateAccountRequest, CreateAccountResponse} +import org.junit.Assert +import org.junit.runner.RunWith +import org.scalatest.FlatSpec +import org.scalatest.junit.JUnitRunner +import org.springframework.boot.SpringApplication +import org.springframework.web.client.RestTemplate + +@RunWith(classOf[JUnitRunner]) +class AccountsCommandSideServiceIntegrationTest extends FlatSpec { + + val sa = new SpringApplication(classOf[AccountsCommandSideServiceTestConfiguration]) + val ctx = sa.run() + + // var server = ctx.getBean(classOf[EmbeddedServletContainer]) + + val port = 8080 + + val baseUrl = s"http://localhost:$port/" + + val restTemplate = ctx.getBean(classOf[RestTemplate]) + + it should "create account" in { + + val CreateAccountResponse(accountId) = restTemplate.postForEntity(s"$baseUrl/accounts", CreateAccountRequest(BigDecimal(500)), classOf[CreateAccountResponse]).getBody + Assert.assertNotNull(accountId) + + } + +} diff --git a/scala-spring/accounts-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceTestConfiguration.scala b/scala-spring/accounts-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceTestConfiguration.scala new file mode 100644 index 0000000..424a1f9 --- /dev/null +++ b/scala-spring/accounts-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsCommandSideServiceTestConfiguration.scala @@ -0,0 +1,26 @@ +package net.chrisrichardson.eventstore.examples.bank.web + + +import com.fasterxml.jackson.databind.ObjectMapper +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation.{Bean, Import, Configuration} +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter +import org.springframework.web.client.RestTemplate +import scala.collection.JavaConversions._ + +@Configuration +@Import(Array(classOf[AccountsCommandSideServiceConfiguration])) +class AccountsCommandSideServiceTestConfiguration { + + @Bean + def restTemplate(scalaObjectMapper: ObjectMapper) = { + val restTemplate = new RestTemplate() + restTemplate.getMessageConverters foreach { + case mc: MappingJackson2HttpMessageConverter => + mc.setObjectMapper(scalaObjectMapper) + case _ => + } + restTemplate + } + +} diff --git a/scala-spring/commandside-web-accounts/build.gradle b/scala-spring/accounts-command-side-web/build.gradle similarity index 69% rename from scala-spring/commandside-web-accounts/build.gradle rename to scala-spring/accounts-command-side-web/build.gradle index 3f07dc2..827fd7c 100644 --- a/scala-spring/commandside-web-accounts/build.gradle +++ b/scala-spring/accounts-command-side-web/build.gradle @@ -2,9 +2,9 @@ apply plugin: 'scala' dependencies { compile "org.scala-lang:scala-library:2.10.2" - compile project(":commandside-backend-accounts") - compile project(":web-common") + compile project(":accounts-command-side-backend") + compile project(":common-web") testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" testCompile scalaTestDependency -} \ No newline at end of file +} diff --git a/scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/CommandSideWebAccountsConfiguration.scala b/scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/CommandSideWebAccountsConfiguration.scala similarity index 100% rename from scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/CommandSideWebAccountsConfiguration.scala rename to scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/CommandSideWebAccountsConfiguration.scala diff --git a/scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/AccountController.scala b/scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/AccountController.scala similarity index 100% rename from scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/AccountController.scala rename to scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/AccountController.scala diff --git a/scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountRequest.scala b/scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountRequest.scala similarity index 100% rename from scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountRequest.scala rename to scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountRequest.scala diff --git a/scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountResponse.scala b/scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountResponse.scala similarity index 100% rename from scala-spring/commandside-web-accounts/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountResponse.scala rename to scala-spring/accounts-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/accounts/controllers/CreateAccountResponse.scala diff --git a/scala-spring/queryside-backend/build.gradle b/scala-spring/accounts-query-side-backend/build.gradle similarity index 100% rename from scala-spring/queryside-backend/build.gradle rename to scala-spring/accounts-query-side-backend/build.gradle diff --git a/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfo.scala b/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfo.scala similarity index 100% rename from scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfo.scala rename to scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfo.scala diff --git a/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoQueryService.scala b/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoQueryService.scala new file mode 100644 index 0000000..b8e1f3f --- /dev/null +++ b/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoQueryService.scala @@ -0,0 +1,17 @@ +package net.chrisrichardson.eventstore.examples.bank.queryside + +import net.chrisrichardson.eventstore.EntityId + +class AccountInfoQueryService(accountInfoRepository : AccountInfoRepository) { + + def findByAccountId(accountId : EntityId) : AccountInfo = { + val account = accountInfoRepository.findOne(accountId.id) + if (account == null) + throw new AccountNotFoundException(accountId) + else + account + } + +} + +class AccountNotFoundException(accountId : EntityId) extends RuntimeException("Account not found " + accountId) \ No newline at end of file diff --git a/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoUpdateService.scala b/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoUpdateService.scala similarity index 92% rename from scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoUpdateService.scala rename to scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoUpdateService.scala index d09841f..ebb5394 100644 --- a/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoUpdateService.scala +++ b/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoUpdateService.scala @@ -29,7 +29,10 @@ class AccountInfoUpdateService(accountInfoRepository : AccountInfoRepository, mo logger.info("About to save") try { - accountInfoRepository.save(AccountInfo(de.entityId.id, toIntegerRepr(de.event.initialBalance), Seq(), Seq(), de.eventId.asString)) + if (de.event.initialBalance != null) + accountInfoRepository.save(AccountInfo(de.entityId.id, toIntegerRepr(de.event.initialBalance), Seq(), Seq(), de.eventId.asString)) + else + logger.error("Event with initialBalance == null {}", de.entityId) } catch { case t : Throwable => diff --git a/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerySideConfiguration.scala b/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerySideConfiguration.scala similarity index 100% rename from scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerySideConfiguration.scala rename to scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerySideConfiguration.scala diff --git a/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerysideDependencyChecker.scala b/scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerysideDependencyChecker.scala similarity index 100% rename from scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerysideDependencyChecker.scala rename to scala-spring/accounts-query-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/QuerysideDependencyChecker.scala diff --git a/scala-spring/accounts-query-side-service/build.gradle b/scala-spring/accounts-query-side-service/build.gradle new file mode 100644 index 0000000..8907076 --- /dev/null +++ b/scala-spring/accounts-query-side-service/build.gradle @@ -0,0 +1,23 @@ +apply plugin: 'scala' +apply plugin: 'spring-boot' +apply plugin: VerifyMongoDBConfigurationPlugin +apply plugin: VerifyEventStoreEnvironmentPlugin + +dependencies { + compile "org.scala-lang:scala-library:2.10.2" + compile project(":accounts-query-side-web") + + compile "org.springframework.boot:spring-boot-starter-web" + compile "org.springframework.boot:spring-boot-starter-actuator" + + compile "net.chrisrichardson.eventstore.client:eventstore-http-stomp-client:$eventStoreClientVersion" + + testCompile "org.springframework.boot:spring-boot-starter-test" + testCompile scalaTestDependency + +} + +test { + ignoreFailures true +} + diff --git a/scala-spring/accounts-query-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceConfiguration.scala b/scala-spring/accounts-query-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceConfiguration.scala new file mode 100644 index 0000000..b9703a2 --- /dev/null +++ b/scala-spring/accounts-query-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceConfiguration.scala @@ -0,0 +1,14 @@ +package net.chrisrichardson.eventstore.examples.bank.web + +import net.chrisrichardson.eventstore.client.config.EventStoreHttpClientConfiguration +import net.chrisrichardson.eventstore.examples.bank.web.queryside.QuerySideWebConfiguration +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation._ + +@Configuration +@EnableAutoConfiguration +@Import(Array(classOf[QuerySideWebConfiguration], classOf[EventStoreHttpClientConfiguration])) +@ComponentScan +class AccountsQuerySideServiceConfiguration { + +} diff --git a/scala-spring/accounts-query-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/AccountsQuerySideServiceMain.scala b/scala-spring/accounts-query-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/AccountsQuerySideServiceMain.scala new file mode 100644 index 0000000..4be2004 --- /dev/null +++ b/scala-spring/accounts-query-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/AccountsQuerySideServiceMain.scala @@ -0,0 +1,10 @@ +package net.chrisrichardson.eventstore.examples.bank.web.main + +import net.chrisrichardson.eventstore.examples.bank.web.AccountsQuerySideServiceConfiguration +import org.springframework.boot.SpringApplication + +object AccountsQuerySideServiceMain { + + def main(args: Array[String]) : Unit = SpringApplication.run(classOf[AccountsQuerySideServiceConfiguration], args :_ *) + +} diff --git a/scala-spring/accounts-query-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceIntegrationTest.scala b/scala-spring/accounts-query-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceIntegrationTest.scala new file mode 100644 index 0000000..8c8b66d --- /dev/null +++ b/scala-spring/accounts-query-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceIntegrationTest.scala @@ -0,0 +1,30 @@ +package net.chrisrichardson.eventstore.examples.bank.web + +import org.junit.runner.RunWith +import org.scalatest.FlatSpec +import org.scalatest.concurrent.Eventually._ +import org.scalatest.junit.JUnitRunner +import org.scalatest.time.{Millis, Span} +import org.springframework.boot.SpringApplication +import org.springframework.web.client.RestTemplate + +@RunWith(classOf[JUnitRunner]) +class AccountsQuerySideServiceIntegrationTest extends FlatSpec { + + val sa = new SpringApplication(classOf[AccountsQuerySideServiceTestConfiguration]) + val ctx = sa.run() + + // var server = ctx.getBean(classOf[EmbeddedServletContainer]) + + val port = 8080 + + val baseUrl = s"http://localhost:$port/" + + val restTemplate = ctx.getBean(classOf[RestTemplate]) + + implicit val reallyLongPatienceConfig = PatienceConfig(timeout = Span(10 * 1000, Millis), interval = Span(1 * 1000, Millis)) + + it should "create accounts and transfer money" in { + // FIXME + } +} diff --git a/scala-spring/accounts-query-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceTestConfiguration.scala b/scala-spring/accounts-query-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceTestConfiguration.scala new file mode 100644 index 0000000..bec9562 --- /dev/null +++ b/scala-spring/accounts-query-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/AccountsQuerySideServiceTestConfiguration.scala @@ -0,0 +1,26 @@ +package net.chrisrichardson.eventstore.examples.bank.web + + +import com.fasterxml.jackson.databind.ObjectMapper +import org.springframework.context.annotation.{Bean, Configuration, Import} +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter +import org.springframework.web.client.RestTemplate + +import scala.collection.JavaConversions._ + +@Configuration +@Import(Array(classOf[AccountsQuerySideServiceConfiguration])) +class AccountsQuerySideServiceTestConfiguration { + + @Bean + def restTemplate(scalaObjectMapper: ObjectMapper) = { + val restTemplate = new RestTemplate() + restTemplate.getMessageConverters foreach { + case mc: MappingJackson2HttpMessageConverter => + mc.setObjectMapper(scalaObjectMapper) + case _ => + } + restTemplate + } + +} diff --git a/scala-spring/queryside-web/build.gradle b/scala-spring/accounts-query-side-web/build.gradle similarity index 76% rename from scala-spring/queryside-web/build.gradle rename to scala-spring/accounts-query-side-web/build.gradle index 420454f..8c99463 100644 --- a/scala-spring/queryside-web/build.gradle +++ b/scala-spring/accounts-query-side-web/build.gradle @@ -2,8 +2,8 @@ apply plugin: 'scala' dependencies { compile "org.scala-lang:scala-library:2.10.2" - compile project(":queryside-backend") - compile project(":web-common") + compile project(":accounts-query-side-backend") + compile project(":common-web") compile "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion" diff --git a/scala-spring/queryside-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/QuerySideWebConfiguration.scala b/scala-spring/accounts-query-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/QuerySideWebConfiguration.scala similarity index 77% rename from scala-spring/queryside-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/QuerySideWebConfiguration.scala rename to scala-spring/accounts-query-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/QuerySideWebConfiguration.scala index 154997e..a564d04 100644 --- a/scala-spring/queryside-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/QuerySideWebConfiguration.scala +++ b/scala-spring/accounts-query-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/QuerySideWebConfiguration.scala @@ -1,11 +1,13 @@ package net.chrisrichardson.eventstore.examples.bank.web.queryside import net.chrisrichardson.eventstore.examples.bank.queryside.QuerySideConfiguration +import net.chrisrichardson.eventstore.subscriptions.EnableEventHandlers import org.springframework.context.annotation._ @Configuration @Import(Array(classOf[QuerySideConfiguration])) @ComponentScan +@EnableEventHandlers class QuerySideWebConfiguration { } diff --git a/scala-spring/queryside-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/controllers/AccountQuerySideController.scala b/scala-spring/accounts-query-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/controllers/AccountQuerySideController.scala similarity index 57% rename from scala-spring/queryside-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/controllers/AccountQuerySideController.scala rename to scala-spring/accounts-query-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/controllers/AccountQuerySideController.scala index 1fe68df..d0c3e3a 100644 --- a/scala-spring/queryside-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/controllers/AccountQuerySideController.scala +++ b/scala-spring/accounts-query-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/queryside/controllers/AccountQuerySideController.scala @@ -1,9 +1,10 @@ package net.chrisrichardson.eventstore.examples.bank.web.queryside.controllers import net.chrisrichardson.eventstore.EntityId -import net.chrisrichardson.eventstore.examples.bank.queryside.AccountInfoQueryService +import net.chrisrichardson.eventstore.examples.bank.queryside.{AccountNotFoundException, AccountInfoQueryService} import org.springframework.beans.factory.annotation.Autowired -import org.springframework.web.bind.annotation.{PathVariable, RequestMapping, RequestMethod, RestController} +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation._ @RestController class AccountQuerySideController @Autowired() (accountInfoQueryService : AccountInfoQueryService) { @@ -11,4 +12,7 @@ class AccountQuerySideController @Autowired() (accountInfoQueryService : Account @RequestMapping(value=Array("/accounts/{accountId}"), method = Array(RequestMethod.GET)) def get(@PathVariable accountId : String) = accountInfoQueryService.findByAccountId(EntityId(accountId)) + @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "account not found") + @ExceptionHandler(Array(classOf[AccountNotFoundException])) + def accountNotFound() {} } diff --git a/scala-spring/backend-integration-tests/build.gradle b/scala-spring/backend-integration-tests/build.gradle index 608eb53..87c60b3 100644 --- a/scala-spring/backend-integration-tests/build.gradle +++ b/scala-spring/backend-integration-tests/build.gradle @@ -5,9 +5,9 @@ dependencies { compile "org.scala-lang:scala-library:2.10.2" - compile project(":commandside-backend-transactions") - compile project(":commandside-backend-accounts") - compile project(":queryside-backend") + compile project(":transactions-command-side-backend") + compile project(":accounts-command-side-backend") + compile project(":accounts-query-side-backend") testCompile scalaTestDependency diff --git a/scala-spring/buildSrc/src/main/groovy/VerifyEventStoreEnvironmentPlugin.groovy b/scala-spring/buildSrc/src/main/groovy/VerifyEventStoreEnvironmentPlugin.groovy new file mode 100644 index 0000000..90e18ce --- /dev/null +++ b/scala-spring/buildSrc/src/main/groovy/VerifyEventStoreEnvironmentPlugin.groovy @@ -0,0 +1,16 @@ +import org.gradle.api.* + + +class VerifyEventStoreEnvironmentPlugin implements Plugin { + void apply(Project project) { + project.test { + beforeSuite { x -> + if (x.parent == null) { + if (System.getenv("EVENT_STORE_URL") == null) + logger.warn("\nPLEASE make sure that Event Store-related environment variables including EVENT_STORE_URL are set, see sample-set-remote-env.sh !!!!\n") + } + } + } + } +} + diff --git a/scala-spring/web-common/build.gradle b/scala-spring/common-web/build.gradle similarity index 100% rename from scala-spring/web-common/build.gradle rename to scala-spring/common-web/build.gradle diff --git a/scala-spring/web-common/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/util/WebUtil.scala b/scala-spring/common-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/util/WebUtil.scala similarity index 100% rename from scala-spring/web-common/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/util/WebUtil.scala rename to scala-spring/common-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/util/WebUtil.scala diff --git a/scala-spring/e2e-test/build.gradle b/scala-spring/e2e-test/build.gradle new file mode 100644 index 0000000..77b8e20 --- /dev/null +++ b/scala-spring/e2e-test/build.gradle @@ -0,0 +1,20 @@ +apply plugin: 'scala' +apply plugin: VerifyMongoDBConfigurationPlugin + +dependencies { + compile "org.scala-lang:scala-library:2.10.2" + + testCompile project(":accounts-command-side-web") + testCompile project(":transactions-command-side-web") + testCompile project(":accounts-query-side-web") + + testCompile "junit:junit:4.11" + testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" + testCompile scalaTestDependency + +} + +test { + ignoreFailures true +} + diff --git a/scala-spring/e2e-test/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.scala b/scala-spring/e2e-test/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.scala new file mode 100644 index 0000000..c4650bd --- /dev/null +++ b/scala-spring/e2e-test/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.scala @@ -0,0 +1,67 @@ +package net.chrisrichardson.eventstore.examples.bank.web + +import net.chrisrichardson.eventstore.EntityId +import net.chrisrichardson.eventstore.examples.bank.queryside.AccountInfo +import net.chrisrichardson.eventstore.examples.bank.web.accounts.controllers.{CreateAccountRequest, CreateAccountResponse} +import net.chrisrichardson.eventstore.examples.bank.web.transactions.controllers.{CreateMoneyTransferResponse, GetMoneyTransferResponse, MoneyTransferRequest} +import net.chrisrichardson.eventstore.json.EventStoreCommonObjectMapping.EventStoreCommonObjectMapper +import org.junit.runner.RunWith +import org.scalatest.FlatSpec +import org.scalatest.Matchers._ +import org.scalatest.concurrent.Eventually._ +import org.scalatest.junit.JUnitRunner +import org.scalatest.time.{Millis, Span} +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter +import org.springframework.web.client.RestTemplate +import scala.collection.JavaConversions._ + +@RunWith(classOf[JUnitRunner]) +class EndToEndTest extends FlatSpec { + + val accountsCommandSideBaseUrl = s"http://localhost:8080/" + val accountsQuerySideBaseUrl = s"http://localhost:8081/" + val transactionsCommandSideBaseUrl = s"http://localhost:8082/" + + val restTemplate = new RestTemplate() + restTemplate.getMessageConverters foreach { + case mc: MappingJackson2HttpMessageConverter => + mc.setObjectMapper(EventStoreCommonObjectMapper) + case _ => + } + + implicit val reallyLongPatienceConfig = PatienceConfig(timeout = Span(10 * 1000, Millis), interval = Span(1 * 1000, Millis)) + + it should "create accounts and transfer money" in { + + val CreateAccountResponse(fromAccountId) = restTemplate.postForEntity(s"$accountsCommandSideBaseUrl/accounts", CreateAccountRequest(BigDecimal(500)), classOf[CreateAccountResponse]).getBody + val CreateAccountResponse(toAccountId) = restTemplate.postForEntity(s"$accountsCommandSideBaseUrl/accounts", CreateAccountRequest(BigDecimal(100)), classOf[CreateAccountResponse]).getBody + + eventually { + val accountInfo = restTemplate.getForEntity(s"$accountsQuerySideBaseUrl/accounts/" + fromAccountId, classOf[AccountInfo]).getBody + accountInfo should not be null + val AccountInfo(accountId, initialBalance, _, _, _) = accountInfo + accountId should be(fromAccountId) + initialBalance should be(500*100) + }(reallyLongPatienceConfig) + + + val CreateMoneyTransferResponse(transactionId) = restTemplate.postForEntity(s"$transactionsCommandSideBaseUrl/transfers", + MoneyTransferRequest(EntityId(fromAccountId), EntityId(toAccountId), BigDecimal(150)), classOf[CreateMoneyTransferResponse]).getBody + + eventually { + val AccountInfo(_, newFromAccountBalance, _, _, _) = restTemplate.getForEntity(s"$accountsQuerySideBaseUrl/accounts/" + fromAccountId, classOf[AccountInfo]).getBody + newFromAccountBalance should be(350*100) + }(reallyLongPatienceConfig) + eventually { + val AccountInfo(_, newToAccountBalance, _, _, _) = restTemplate.getForEntity(s"$accountsQuerySideBaseUrl/accounts/" + toAccountId, classOf[AccountInfo]).getBody + newToAccountBalance should be(250*100) + }(reallyLongPatienceConfig) + + eventually { + val GetMoneyTransferResponse(_, state) = restTemplate.getForEntity(s"$transactionsCommandSideBaseUrl/transfers/" + transactionId, classOf[GetMoneyTransferResponse]).getBody + state should be("COMPLETED$") + }(reallyLongPatienceConfig) + + } + +} diff --git a/scala-spring/gradle.properties b/scala-spring/gradle.properties index 03a293b..e1b7905 100644 --- a/scala-spring/gradle.properties +++ b/scala-spring/gradle.properties @@ -5,5 +5,5 @@ scalaTestDependency=org.scalatest:scalatest_2.10:2.0 springBootVersion=1.1.10.RELEASE -eventStoreCommonVersion=0.2 -eventStoreClientVersion=0.2 +eventStoreClientVersion=0.5 +eventStoreCommonVersion=0.5 diff --git a/scala-spring/monolithic-web/build.gradle b/scala-spring/monolithic-service/build.gradle similarity index 76% rename from scala-spring/monolithic-web/build.gradle rename to scala-spring/monolithic-service/build.gradle index f27fcae..30fb308 100644 --- a/scala-spring/monolithic-web/build.gradle +++ b/scala-spring/monolithic-service/build.gradle @@ -4,9 +4,9 @@ apply plugin: VerifyMongoDBConfigurationPlugin dependencies { compile "org.scala-lang:scala-library:2.10.2" - compile project(":commandside-web-accounts") - compile project(":commandside-web-transactions") - compile project(":queryside-web") + compile project(":accounts-command-side-web") + compile project(":transactions-command-side-web") + compile project(":accounts-query-side-web") compile "org.springframework.boot:spring-boot-starter-web" compile "org.springframework.boot:spring-boot-starter-actuator" diff --git a/scala-spring/monolithic-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppConfiguration.scala b/scala-spring/monolithic-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppConfiguration.scala similarity index 100% rename from scala-spring/monolithic-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppConfiguration.scala rename to scala-spring/monolithic-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppConfiguration.scala diff --git a/scala-spring/monolithic-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/BankingMain.scala b/scala-spring/monolithic-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/BankingMain.scala similarity index 100% rename from scala-spring/monolithic-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/BankingMain.scala rename to scala-spring/monolithic-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/BankingMain.scala diff --git a/scala-spring/monolithic-web/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankWebIntegrationTest.scala b/scala-spring/monolithic-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankWebIntegrationTest.scala similarity index 75% rename from scala-spring/monolithic-web/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankWebIntegrationTest.scala rename to scala-spring/monolithic-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankWebIntegrationTest.scala index 49359a2..72d9087 100644 --- a/scala-spring/monolithic-web/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankWebIntegrationTest.scala +++ b/scala-spring/monolithic-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankWebIntegrationTest.scala @@ -2,17 +2,17 @@ package net.chrisrichardson.eventstore.examples.bank.web import net.chrisrichardson.eventstore.EntityId import net.chrisrichardson.eventstore.examples.bank.queryside.AccountInfo -import net.chrisrichardson.eventstore.examples.bank.transactions.TransferStates -import net.chrisrichardson.eventstore.examples.bank.web.accounts.controllers.{GetAccountResponse, CreateAccountRequest, CreateAccountResponse} -import net.chrisrichardson.eventstore.examples.bank.web.transactions.controllers.{GetMoneyTransferResponse, MoneyTransferRequest, CreateMoneyTransferResponse} +import net.chrisrichardson.eventstore.examples.bank.web.accounts.controllers.{CreateAccountRequest, CreateAccountResponse} +import net.chrisrichardson.eventstore.examples.bank.web.transactions.controllers.{CreateMoneyTransferResponse, GetMoneyTransferResponse, MoneyTransferRequest} import org.junit.runner.RunWith import org.scalatest.FlatSpec +import org.scalatest.Matchers._ import org.scalatest.concurrent.Eventually._ import org.scalatest.junit.JUnitRunner import org.scalatest.time.{Millis, Span} import org.springframework.boot.SpringApplication -import org.springframework.web.client.RestTemplate -import org.scalatest.Matchers._ +import org.springframework.http.HttpStatus +import org.springframework.web.client.{HttpClientErrorException, RestTemplate} @RunWith(classOf[JUnitRunner]) class BankWebIntegrationTest extends FlatSpec { @@ -35,7 +35,11 @@ class BankWebIntegrationTest extends FlatSpec { val CreateAccountResponse(fromAccountId) = restTemplate.postForEntity(s"$baseUrl/accounts", CreateAccountRequest(BigDecimal(500)), classOf[CreateAccountResponse]).getBody val CreateAccountResponse(toAccountId) = restTemplate.postForEntity(s"$baseUrl/accounts", CreateAccountRequest(BigDecimal(100)), classOf[CreateAccountResponse]).getBody - val AccountInfo(accountId, initialBalance, _, _, _) = restTemplate.getForEntity(s"$baseUrl/accounts/" + fromAccountId, classOf[AccountInfo]).getBody + val AccountInfo(accountId, initialBalance, _, _, _) = eventually { + val accountInfo = restTemplate.getForEntity(s"$baseUrl/accounts/" + fromAccountId, classOf[AccountInfo]).getBody + accountInfo should not be null + accountInfo + }(reallyLongPatienceConfig) accountId should be(fromAccountId) initialBalance should be(500*100) @@ -59,4 +63,8 @@ class BankWebIntegrationTest extends FlatSpec { } + it should "Return 404 for non-existent account" in { + val t = the[HttpClientErrorException] thrownBy restTemplate.getForEntity(s"$baseUrl/accounts/" + "non-existent-account-id", classOf[AccountInfo]) + t.getStatusCode shouldBe HttpStatus.NOT_FOUND + } } diff --git a/scala-spring/monolithic-web/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppTestConfiguration.scala b/scala-spring/monolithic-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppTestConfiguration.scala similarity index 100% rename from scala-spring/monolithic-web/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppTestConfiguration.scala rename to scala-spring/monolithic-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/BankingWebAppTestConfiguration.scala diff --git a/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoQueryService.scala b/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoQueryService.scala deleted file mode 100644 index 11ae25a..0000000 --- a/scala-spring/queryside-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/queryside/AccountInfoQueryService.scala +++ /dev/null @@ -1,9 +0,0 @@ -package net.chrisrichardson.eventstore.examples.bank.queryside - -import net.chrisrichardson.eventstore.EntityId - -class AccountInfoQueryService(accountInfoRepository : AccountInfoRepository) { - - def findByAccountId(accountId : EntityId) : AccountInfo = accountInfoRepository.findOne(accountId.id) - -} diff --git a/scala-spring/settings.gradle b/scala-spring/settings.gradle index f0e14d4..3beee8e 100644 --- a/scala-spring/settings.gradle +++ b/scala-spring/settings.gradle @@ -1,18 +1,23 @@ -include 'web-common' +include 'common-web' include 'common-backend' -include 'commandside-backend-accounts' -include 'commandside-backend-transactions' -include 'commandside-web-accounts' -include 'commandside-web-transactions' +include 'accounts-command-side-backend' +include 'transactions-command-side-backend' +include 'accounts-command-side-web' +include 'transactions-command-side-web' -include 'queryside-backend' -include 'queryside-web' +include 'accounts-query-side-backend' +include 'accounts-query-side-web' include 'backend-integration-tests' -include 'monolithic-web' +include 'monolithic-service' +include 'accounts-command-side-service' +include 'accounts-query-side-service' +include 'transactions-command-side-service' + +include 'e2e-test' rootProject.name = 'scala-spring-event-sourcing-example' diff --git a/scala-spring/commandside-backend-accounts/build.gradle b/scala-spring/transactions-command-side-backend/build.gradle similarity index 99% rename from scala-spring/commandside-backend-accounts/build.gradle rename to scala-spring/transactions-command-side-backend/build.gradle index 1e4e33d..e4686a5 100644 --- a/scala-spring/commandside-backend-accounts/build.gradle +++ b/scala-spring/transactions-command-side-backend/build.gradle @@ -2,4 +2,4 @@ dependencies { compile "org.scala-lang:scala-library:2.10.2" compile project(":common-backend") compile "net.chrisrichardson.eventstore.client:eventstore-client-event-handling:$eventStoreClientVersion" -} \ No newline at end of file +} diff --git a/scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransfer.scala b/scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransfer.scala similarity index 100% rename from scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransfer.scala rename to scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransfer.scala diff --git a/scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferCommands.scala b/scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferCommands.scala similarity index 100% rename from scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferCommands.scala rename to scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferCommands.scala diff --git a/scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferEventHandlers.scala b/scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferEventHandlers.scala similarity index 100% rename from scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferEventHandlers.scala rename to scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferEventHandlers.scala diff --git a/scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferService.scala b/scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferService.scala similarity index 100% rename from scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferService.scala rename to scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/MoneyTransferService.scala diff --git a/scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/TransactionConfiguration.scala b/scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/TransactionConfiguration.scala similarity index 100% rename from scala-spring/commandside-backend-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/TransactionConfiguration.scala rename to scala-spring/transactions-command-side-backend/src/main/scala/net/chrisrichardson/eventstore/examples/bank/transactions/TransactionConfiguration.scala diff --git a/scala-spring/transactions-command-side-service/build.gradle b/scala-spring/transactions-command-side-service/build.gradle new file mode 100644 index 0000000..6cf86c0 --- /dev/null +++ b/scala-spring/transactions-command-side-service/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'scala' +apply plugin: 'spring-boot' +apply plugin: VerifyEventStoreEnvironmentPlugin + +dependencies { + compile "org.scala-lang:scala-library:2.10.2" + compile project(":transactions-command-side-web") + + compile "org.springframework.boot:spring-boot-starter-web" + compile "org.springframework.boot:spring-boot-starter-actuator" + + compile "net.chrisrichardson.eventstore.client:eventstore-http-stomp-client:$eventStoreClientVersion" + + testCompile "org.springframework.boot:spring-boot-starter-test" + testCompile scalaTestDependency + +} + +test { + ignoreFailures true +} + diff --git a/scala-spring/transactions-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceConfiguration.scala b/scala-spring/transactions-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceConfiguration.scala new file mode 100644 index 0000000..d378f9d --- /dev/null +++ b/scala-spring/transactions-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceConfiguration.scala @@ -0,0 +1,14 @@ +package net.chrisrichardson.eventstore.examples.bank.web + +import net.chrisrichardson.eventstore.client.config.EventStoreHttpClientConfiguration +import net.chrisrichardson.eventstore.examples.bank.web.transactions.CommandSideWebTransactionsConfiguration +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation._ + +@Configuration +@EnableAutoConfiguration +@Import(Array(classOf[CommandSideWebTransactionsConfiguration], classOf[EventStoreHttpClientConfiguration])) +@ComponentScan +class TransactionsCommandSideServiceConfiguration { + +} diff --git a/scala-spring/transactions-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/TransactionsCommandSideServiceMain.scala b/scala-spring/transactions-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/TransactionsCommandSideServiceMain.scala new file mode 100644 index 0000000..f9a3728 --- /dev/null +++ b/scala-spring/transactions-command-side-service/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/main/TransactionsCommandSideServiceMain.scala @@ -0,0 +1,10 @@ +package net.chrisrichardson.eventstore.examples.bank.web.main + +import net.chrisrichardson.eventstore.examples.bank.web.TransactionsCommandSideServiceConfiguration +import org.springframework.boot.SpringApplication + +object TransactionsCommandSideServiceMain { + + def main(args: Array[String]) : Unit = SpringApplication.run(classOf[TransactionsCommandSideServiceConfiguration], args :_ *) + +} diff --git a/scala-spring/transactions-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceIntegrationTest.scala b/scala-spring/transactions-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceIntegrationTest.scala new file mode 100644 index 0000000..8465635 --- /dev/null +++ b/scala-spring/transactions-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceIntegrationTest.scala @@ -0,0 +1,30 @@ +package net.chrisrichardson.eventstore.examples.bank.web + +import org.junit.runner.RunWith +import org.scalatest.FlatSpec +import org.scalatest.concurrent.Eventually._ +import org.scalatest.junit.JUnitRunner +import org.scalatest.time.{Millis, Span} +import org.springframework.boot.SpringApplication +import org.springframework.web.client.RestTemplate + +@RunWith(classOf[JUnitRunner]) +class TransactionsCommandSideServiceIntegrationTest extends FlatSpec { + + val sa = new SpringApplication(classOf[TransactionsCommandSideServiceTestConfiguration]) + val ctx = sa.run() + + // var server = ctx.getBean(classOf[EmbeddedServletContainer]) + + val port = 8080 + + val baseUrl = s"http://localhost:$port/" + + val restTemplate = ctx.getBean(classOf[RestTemplate]) + + implicit val reallyLongPatienceConfig = PatienceConfig(timeout = Span(10 * 1000, Millis), interval = Span(1 * 1000, Millis)) + + it should "create accounts and transfer money" in { + // FIXME + } +} diff --git a/scala-spring/transactions-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceTestConfiguration.scala b/scala-spring/transactions-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceTestConfiguration.scala new file mode 100644 index 0000000..ab39741 --- /dev/null +++ b/scala-spring/transactions-command-side-service/src/test/scala/net/chrisrichardson/eventstore/examples/bank/web/TransactionsCommandSideServiceTestConfiguration.scala @@ -0,0 +1,26 @@ +package net.chrisrichardson.eventstore.examples.bank.web + + +import com.fasterxml.jackson.databind.ObjectMapper +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation.{Bean, Import, Configuration} +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter +import org.springframework.web.client.RestTemplate +import scala.collection.JavaConversions._ + +@Configuration +@Import(Array(classOf[TransactionsCommandSideServiceConfiguration])) +class TransactionsCommandSideServiceTestConfiguration { + + @Bean + def restTemplate(scalaObjectMapper: ObjectMapper) = { + val restTemplate = new RestTemplate() + restTemplate.getMessageConverters foreach { + case mc: MappingJackson2HttpMessageConverter => + mc.setObjectMapper(scalaObjectMapper) + case _ => + } + restTemplate + } + +} diff --git a/scala-spring/commandside-web-transactions/build.gradle b/scala-spring/transactions-command-side-web/build.gradle similarity index 69% rename from scala-spring/commandside-web-transactions/build.gradle rename to scala-spring/transactions-command-side-web/build.gradle index 75317fe..3f6f7fd 100644 --- a/scala-spring/commandside-web-transactions/build.gradle +++ b/scala-spring/transactions-command-side-web/build.gradle @@ -2,9 +2,9 @@ apply plugin: 'scala' dependencies { compile "org.scala-lang:scala-library:2.10.2" - compile project(":commandside-backend-transactions") - compile project(":web-common") + compile project(":transactions-command-side-backend") + compile project(":common-web") testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" testCompile scalaTestDependency -} \ No newline at end of file +} diff --git a/scala-spring/commandside-web-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/CommandSideWebTransactionsConfiguration.scala b/scala-spring/transactions-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/CommandSideWebTransactionsConfiguration.scala similarity index 100% rename from scala-spring/commandside-web-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/CommandSideWebTransactionsConfiguration.scala rename to scala-spring/transactions-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/CommandSideWebTransactionsConfiguration.scala diff --git a/scala-spring/commandside-web-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/CreateMoneyTransferResponse.scala b/scala-spring/transactions-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/CreateMoneyTransferResponse.scala similarity index 100% rename from scala-spring/commandside-web-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/CreateMoneyTransferResponse.scala rename to scala-spring/transactions-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/CreateMoneyTransferResponse.scala diff --git a/scala-spring/commandside-web-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/MoneyTransferController.scala b/scala-spring/transactions-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/MoneyTransferController.scala similarity index 100% rename from scala-spring/commandside-web-transactions/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/MoneyTransferController.scala rename to scala-spring/transactions-command-side-web/src/main/scala/net/chrisrichardson/eventstore/examples/bank/web/transactions/controllers/MoneyTransferController.scala