diff --git a/bank-services/account-service/src/main/resources/application.yml b/bank-services/account-service/src/main/resources/application.yml index 351dc67..e56606d 100644 --- a/bank-services/account-service/src/main/resources/application.yml +++ b/bank-services/account-service/src/main/resources/application.yml @@ -24,6 +24,7 @@ management: enabled: true endpoints.web.exposure.include: "*" endpoint: + shutdown.enabled: true health.show-details: always logging.level: diff --git a/bank-services/customer-service/src/main/java/org/siriusxi/blueharvest/bank/cs/api/CustomerController.java b/bank-services/customer-service/src/main/java/org/siriusxi/blueharvest/bank/cs/api/CustomerController.java index 450f12a..e4428c3 100644 --- a/bank-services/customer-service/src/main/java/org/siriusxi/blueharvest/bank/cs/api/CustomerController.java +++ b/bank-services/customer-service/src/main/java/org/siriusxi/blueharvest/bank/cs/api/CustomerController.java @@ -37,15 +37,15 @@ public List getCustomers() { value = "customers/{id}/accounts", consumes = APPLICATION_JSON_VALUE) public void createAccount(@PathVariable int id, @RequestBody AccountDTO account) { - - log.debug("createAccount: creates a new account {}", account); - requireNonNull(account, "Invalid account data."); if (id <= 0 || account.getInitialCredit().doubleValue() < 0.0) - throw new InvalidInputException(format("Invalid account data %s", account)); + throw new InvalidInputException(format("Invalid data (Customer Id= %d, " + + "initialCredit= %.2f)", id, account.getInitialCredit().doubleValue())); account.setCustomerId(id); customerService.createCustomerAccount(account); + + log.debug("createAccount: a new account {} is created.", account); } } diff --git a/bank-services/customer-service/src/main/resources/application.yml b/bank-services/customer-service/src/main/resources/application.yml index 6345e96..cc6f125 100644 --- a/bank-services/customer-service/src/main/resources/application.yml +++ b/bank-services/customer-service/src/main/resources/application.yml @@ -24,6 +24,7 @@ management: enabled: true endpoints.web.exposure.include: "*" endpoint: + shutdown.enabled: true health.show-details: always logging.level: diff --git a/bank-services/customer-service/src/test/java/org/siriusxi/blueharvest/bank/cs/CustomerServiceIntegrationTests.java b/bank-services/customer-service/src/test/java/org/siriusxi/blueharvest/bank/cs/CustomerServiceIntegrationTests.java index 5d96fb4..f6fc459 100644 --- a/bank-services/customer-service/src/test/java/org/siriusxi/blueharvest/bank/cs/CustomerServiceIntegrationTests.java +++ b/bank-services/customer-service/src/test/java/org/siriusxi/blueharvest/bank/cs/CustomerServiceIntegrationTests.java @@ -66,7 +66,7 @@ void createAccountForCustomerDoesNotExist() throws Exception { @Test @Order(2) - void createAccountInvalidIdLessThanZero() throws Exception { + void createAccountInvalidCustomerIdLessThanZero() throws Exception { // When mvc.perform( @@ -78,7 +78,7 @@ void createAccountInvalidIdLessThanZero() throws Exception { .andExpect( jsonPath( "$.message", - is("Invalid account data AccountDTO(customerId=0, initialCredit=100.00)"))); + is("Invalid data (Customer Id= -1, initialCredit= 100.00)"))); } @Test @@ -95,7 +95,7 @@ void createAccountInvalidCreditLessThanZero() throws Exception { .andExpect( jsonPath( "$.message", - is("Invalid account data AccountDTO(customerId=0, initialCredit=-100.00)"))); + is("Invalid data (Customer Id= 1, initialCredit= -100.00)"))); } @Test diff --git a/bank-services/transaction-service/src/main/resources/application.yml b/bank-services/transaction-service/src/main/resources/application.yml index cc6a035..9f9840f 100644 --- a/bank-services/transaction-service/src/main/resources/application.yml +++ b/bank-services/transaction-service/src/main/resources/application.yml @@ -24,6 +24,7 @@ management: enabled: true endpoints.web.exposure.include: "*" endpoint: + shutdown.enabled: true health.show-details: always logging.level: diff --git a/run-em-all.sh b/run-em-all.sh new file mode 100755 index 0000000..f3c1ce6 --- /dev/null +++ b/run-em-all.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +## Author: Mohamed Taman +## version: v0.7 + +echo -e "Starting [Harvest Bank] μServices ....\n\ +---------------------------------------\n" + +function runService(){ + java --enable-preview -jar $1/target/*.jar > /dev/null +} + +for dir in $(find bank-services/*-service -maxdepth 0 -type d) +do + echo -e "Starting [$dir] μService.... \n" && \ + runService "$dir" & +done diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..7130660 --- /dev/null +++ b/setup.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +## author: Mohamed Taman +## version: v0.7 + +echo -e "\nInstalling all Harvest Bank core shared modules & Parent POMs" +echo -e "...............................................................\n" +echo "1- Installing [Parent Build Chassis] module..." +./mvnw --quiet clean install -U -pl bank-base/bank-build-chassis || exit 126 +echo -e "Done successfully.\n" +echo "2- Installing shared [Services Utilities] module..." +./mvnw --quiet clean install -pl bank-common || exit 126 +echo -e "Done successfully.\n" +echo "3- Installing [Parent Services Chassis] module..." +./mvnw --quiet clean install -U -pl bank-base/bank-services-chassis || exit 126 +echo -e "Done successfully.\n" + +echo -e "Woohoo, building & installing all project modules are finished successfully.\n\ +The project is ready for the next step. :)" \ No newline at end of file diff --git a/stop-em-all.sh b/stop-em-all.sh new file mode 100755 index 0000000..b4a287f --- /dev/null +++ b/stop-em-all.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +## Author: Mohamed Taman +## version: v0.7 + +echo -e "Stopping [Harvest Bank] μServices ....\n\ +---------------------------------------\n" +for port in 8090 8091 8092 +do + echo "Stopping μService at port $port ...." + curl -X POST localhost:${port}/actuator/shutdown + echo -e "\nμService at port ${port} stopped successfully .... \n" +done diff --git a/test-em-all.sh b/test-em-all.sh new file mode 100755 index 0000000..2ed9b53 --- /dev/null +++ b/test-em-all.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash +## Author: Mohamed Taman +## version: v0.7 +### Sample usage: +# +# for local run +# HOST=localhost PORT=8090 ./test-em-all.bash start stop +# +echo -e "\nStarting 'Harvest Bank μServices' for [end-2-end] testing....\n" + +: "${HOST=localhost}" +: "${PORT=8090}" +: "${CUST_ID_OK=1}" +: "${CUST_ID_NOT_FOUND=14}" +: "${CONTENT_TYPE=\"Content-Type: application/json\"}" + +BASE_URL="/bank/api/v1/customers" + +function assertCurl() { + + local expectedHttpCode=$1 + local curlCmd="$2 -w \"%{http_code}\"" + local result=$(eval "${curlCmd}") + local httpCode="${result:(-3)}" + RESPONSE='' && (( ${#result} > 3 )) && RESPONSE="${result%???}" + + if [[ "$httpCode" = "$expectedHttpCode" ]] + then + if [[ "$httpCode" = "200" ]] + then + echo "Test OK (HTTP Code: $httpCode)" + else + echo "Test OK (HTTP Code: $httpCode, $RESPONSE)" + fi + return 0 + else + echo "Test FAILED, EXPECTED HTTP Code: $expectedHttpCode, GOT: $httpCode, WILL ABORT!" + echo "- Failing command: $curlCmd" + echo "- Response Body: $RESPONSE" + return 1 + fi +} + +function assertEqual() { + + local expected=$1 + local actual=$2 + + if [[ "$actual" = "$expected" ]] + then + echo "Test OK (actual value: $actual)" + return 0 + else + echo "Test FAILED, EXPECTED VALUE: $expected, ACTUAL VALUE: $actual, WILL ABORT" + return 1 + fi +} + +function testUrl() { + url=$@ + if curl ${url} -ks -f -o /dev/null + then + return 0 + else + return 1 + fi; +} + +function waitForService() { + url=$@ + echo -n "Wait for: $url ... " + n=0 + until testUrl ${url} + do + n=$((n + 1)) + if [[ ${n} == 100 ]] + then + echo " Give up" + exit 1 + else + sleep 3 + echo -n ", retry #$n " + fi + done + echo -e "\n DONE, continues...\n" +} + +set -e + +echo "Start Tests:" "$(date)" + +echo "HOST=${HOST}" +echo "PORT=${PORT}" + +if [[ $@ == *"start"* ]] +then + echo "Firing up the test environment..." + bash run-em-all.sh +fi + +waitForService curl http://${HOST}:${PORT}/actuator/health + +# Verify that a normal request works, expect seven customers +assertCurl 200 "curl http://$HOST:$PORT${BASE_URL} -s" +assertEqual 7 "$(echo "${RESPONSE}" | jq ". | length")" +assertEqual 0 "$(echo "${RESPONSE}" | jq ".[0].accounts | length")" +assertEqual 0 "$(echo "${RESPONSE}" | jq ".[0].accounts[0].transactions | length")" + +# Verify that a 404 (Not Found) error is returned for a non existing customer (14) +assertCurl 404 "curl -H ${CONTENT_TYPE} -d '{\"initialCredit\": 10.0}' \ +http://$HOST:$PORT${BASE_URL}/$CUST_ID_NOT_FOUND/accounts -s" + +# Verify that a 422 (Unprocessable Entity) error is returned for minus Initial Credit +assertCurl 422 "curl -H ${CONTENT_TYPE} -d '{\"initialCredit\": -10.0}' \ +http://$HOST:$PORT${BASE_URL}/$CUST_ID_NOT_FOUND/accounts -s" + +# Verify that a 400 (Bad Request) error error is returned for a customerId that is not a number, i +# .e. invalid format +assertCurl 400 "curl -H ${CONTENT_TYPE} -d '{\"initialCredit\": -10.0}' \ +http://$HOST:$PORT${BASE_URL}/invalidCustomerId/accounts -s" +assertEqual "\"Bad Request\"" "$(echo "${RESPONSE}" | jq .error)" + +# Verify that no transactions only created customer Account for initial credit 0.0 +assertCurl 200 "curl -H ${CONTENT_TYPE} -d '{\"initialCredit\": 0.0}' \ +http://$HOST:$PORT${BASE_URL}/$CUST_ID_OK/accounts -s" +assertCurl 200 "curl http://$HOST:$PORT${BASE_URL} -s" +assertEqual 1 "$(echo "${RESPONSE}" | jq ".[0].accounts | length")" +assertEqual 0 "$(echo "${RESPONSE}" | jq ".[0].accounts[0].balance")" +assertEqual 0 "$(echo "${RESPONSE}" | jq ".[0].accounts[0].transactions | length")" + +# Verify that transaction is created for customer account for initial credit 100.20 +assertCurl 200 "curl -H ${CONTENT_TYPE} -d '{\"initialCredit\": 100.20}' \ +http://$HOST:$PORT${BASE_URL}/$CUST_ID_OK/accounts -s" +assertCurl 200 "curl http://$HOST:$PORT${BASE_URL} -s" +assertEqual 100.2 "$(echo "${RESPONSE}" | jq ".[0].balance")" +assertEqual 2 "$(echo "${RESPONSE}" | jq ".[0].accounts | length")" +assertEqual 100.2 "$(echo "${RESPONSE}" | jq ".[0].accounts[1].balance")" +assertEqual 1 "$(echo "${RESPONSE}" | jq ".[0].accounts[1].transactions | length")" +assertEqual 100.2 "$(echo "${RESPONSE}" | jq ".[0].accounts[1].transactions[0].amount")" + +# Verify customer balance is updated to 200.0 +assertCurl 200 "curl -H ${CONTENT_TYPE} -d '{\"initialCredit\": 99.80}' \ +http://$HOST:$PORT${BASE_URL}/$CUST_ID_OK/accounts -s" +assertCurl 200 "curl http://$HOST:$PORT${BASE_URL} -s" +assertEqual 200 "$(echo "${RESPONSE}" | jq ".[0].balance")" +assertEqual 3 "$(echo "${RESPONSE}" | jq ".[0].accounts | length")" +assertEqual 99.8 "$(echo "${RESPONSE}" | jq ".[0].accounts[2].balance")" +assertEqual 1 "$(echo "${RESPONSE}" | jq ".[0].accounts[2].transactions | length")" +assertEqual 99.8 "$(echo "${RESPONSE}" | jq ".[0].accounts[2].transactions[0].amount")" + +echo -e "\nEnd, all tests OK: $(date) \n" + +if [[ $@ == *"stop"* ]] +then + echo "We are done, stopping the test environment..." + bash stop-em-all.sh +fi \ No newline at end of file