diff --git a/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/ApiGatewayServiceConfiguration.java b/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/ApiGatewayServiceConfiguration.java index b638db3..fdb6258 100755 --- a/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/ApiGatewayServiceConfiguration.java +++ b/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/ApiGatewayServiceConfiguration.java @@ -5,6 +5,7 @@ import net.chrisrichardson.eventstore.client.config.EventStoreHttpClientConfigur import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.AuthConfiguration; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClients; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -16,6 +17,7 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import java.util.Collections; @@ -24,9 +26,10 @@ import java.util.Collections; */ @Configuration @ComponentScan +@EnableAutoConfiguration @Import({EventStoreHttpClientConfiguration.class, AuthConfiguration.class}) @EnableConfigurationProperties({ApiGatewayProperties.class}) -public class ApiGatewayServiceConfiguration { +public class ApiGatewayServiceConfiguration extends WebMvcConfigurerAdapter { @Bean public RestTemplate restTemplate(HttpMessageConverters converters) { diff --git a/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/controller/GatewayController.java b/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/controller/GatewayController.java index c8f96e7..64cff3b 100755 --- a/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/controller/GatewayController.java +++ b/java-spring/api-gateway-service/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/apigateway/controller/GatewayController.java @@ -31,7 +31,6 @@ import static org.springframework.web.bind.annotation.RequestMethod.*; * Created by popikyardo on 15.01.16. */ @RestController -@RequestMapping("/api") public class GatewayController { Logger log = LoggerFactory.getLogger(this.getClass()); @@ -50,7 +49,7 @@ public class GatewayController { .build(); } - @RequestMapping(value = "/**", method = {GET, POST, PUT, DELETE}) + @RequestMapping(value = "/**", method = {GET, POST}) public String proxyRequest(HttpServletRequest request) throws NoSuchRequestHandlingMethodException, IOException, URISyntaxException { HttpUriRequest proxiedRequest = createHttpUriRequest(request); log.info("request: {}", proxiedRequest); diff --git a/java-spring/api-gateway-service/src/main/resources/logback.xml b/java-spring/api-gateway-service/src/main/resources/logback.xml new file mode 100755 index 0000000..5d568b7 --- /dev/null +++ b/java-spring/api-gateway-service/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + + + + %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/java-spring/docker-compose.yml b/java-spring/docker-compose.yml index 68f4813..c22a1e8 100644 --- a/java-spring/docker-compose.yml +++ b/java-spring/docker-compose.yml @@ -1,3 +1,21 @@ +apigateway: + image: java:8 + working_dir: /app + volumes: + - ./api-gateway-service/build/libs:/app + command: java -jar /app/api-gateway-service.jar --accounts.commandside.service.host=accountscommandside --transactions.commandside.service.host=transactionscommandside --accounts.queryside.service.host=accountsqueryside --customers.commandside.service.host=customerscommandside --customers.queryside.service.host=customersqueryside + ports: + - "8080:8080" + links: + - accountscommandside + - transactionscommandside + - accountsqueryside + - customerscommandside + - customersqueryside + environment: + EVENTUATE_API_KEY_ID: + EVENTUATE_API_KEY_SECRET: + accountscommandside: image: java:8 working_dir: /app @@ -5,7 +23,7 @@ accountscommandside: - ./accounts-command-side-service/build/libs:/app command: java -jar /app/accounts-command-side-service.jar ports: - - "8080:8080" + - "8085:8080" environment: EVENTUATE_API_KEY_ID: EVENTUATE_API_KEY_SECRET: diff --git a/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java b/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java index 2439b45..38c580d 100644 --- a/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java +++ b/java-spring/e2e-test/src/test/java/net/chrisrichardson/eventstore/examples/bank/web/EndToEndTest.java @@ -1,10 +1,7 @@ package net.chrisrichardson.eventstore.examples.bank.web; -import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Address; -import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerInfo; -import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerResponse; -import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Name; +import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.*; import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.utils.BasicAuthUtils; import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest; import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse; @@ -147,20 +144,20 @@ public class EndToEndTest { private void assertCustomerResponse(final String customerId, final CustomerInfo customerInfo) { eventually( - new Producer() { + new Producer() { @Override - public Observable produce() { - return Observable.just(BasicAuthUtils.doBasicAuthenticatedRequest(restTemplate, - customersQuerySideBaseUrl("/customers/" + customerId), - HttpMethod.GET, - CustomerResponse.class)); + public Observable produce() { + return Observable.just(BasicAuthUtils.doBasicAuthenticatedRequest(restTemplate, + customersQuerySideBaseUrl("/customers/" + customerId), + HttpMethod.GET, + QuerySideCustomer.class)); } }, - new Verifier() { + new Verifier() { @Override - public void verify(CustomerResponse customerResponse) { - Assert.assertEquals(customerId, customerResponse.getId()); - Assert.assertEquals(customerInfo, customerResponse.getCustomerInfo()); + public void verify(QuerySideCustomer querySideCustomer) { + Assert.assertEquals(customerId, querySideCustomer.getId()); + assertQuerySideCustomerEqualscCustomerInfo(querySideCustomer, customerInfo); } }); } @@ -179,4 +176,11 @@ public class EndToEndTest { ); } + private void assertQuerySideCustomerEqualscCustomerInfo(QuerySideCustomer querySideCustomer, CustomerInfo customerInfo) { + Assert.assertEquals(querySideCustomer.getName(), customerInfo.getName()); + Assert.assertEquals(querySideCustomer.getEmail(), customerInfo.getEmail()); + Assert.assertEquals(querySideCustomer.getPhoneNumber(), customerInfo.getPhoneNumber()); + Assert.assertEquals(querySideCustomer.getSsn(), customerInfo.getSsn()); + Assert.assertEquals(querySideCustomer.getAddress(), customerInfo.getAddress()); + } } diff --git a/java-spring/schemas/java-mt-demo-extended-api.json b/java-spring/schemas/java-mt-demo-extended-api.json index 28c4df8..84fd542 100644 --- a/java-spring/schemas/java-mt-demo-extended-api.json +++ b/java-spring/schemas/java-mt-demo-extended-api.json @@ -17,30 +17,38 @@ "basePath": "/", "tags": [ { - "name": "customer-service-command-side-controller", - "description": "Customer Service Commandside Controller" + "name": "account-query-controller", + "description": "Account Query Controller" }, { - "name": "customer-service-query-side-controller", - "description": "Customer Service Queryside Controller" - }, - { - "name": "account-query-side-controller", - "description": "Account Service Queryside Controller" + "name": "money-transfer-controller", + "description": "Money Transfer Controller" }, { "name": "auth-controller", - "description": "Authentication Controller" + "description": "Auth Controller" + }, + { + "name": "customer-controller", + "description": "Customer Controller" + }, + { + "name": "customer-query-controller", + "description": "Customer Query Controller" + }, + { + "name": "account-controller", + "description": "Account Controller" } ], "paths": { - "/login": { + "/accounts": { "post": { "tags": [ - "auth-controller" + "account-controller" ], - "summary": "doAuth", - "operationId": "doAuthUsingPOST", + "summary": "createAccount", + "operationId": "createAccountUsingPOST", "consumes": [ "application/json" ], @@ -54,7 +62,7 @@ "description": "request", "required": true, "schema": { - "$ref": "#/definitions/AuthRequest" + "$ref": "#/definitions/CreateAccountRequest" } } ], @@ -62,7 +70,39 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/CustomerResponse" + "$ref": "#/definitions/CreateAccountResponse" + } + } + } + } + }, + "/accounts/{accountId}": { + "get": { + "tags": [ + "account-query-controller" + ], + "summary": "get", + "operationId": "getUsingGET", + "consumes": [ + "application/json" + ], + "produces": [ + "*/*" + ], + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "accountId", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/GetAccountResponse" } } } @@ -71,21 +111,21 @@ "/customers": { "get": { "tags": [ - "customer-service-query-side-controller" + "customer-query-controller" ], - "summary": "getAllCustomersByEmail", - "operationId": "getAllCustomersByEmailUsingGET", + "summary": "getCustomersByEmail", + "operationId": "getCustomersByEmailUsingGET", "consumes": [ "application/json" ], "produces": [ "*/*" ], - "parameters": [ + "parameters": [ { "name": "email", "in": "query", - "description": "customer's email", + "description": "email", "required": true, "type": "string" } @@ -101,10 +141,10 @@ }, "post": { "tags": [ - "customer-service-command-side-controller" + "customer-controller" ], - "summary": "saveCustomer", - "operationId": "saveCustomerUsingPOST", + "summary": "createCustomer", + "operationId": "createCustomerUsingPOST", "consumes": [ "application/json" ], @@ -128,20 +168,17 @@ "schema": { "$ref": "#/definitions/CustomerResponse" } - }, - "400": { - "description": "Validation error" } } } }, - "/customers/{id}": { + "/customers/{customerId}": { "get": { "tags": [ - "customer-service-query-side-controller" + "customer-query-controller" ], - "summary": "getBoard", - "operationId": "getBoardUsingGET", + "summary": "getCustomer", + "operationId": "getCustomerUsingGET", "consumes": [ "application/json" ], @@ -150,9 +187,9 @@ ], "parameters": [ { - "name": "id", + "name": "customerId", "in": "path", - "description": "id", + "description": "customerId", "required": true, "type": "string" } @@ -161,7 +198,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/CustomerResponse" + "$ref": "#/definitions/QuerySideCustomer" } } } @@ -170,7 +207,7 @@ "/customers/{id}/toaccounts": { "post": { "tags": [ - "customer-service-command-side-controller" + "customer-controller" ], "summary": "addToAccount", "operationId": "addToAccountUsingPOST", @@ -200,94 +237,166 @@ ], "responses": { "200": { - "description": "OK" - }, - "400": { - "description": "Validation error" + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + }, + "/login": { + "post": { + "tags": [ + "auth-controller" + ], + "summary": "doAuth", + "operationId": "doAuthUsingPOST", + "consumes": [ + "application/json" + ], + "produces": [ + "*/*" + ], + "parameters": [ + { + "in": "body", + "name": "request", + "description": "request", + "required": true, + "schema": { + "$ref": "#/definitions/AuthRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/QuerySideCustomer" + } + } + } + } + }, + "/transfers": { + "post": { + "tags": [ + "money-transfer-controller" + ], + "summary": "createMoneyTransfer", + "operationId": "createMoneyTransferUsingPOST", + "consumes": [ + "application/json" + ], + "produces": [ + "*/*" + ], + "parameters": [ + { + "in": "body", + "name": "request", + "description": "request", + "required": true, + "schema": { + "$ref": "#/definitions/CreateMoneyTransferRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/CreateMoneyTransferResponse" + } } } } } }, "definitions": { + "CreateAccountResponse": { + "properties": { + "accountId": { + "type": "string" + } + } + }, "AuthRequest": { - "required": [ "email" ], "properties": { "email": { "type": "string" } } }, - "AuthResponse": { + "QuerySideCustomer": { "properties": { - "token": { + "address": { + "$ref": "#/definitions/Address" + }, + "email": { "type": "string" - } - } - }, - "CustomerInfo": { - "required": [ "email" ], - "properties": { + }, + "id": { + "type": "string" + }, "name": { "$ref": "#/definitions/Name" }, - "email": { + "phoneNumber": { "type": "string" }, "ssn": { "type": "string" }, - "phoneNumber": { - "type": "string" - }, - "address": { - "$ref": "#/definitions/Address" - } - } - }, - "CustomersQueryResponse": { - "properties": { - "customers": { - "type": "array", - "items": { - "$ref": "#/definitions/CustomerResponse" + "toAccounts": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ToAccountInfo" } } } }, - "CustomerResponse": { - "required": [ "id", "customerInfo" ], + "Address": { + "properties": { + "city": { + "type": "string" + }, + "state": { + "type": "string" + }, + "street1": { + "type": "string" + }, + "street2": { + "type": "string" + }, + "zipCode": { + "type": "string" + } + } + }, + "CreateMoneyTransferResponse": { + "properties": { + "moneyTransferId": { + "type": "string" + } + } + }, + "ToAccountInfo": { "properties": { "id": { "type": "string" }, - "customerInfo": { - "$ref": "#/definitions/CustomerInfo" - } - } - }, - "AccountsQueryResponse": { - "properties": { - "customers": { - "type": "array", - "items": { - "$ref": "#/definitions/GetAccountResponse" - } - } - } - }, - "GetAccountResponse": { - "properties": { - "accountId": { + "owner": { "type": "string" }, - "balance": { - "type": "number" + "title": { + "type": "string" } } }, "Name": { - "required": [ "firstName", "lastName" ], "properties": { "firstName": { "type": "string" @@ -297,40 +406,83 @@ } } }, - "ToAccountInfo":{ - "required": [ "id", "owner" ], + "GetAccountResponse": { "properties": { - "id": { + "accountId": { "type": "string" }, + "balance": { + "type": "number", + "format": "double" + } + } + }, + "CreateAccountRequest": { + "properties": { + "customerId": { + "type": "string" + }, + "initialBalance": { + "type": "number", + "format": "double" + }, "title": { "type": "string" - }, - "owner": { - "type": "string" } } }, - "Address": { - "required": [ "street1", "city", "state", "zipCode" ], + "CustomersQueryResponse": { "properties": { - "street1": { + "customers": { + "type": "array", + "items": { + "$ref": "#/definitions/QuerySideCustomer" + } + } + } + }, + "CreateMoneyTransferRequest": { + "properties": { + "amount": { + "type": "number", + "format": "double" + }, + "fromAccountId": { "type": "string" }, - "street2": { + "toAccountId": { + "type": "string" + } + } + }, + "CustomerInfo": { + "properties": { + "address": { + "$ref": "#/definitions/Address" + }, + "email": { "type": "string" }, - "city": { + "name": { + "$ref": "#/definitions/Name" + }, + "phoneNumber": { "type": "string" }, - "state": { + "ssn": { "type": "string" + } + } + }, + "CustomerResponse": { + "properties": { + "customerInfo": { + "$ref": "#/definitions/CustomerInfo" }, - "zipCode": { + "id": { "type": "string" } } } } -} - +} \ No newline at end of file