Compare commits

...

100 Commits

Author SHA1 Message Date
allcontributors[bot]
7f09cd5b2d docs: update .all-contributorsrc [skip ci] 2020-08-21 14:34:24 +00:00
allcontributors[bot]
b388020fc0 docs: update README.md [skip ci] 2020-08-21 14:34:23 +00:00
Ilkka Seppälä
0c552effc3 Merge pull request #1492 from ToxicDreamz/SonarCloud-Reports-Issue#1012
Fixed most reported issues by SonarCloud.
2020-08-21 17:25:16 +03:00
Toxic Dreamz
885c8a6765 Fixed a test-case issue within the dirty-flag module. 2020-08-20 01:21:03 +04:00
Toxic Dreamz
6b5b2ac1e8 Merge remote-tracking branch 'origin/SonarCloud-Reports-Issue#1012' into SonarCloud-Reports-Issue#1012 2020-08-20 01:03:50 +04:00
Toxic Dreamz
c35b98b4d7 Fixed pom.xml issues within the dirty-flag and partial-response modules that were causing build failures. 2020-08-20 01:01:03 +04:00
Toxic Dreamz
f5fddeb7f0 Merge branch 'master' into SonarCloud-Reports-Issue#1012 2020-08-19 23:29:36 +04:00
Toxic Dreamz
292ec5b8e5 Merge branch 'SonarCloud-Reports-Issue#1012'
# Conflicts:
#	pom.xml
2020-08-19 23:27:43 +04:00
Toxic Dreamz
60d87789a6 Merge pull request #1 from iluwatar/master
Fork Update
2020-08-19 23:26:19 +04:00
Toxic Dreamz
860453b46b Fixed JUnit tests causing build issues due to mixing JUnit 4 & JUnit 5 2020-08-19 23:14:37 +04:00
Toxic Dreamz
6921b0dce0 Fixed checkstyle errors causing build failures. 2020-08-19 13:27:08 +04:00
Ilkka Seppälä
847585334c Update README.md 2020-08-18 20:09:04 +03:00
Ilkka Seppälä
9bb0b6fe6f Merge pull request #1498 from iluwatar/all-contributors/add-ohbus
docs: add ohbus as a contributor
2020-08-18 19:46:13 +03:00
allcontributors[bot]
31881f500d docs: update .all-contributorsrc [skip ci] 2020-08-18 16:45:38 +00:00
allcontributors[bot]
06f20570b6 docs: update README.md [skip ci] 2020-08-18 16:45:37 +00:00
Ilkka Seppälä
017ee23793 Merge pull request #1497 from iluwatar/all-contributors/add-nahteb
docs: add nahteb as a contributor
2020-08-18 19:42:38 +03:00
allcontributors[bot]
6c7715ace6 docs: update .all-contributorsrc [skip ci] 2020-08-18 16:42:03 +00:00
allcontributors[bot]
ef43af3b23 docs: update README.md [skip ci] 2020-08-18 16:42:02 +00:00
Ilkka Seppälä
95e513b6ec Edit readme 2020-08-17 19:49:00 +03:00
Ilkka Seppälä
194040543e Merge pull request #1493 from ohbus/master
updated workflows
2020-08-17 19:18:39 +03:00
Ilkka Seppälä
846a174ade Merge pull request #1496 from iluwatar/all-contributors/add-ohbus
docs: add ohbus as a contributor
2020-08-17 19:14:47 +03:00
allcontributors[bot]
7f60f7be25 docs: update .all-contributorsrc [skip ci] 2020-08-17 16:14:04 +00:00
allcontributors[bot]
cfb58191ea docs: update README.md [skip ci] 2020-08-17 16:14:03 +00:00
Ilkka Seppälä
82bf9fdd61 Merge pull request #1494 from nahteb/fix-typo
Fix typo in README for Observer pattern
2020-08-17 19:13:25 +03:00
Ilkka Seppälä
be552d0ece Merge pull request #1495 from iluwatar/all-contributors/add-xdvrx1
docs: add xdvrx1 as a contributor
2020-08-17 19:11:05 +03:00
allcontributors[bot]
d584404df6 docs: update .all-contributorsrc [skip ci] 2020-08-17 16:10:21 +00:00
allcontributors[bot]
353a2d9fcf docs: update README.md [skip ci] 2020-08-17 16:10:20 +00:00
Subhrodip Mohanta
8c5740563d reverted the copyright year back to 2019 2020-08-17 19:12:54 +05:30
Bethan Palmer
89bda692f8 Fix typo in README
The log message in the Orcs class should say orcs instead of hobbits.

This is correct in the code example but wrong in the README.
2020-08-17 07:47:30 +01:00
Subhrodip Mohanta
241f93f3cc updated cache to v2 and removed SQ analysis 2020-08-17 11:28:33 +05:30
Toxic Dreamz
57e45a329f Fixed a whitespace and spelling issue that was causing the test case to fail. 2020-08-16 22:35:15 +04:00
Subhrodip Mohanta
79a6af703e updated copyright year to 2020 2020-08-16 12:49:21 +05:30
Subhrodip Mohanta
00d06871f4 updated workflows 2020-08-16 12:42:08 +05:30
Toxic Dreamz
133ef52898 Fixed an issue with the order of imports that was causing build failures. 2020-08-15 22:19:27 +04:00
Ilkka Seppälä
7afb065a10 Upgrade urm plugin to latest version 2020-08-15 20:59:11 +03:00
Ilkka Seppälä
af9f8fe4e1 Merge pull request #1491 from iluwatar/all-contributors/add-xdvrx1
docs: add xdvrx1 as a contributor
2020-08-15 20:54:25 +03:00
allcontributors[bot]
a1c96ede13 docs: update .all-contributorsrc [skip ci] 2020-08-15 17:53:38 +00:00
allcontributors[bot]
0d2c4abe5a docs: update README.md [skip ci] 2020-08-15 17:53:37 +00:00
Toxic Dreamz
31471acb69 Fixed most reported issues by SonarCloud. 2020-08-15 21:47:39 +04:00
Ilkka Seppälä
e7e3ace01f Merge pull request #1489 from iluwatar/all-contributors/add-RayYH
docs: add RayYH as a contributor
2020-08-11 17:30:33 +03:00
allcontributors[bot]
41dacc2e2e docs: update .all-contributorsrc [skip ci] 2020-08-11 14:29:45 +00:00
allcontributors[bot]
dc7bf6190d docs: update README.md [skip ci] 2020-08-11 14:29:44 +00:00
Ilkka Seppälä
98d2dc0104 Merge pull request #1487 from RayYH/master
fix word typo
2020-08-11 17:29:06 +03:00
Ilkka Seppälä
870d44b127 Fix layout 2020-08-11 17:26:05 +03:00
Ilkka Seppälä
834f20911b Merge pull request #1488 from iluwatar/all-contributors/add-ashishtrivedi16
docs: add ashishtrivedi16 as a contributor
2020-08-11 17:23:22 +03:00
allcontributors[bot]
2b7949ce6a docs: update .all-contributorsrc [skip ci] 2020-08-11 14:21:59 +00:00
allcontributors[bot]
4ffab7da85 docs: update README.md [skip ci] 2020-08-11 14:21:58 +00:00
Ilkka Seppälä
1683fbdf9c Clean up Transaction Script 2020-08-11 17:17:25 +03:00
Ilkka Seppälä
d091e369ec Merge pull request #1480 from ashishtrivedi16/master
#1321 Transaction script model implementation
2020-08-11 16:59:48 +03:00
rayyh
b91bbc773d fix word typo 2020-08-11 14:19:39 +08:00
Ashish Trivedi
3c07a42e9d #1321 Updated UML diagram 2020-08-11 00:23:00 +05:30
Ashish Trivedi
e99bcf772b #1321 Added comments about TS 2020-08-11 00:21:46 +05:30
Ilkka Seppälä
2d16e5afbf Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2020-08-10 16:27:28 +03:00
Ilkka Seppälä
2c6f1832b0 Merge pull request #1485 from amit1307/logging-api-gateway-1338
Add logging in API Gateway
2020-08-10 16:26:18 +03:00
Ilkka Seppälä
04a2be0c99 Update readme 2020-08-10 16:25:06 +03:00
Ilkka Seppälä
10815b6469 Fix tags 2020-08-10 16:05:52 +03:00
Ashish Trivedi
75b10ed657 #1321 2020-08-10 13:21:24 +05:30
Ashish Trivedi
108532d8dd #1321 2020-08-10 13:12:12 +05:30
Ashish Trivedi
5527cf4234 #1321 Renamed main class 2020-08-10 13:06:46 +05:30
Ashish Trivedi
4008ae41b5 #1321 2020-08-10 13:02:35 +05:30
Ashish Trivedi
8166a1835d Merge remote-tracking branch 'origin/master' 2020-08-10 13:01:30 +05:30
Ashish Trivedi
4c9cad5475 #1321 Updated README 2020-08-10 13:01:12 +05:30
Ashish Trivedi
24126edd86 Update Hotel.java 2020-08-10 12:54:46 +05:30
Ashish Trivedi
c0edac0046 Rename TransactionScriptApp.java to App.java 2020-08-10 12:53:13 +05:30
Ashish Trivedi
f5c337981b Rename Readme.md to README.md 2020-08-10 12:52:37 +05:30
Ashish Trivedi
5441db6582 Update pom.xml 2020-08-10 12:52:15 +05:30
Ashish Trivedi
87f3a4d956 Delete module-info.java 2020-08-10 12:48:55 +05:30
Ashish Trivedi
31d753e59d Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-10 00:25:43 +05:30
Ashish Trivedi
6cef98d41e Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-10 00:25:01 +05:30
Ilkka Seppälä
7450456dae Add syntax highlighting 2020-08-09 21:54:54 +03:00
Ashish Trivedi
45e416928d Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-10 00:24:44 +05:30
Ashish Trivedi
94c131f7e9 Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-10 00:24:33 +05:30
Ashish Trivedi
5eb9b98e78 Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-10 00:24:20 +05:30
Ilkka Seppälä
8305e9365d Fix typos 2020-08-09 21:49:00 +03:00
Ilkka Seppälä
04e3368a81 Merge pull request #1482 from vINCENT8888801/private-class-data-explanation
Private class data explanation
2020-08-09 21:27:34 +03:00
Amit Garg
d219a104c7 Add logging in API Gateway 2020-08-09 18:13:24 +01:00
Wei Seng
700f5c6d27 corrected some typo 2020-08-09 18:22:40 +08:00
Wei Seng
f4fa73cd48 Update README.md
Increase clarity
2020-08-09 16:28:40 +08:00
Ashish_Trivedi
e09de2fb36 #1321 2020-08-09 01:58:19 +05:30
Ashish_Trivedi
a59c9bba97 #1321 2020-08-09 01:39:51 +05:30
Ashish_Trivedi
7acc5fbf95 #1321
Resolved conflicts and used var wherever possible
2020-08-09 01:33:19 +05:30
Ashish Trivedi
bdf2145b3f Merge branch 'master' into master 2020-08-09 01:17:07 +05:30
Ilkka Seppälä
1e90d0d645 Merge pull request #1484 from iluwatar/all-contributors/add-vINCENT8888801
docs: add vINCENT8888801 as a contributor
2020-08-08 22:44:51 +03:00
Ashish Trivedi
5bfaeffecf Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-09 00:51:44 +05:30
Ashish Trivedi
c0acaf073b Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-09 00:51:36 +05:30
Ashish Trivedi
9f190c59c4 Update transaction-script/Readme.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-08-09 00:51:28 +05:30
Wei Seng
08cec0e254 Update README.md 2020-08-09 03:10:43 +08:00
Wei Seng
1f6e6f34ea Update README.md 2020-08-09 03:09:53 +08:00
Ashish Trivedi
fa68789cd5 #1321 Updated readme and add UML diagram 2020-08-08 15:49:14 +05:30
Ashish Trivedi
12d392931e #1321 Added UML diagram 2020-07-27 00:39:53 +05:30
Ashish Trivedi
4017c37b6f #1321 Fixed a test 2020-07-26 18:34:42 +05:30
Ashish Trivedi
9d191324ff #1321 2020-07-26 18:17:00 +05:30
Ashish Trivedi
75ab3b5245 #1321 Added Tests 2020-07-26 17:38:33 +05:30
Ashish Trivedi
e0fb2d014a #1321 Added comments and refactored code 2020-07-26 15:56:55 +05:30
Ashish Trivedi
c4b1b89f1f #1321 2020-07-19 22:20:15 +05:30
Ashish Trivedi
52e6ea2b68 #1321
Implemented DAO
2020-07-19 20:33:52 +05:30
Ashish Trivedi
112973482d #1321
Added basic structure and planned out the roadmap
2020-07-19 16:51:16 +05:30
Ashish Trivedi
58e3fbfc6a #1321
Added gitignore
2020-07-19 16:19:01 +05:30
Ashish Trivedi
bf01f3e68b #1321
Added Readme file
2020-07-19 15:35:53 +05:30
Ashish Trivedi
58b98c54e5 #1321
Initial folder setup
2020-07-19 15:30:30 +05:30
225 changed files with 3297 additions and 749 deletions

View File

@@ -1093,6 +1093,62 @@
"contributions": [
"code"
]
},
{
"login": "ashishtrivedi16",
"name": "Ashish Trivedi",
"avatar_url": "https://avatars3.githubusercontent.com/u/23194128?v=4",
"profile": "https://www.linkedin.com/in/ashish-trivedi-218379135/",
"contributions": [
"code"
]
},
{
"login": "RayYH",
"name": "洪月阳",
"avatar_url": "https://avatars1.githubusercontent.com/u/41055099?v=4",
"profile": "https://rayyounghong.com",
"contributions": [
"code"
]
},
{
"login": "xdvrx1",
"name": "xdvrx1",
"avatar_url": "https://avatars0.githubusercontent.com/u/47092464?v=4",
"profile": "https://xdvrx1.github.io/",
"contributions": [
"review",
"ideas"
]
},
{
"login": "ohbus",
"name": "Subhrodip Mohanta",
"avatar_url": "https://avatars0.githubusercontent.com/u/13291222?v=4",
"profile": "http://subho.xyz",
"contributions": [
"code",
"review"
]
},
{
"login": "nahteb",
"name": "Bethan Palmer",
"avatar_url": "https://avatars3.githubusercontent.com/u/13121570?v=4",
"profile": "https://github.com/nahteb",
"contributions": [
"code"
]
},
{
"login": "ToxicDreamz",
"name": "Toxic Dreamz",
"avatar_url": "https://avatars0.githubusercontent.com/u/45225562?v=4",
"profile": "https://github.com/ToxicDreamz",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 4,

View File

@@ -24,13 +24,11 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
name: Java CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
@@ -43,6 +41,12 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
# Some tests need screen access
- name: Install xvfb
run: sudo apt-get install xvfb

57
.github/workflows/maven-pr-builder.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
#
# The MIT License
# Copyright © 2014-2019 Ilkka Seppälä
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java PR Builder
on:
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
# Some tests need screen access
- name: Install xvfb
run: sudo apt-get install xvfb
# SonarQube scan does not work for forked repositories
# See https://jira.sonarsource.com/browse/MMF-1371
- name: Build with Maven
if: github.ref != 'refs/heads/master'
run: xvfb-run mvn clean verify

View File

@@ -9,7 +9,7 @@
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-120-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-126-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
# Introduction
@@ -248,6 +248,16 @@ This project is licensed under the terms of the MIT license.
<td align="center"><a href="https://github.com/ravening"><img src="https://avatars1.githubusercontent.com/u/10645273?v=4" width="100px;" alt=""/><br /><sub><b>Rakesh</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ravening" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/vINCENT8888801"><img src="https://avatars0.githubusercontent.com/u/8037883?v=4" width="100px;" alt=""/><br /><sub><b>Wei Seng</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=vINCENT8888801" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://www.linkedin.com/in/ashish-trivedi-218379135/"><img src="https://avatars3.githubusercontent.com/u/23194128?v=4" width="100px;" alt=""/><br /><sub><b>Ashish Trivedi</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ashishtrivedi16" title="Code">💻</a></td>
<td align="center"><a href="https://rayyounghong.com"><img src="https://avatars1.githubusercontent.com/u/41055099?v=4" width="100px;" alt=""/><br /><sub><b>洪月阳</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=RayYH" title="Code">💻</a></td>
<td align="center"><a href="https://xdvrx1.github.io/"><img src="https://avatars0.githubusercontent.com/u/47092464?v=4" width="100px;" alt=""/><br /><sub><b>xdvrx1</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3Axdvrx1" title="Reviewed Pull Requests">👀</a> <a href="#ideas-xdvrx1" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="http://subho.xyz"><img src="https://avatars0.githubusercontent.com/u/13291222?v=4" width="100px;" alt=""/><br /><sub><b>Subhrodip Mohanta</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ohbus" title="Code">💻</a> <a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3Aohbus" title="Reviewed Pull Requests">👀</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/nahteb"><img src="https://avatars3.githubusercontent.com/u/13121570?v=4" width="100px;" alt=""/><br /><sub><b>Bethan Palmer</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=nahteb" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/ToxicDreamz"><img src="https://avatars0.githubusercontent.com/u/45225562?v=4" width="100px;" alt=""/><br /><sub><b>Toxic Dreamz</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ToxicDreamz" title="Code">💻</a></td>
</tr>
</table>
<!-- markdownlint-enable -->

View File

@@ -25,14 +25,23 @@ package com.iluwatar.abstractdocument;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Simple App test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void shouldExecuteAppWithoutException() {
App.main(null);
void shouldExecuteAppWithoutException() {
assertDoesNotThrow(() -> App.main(null));
}
}

View File

@@ -25,12 +25,23 @@ package com.iluwatar.abstractfactory;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Abstract Factory example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,23 @@ package com.iluwatar.acyclicvisitor;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that the Acyclic Visitor example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,12 +25,23 @@ package com.iluwatar.adapter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Adapter example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -6,6 +6,8 @@ permalink: /patterns/aggregator-microservices/
categories: Architectural
tags:
- Cloud distributed
- Decoupling
- Microservices
---
## Intent

View File

@@ -62,7 +62,7 @@ public class RemoteService implements RemoteServiceInterface {
*
* @param value integer value to be multiplied.
* @return if waitTime is less than {@link RemoteService#THRESHOLD}, it returns value * 10,
* otherwise {@link RemoteServiceInterface#FAILURE}.
* otherwise {@link RemoteServiceStatus#FAILURE}.
*/
@Override
public long doRemoteFunction(int value) {
@@ -74,6 +74,7 @@ public class RemoteService implements RemoteServiceInterface {
} catch (InterruptedException e) {
LOGGER.error("Thread sleep state interrupted", e);
}
return waitTime <= THRESHOLD ? value * 10 : FAILURE;
return waitTime <= THRESHOLD ? value * 10
: RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue();
}
}

View File

@@ -27,7 +27,6 @@ package com.iluwatar.ambassador;
* Interface shared by ({@link RemoteService}) and ({@link ServiceAmbassador}).
*/
interface RemoteServiceInterface {
int FAILURE = -1;
long doRemoteFunction(int value);
}

View File

@@ -0,0 +1,48 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.ambassador;
/**
* Holds information regarding the status of the Remote Service.
*
* <p> This Enum replaces the integer value previously
* stored in {@link RemoteServiceInterface} as SonarCloud was identifying
* it as an issue. All test cases have been checked after changes,
* without failures. </p>
*/
public enum RemoteServiceStatus {
FAILURE(-1)
;
private final long remoteServiceStatusValue;
RemoteServiceStatus(long remoteServiceStatusValue) {
this.remoteServiceStatusValue = remoteServiceStatusValue;
}
public long getRemoteServiceStatusValue() {
return remoteServiceStatusValue;
}
}

View File

@@ -23,6 +23,7 @@
package com.iluwatar.ambassador;
import static com.iluwatar.ambassador.RemoteServiceStatus.FAILURE;
import static java.lang.Thread.sleep;
import org.slf4j.Logger;
@@ -58,14 +59,14 @@ public class ServiceAmbassador implements RemoteServiceInterface {
private long safeCall(int value) {
var retries = 0;
var result = (long) FAILURE;
var result = FAILURE.getRemoteServiceStatusValue();
for (int i = 0; i < RETRIES; i++) {
if (retries >= RETRIES) {
return FAILURE;
return FAILURE.getRemoteServiceStatusValue();
}
if ((result = checkLatency(value)) == FAILURE) {
if ((result = checkLatency(value)) == FAILURE.getRemoteServiceStatusValue()) {
LOGGER.info("Failed to reach remote: (" + (i + 1) + ")");
retries++;
try {

View File

@@ -25,13 +25,23 @@ package com.iluwatar.ambassador;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -37,6 +37,6 @@ class ClientTest {
Client client = new Client();
var result = client.useService(10);
assertTrue(result == 100 || result == RemoteService.FAILURE);
assertTrue(result == 100 || result == RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue());
}
}

View File

@@ -37,7 +37,7 @@ class RemoteServiceTest {
void testFailedCall() {
var remoteService = new RemoteService(new StaticRandomProvider(0.21));
var result = remoteService.doRemoteFunction(10);
assertEquals(RemoteServiceInterface.FAILURE, result);
assertEquals(RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue(), result);
}
@Test

View File

@@ -35,6 +35,6 @@ class ServiceAmbassadorTest {
@Test
void test() {
long result = new ServiceAmbassador().doRemoteFunction(10);
assertTrue(result == 100 || result == RemoteServiceInterface.FAILURE);
assertTrue(result == 100 || result == RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue());
}
}

View File

@@ -12,49 +12,53 @@ tags:
## Intent
Aggregate calls to microservices in a single location: the API Gateway. The user makes a single call to the API Gateway,
and the API Gateway then calls each relevant microservice.
Aggregate calls to microservices in a single location, the API Gateway. The user makes a single call
to the API Gateway, and the API Gateway then calls each relevant microservice.
## Explanation
With the Microservices pattern, a client may need data from multiple different microservices. If the client called each
microservice directly, that could contribute to longer load times, since the client would have to make a network request
for each microservice called. Moreover, having the client call each microservice directly ties the client to that
microservice - if the internal implementations of the microservices change (for example, if two microservices are
combined sometime in the future) or if the location (host and port) of a microservice changes, then every client that
With the Microservices pattern, a client may need data from multiple different microservices. If the
client called each microservice directly, that could contribute to longer load times, since the
client would have to make a network request for each microservice called. Moreover, having the
client call each microservice directly ties the client to that microservice - if the internal
implementations of the microservices change (for example, if two microservices are combined sometime
in the future) or if the location (host and port) of a microservice changes, then every client that
makes use of those microservices must be updated.
The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway pattern, an additional
entity (the API Gateway) is placed between the client and the microservices. The job of the API Gateway is to aggregate
the calls to the microservices. Rather than the client calling each microservice individually, the client calls the
API Gateway a single time. The API Gateway then calls each of the microservices that the client needs.
The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway
pattern, an additional entity (the API Gateway) is placed between the client and the microservices.
The job of the API Gateway is to aggregate the calls to the microservices. Rather than the client
calling each microservice individually, the client calls the API Gateway a single time. The API
Gateway then calls each of the microservices that the client needs.
Real world example
> We are implementing microservices and API Gateway pattern for an e-commerce site. In this system the API Gateway makes
calls to the Image and Price microservices.
> We are implementing microservices and API Gateway pattern for an e-commerce site. In this system
> the API Gateway makes calls to the Image and Price microservices.
In plain words
> For a system implemented using microservices architecture, API Gateway is the single entry point that aggregates the
calls to the individual microservices.
> For a system implemented using microservices architecture, API Gateway is the single entry point
> that aggregates the calls to the individual microservices.
Wikipedia says
> API Gateway is a server that acts as an API front-end, receives API requests, enforces throttling and security
policies, passes requests to the back-end service and then passes the response back to the requester. A gateway often
includes a transformation engine to orchestrate and modify the requests and responses on the fly. A gateway can also
provide functionality such as collecting analytics data and providing caching. The gateway can provide functionality to
support authentication, authorization, security, audit and regulatory compliance.
> API Gateway is a server that acts as an API front-end, receives API requests, enforces throttling
> and security policies, passes requests to the back-end service and then passes the response back
> to the requester. A gateway often includes a transformation engine to orchestrate and modify the
> requests and responses on the fly. A gateway can also provide functionality such as collecting
> analytics data and providing caching. The gateway can provide functionality to support
> authentication, authorization, security, audit and regulatory compliance.
**Programmatic Example**
This implementation shows what the API Gateway pattern could look like for an e-commerce site. The `ApiGateway` makes
calls to the Image and Price microservices using the `ImageClientImpl` and `PriceClientImpl` respectively. Customers
viewing the site on a desktop device can see both price information and an image of a product, so the `ApiGateway` calls
both of the microservices and aggregates the data in the `DesktopProduct` model. However, mobile users only see price
information; they do not see a product image. For mobile users, the `ApiGateway` only retrieves price information, which
it uses to populate the `MobileProduct`.
This implementation shows what the API Gateway pattern could look like for an e-commerce site. The
`ApiGateway` makes calls to the Image and Price microservices using the `ImageClientImpl` and
`PriceClientImpl` respectively. Customers viewing the site on a desktop device can see both price
information and an image of a product, so the `ApiGateway` calls both of the microservices and
aggregates the data in the `DesktopProduct` model. However, mobile users only see price information;
they do not see a product image. For mobile users, the `ApiGateway` only retrieves price
information, which it uses to populate the `MobileProduct`.
Here's the Image microservice implementation.
@@ -64,7 +68,6 @@ public interface ImageClient {
}
public class ImageClientImpl implements ImageClient {
@Override
public String getImagePath() {
var httpClient = HttpClient.newHttpClient();
@@ -114,7 +117,7 @@ public class PriceClientImpl implements PriceClient {
}
```
And here we can see how API Gateway maps the requests to the microservices.
Here we can see how API Gateway maps the requests to the microservices.
```java
public class ApiGateway {

View File

@@ -23,11 +23,16 @@
package com.iluwatar.api.gateway;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
/**
@@ -35,6 +40,8 @@ import org.springframework.stereotype.Component;
*/
@Component
public class ImageClientImpl implements ImageClient {
private static final Logger LOGGER = getLogger(ImageClientImpl.class);
/**
* Makes a simple HTTP Get request to the Image microservice.
*
@@ -49,12 +56,26 @@ public class ImageClientImpl implements ImageClient {
.build();
try {
LOGGER.info("Sending request to fetch image path");
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
logResponse(httpResponse);
return httpResponse.body();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
LOGGER.error("Failure occurred while getting image path", e);
}
return null;
}
private void logResponse(HttpResponse<String> httpResponse) {
if (isSuccessResponse(httpResponse.statusCode())) {
LOGGER.info("Image path received successfully");
} else {
LOGGER.warn("Image path request failed");
}
}
private boolean isSuccessResponse(int responseCode) {
return responseCode >= 200 && responseCode <= 299;
}
}

View File

@@ -23,18 +23,26 @@
package com.iluwatar.api.gateway;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
/**
* An adapter to communicate with the Price microservice.
*/
@Component
public class PriceClientImpl implements PriceClient {
private static final Logger LOGGER = getLogger(PriceClientImpl.class);
/**
* Makes a simple HTTP Get request to the Price microservice.
*
@@ -49,12 +57,26 @@ public class PriceClientImpl implements PriceClient {
.build();
try {
LOGGER.info("Sending request to fetch price info");
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
logResponse(httpResponse);
return httpResponse.body();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
LOGGER.error("Failure occurred while getting price info", e);
}
return null;
}
private void logResponse(HttpResponse<String> httpResponse) {
if (isSuccessResponse(httpResponse.statusCode())) {
LOGGER.info("Price info received successfully");
} else {
LOGGER.warn("Price info request failed");
}
}
private boolean isSuccessResponse(int responseCode) {
return responseCode >= 200 && responseCode <= 299;
}
}

View File

@@ -23,15 +23,20 @@
package com.iluwatar.image.microservice;
import static org.slf4j.LoggerFactory.getLogger;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* Exposes the Image microservice's endpoints.
*/
@RestController
public class ImageController {
private static final Logger LOGGER = getLogger(ImageController.class);
/**
* An endpoint for a user to retrieve an image path.
@@ -40,6 +45,7 @@ public class ImageController {
*/
@RequestMapping(value = "/image-path", method = RequestMethod.GET)
public String getImagePath() {
LOGGER.info("Successfully found image path");
return "/product-image.png";
}
}

View File

@@ -23,15 +23,20 @@
package com.iluwatar.price.microservice;
import static org.slf4j.LoggerFactory.getLogger;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* Exposes the Price microservice's endpoints.
*/
@RestController
public class PriceController {
private static final Logger LOGGER = getLogger(PriceController.class);
/**
* An endpoint for a user to retrieve a product's price.
@@ -40,6 +45,7 @@ public class PriceController {
*/
@RequestMapping(value = "/price", method = RequestMethod.GET)
public String getPrice() {
LOGGER.info("Successfully found price info");
return "20";
}
}

View File

@@ -25,12 +25,24 @@ package com.iluwatar.async.method.invocation;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
void test() throws Exception {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -24,15 +24,26 @@
package com.iluwatar.balking;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
void main() {
App.main();
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow((Executable) App::main);
}
}

View File

@@ -25,12 +25,22 @@ package com.iluwatar.bridge;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,12 +25,23 @@ package com.iluwatar.builder;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -27,13 +27,23 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Business Delegate example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() throws IOException {
String[] args = {};
App.main(args);
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -58,12 +58,14 @@ public class App {
var vm = new VirtualMachine();
vm.getWizards()[0] = wizard;
interpretInstruction("LITERAL 0", vm);
interpretInstruction("LITERAL 0", vm);
String literal = "LITERAL 0";
interpretInstruction(literal, vm);
interpretInstruction(literal, vm);
interpretInstruction("GET_HEALTH", vm);
interpretInstruction("LITERAL 0", vm);
interpretInstruction(literal, vm);
interpretInstruction("GET_AGILITY", vm);
interpretInstruction("LITERAL 0", vm);
interpretInstruction(literal, vm);
interpretInstruction("GET_WISDOM ", vm);
interpretInstruction("ADD", vm);
interpretInstruction("LITERAL 2", vm);

View File

@@ -25,13 +25,22 @@ package com.iluwatar.bytecode;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -27,12 +27,23 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Caching example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,12 +25,23 @@ package com.iluwatar.callback;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Callback example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,23 @@ package com.iluwatar.chain;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -39,6 +39,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -25,12 +25,19 @@ package com.iluwatar.combinator;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
public class CombinatorAppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link CombinatorApp#main(String[])}
* throws an exception.
*/
@Test
public void main() {
CombinatorApp.main(new String[]{});
public void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> CombinatorApp.main(new String[]{}));
}
}

View File

@@ -25,12 +25,21 @@ package com.iluwatar.command;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Command example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -36,9 +36,11 @@ import com.iluwatar.commander.queue.QueueDatabase;
import com.iluwatar.commander.queue.QueueTask;
import com.iluwatar.commander.queue.QueueTask.TaskType;
import com.iluwatar.commander.shippingservice.ShippingService;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>Commander pattern is used to handle all issues that can come up while making a
* distributed transaction. The idea is to have a commander, which coordinates the execution of all
@@ -159,8 +161,8 @@ public class Commander {
private void sendPaymentRequest(Order order) {
if (System.currentTimeMillis() - order.createdTime >= this.paymentTime) {
if (order.paid.equals(PaymentStatus.Trying)) {
order.paid = PaymentStatus.NotDone;
if (order.paid.equals(PaymentStatus.TRYING)) {
order.paid = PaymentStatus.NOT_DONE;
sendPaymentFailureMessage(order);
LOG.error("Order " + order.id + ": Payment time for order over, failed and returning..");
} //if succeeded or failed, would have been dequeued, no attempt to make payment
@@ -172,15 +174,15 @@ public class Commander {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
LOG.debug("Order " + order.id + ": Error in connecting to payment service,"
+ " trying again..");
+ " trying again..");
} else {
LOG.debug("Order " + order.id + ": Error in creating payment request..");
}
throw l.remove(0);
}
if (order.paid.equals(PaymentStatus.Trying)) {
if (order.paid.equals(PaymentStatus.TRYING)) {
var transactionId = paymentService.receiveRequest(order.price);
order.paid = PaymentStatus.Done;
order.paid = PaymentStatus.DONE;
LOG.info("Order " + order.id + ": Payment successful, transaction Id: " + transactionId);
if (!finalSiteMsgShown) {
LOG.info("Payment made successfully, thank you for shopping with us!!");
@@ -193,26 +195,26 @@ public class Commander {
if (PaymentDetailsErrorException.class.isAssignableFrom(err.getClass())) {
if (!finalSiteMsgShown) {
LOG.info("There was an error in payment. Your account/card details "
+ "may have been incorrect. "
+ "Meanwhile, your order has been converted to COD and will be shipped.");
+ "may have been incorrect. "
+ "Meanwhile, your order has been converted to COD and will be shipped.");
finalSiteMsgShown = true;
}
LOG.error("Order " + order.id + ": Payment details incorrect, failed..");
o.paid = PaymentStatus.NotDone;
o.paid = PaymentStatus.NOT_DONE;
sendPaymentFailureMessage(o);
} else {
if (o.messageSent.equals(MessageSent.NoneSent)) {
if (o.messageSent.equals(MessageSent.NONE_SENT)) {
if (!finalSiteMsgShown) {
LOG.info("There was an error in payment. We are on it, and will get back to you "
+ "asap. Don't worry, your order has been placed and will be shipped.");
+ "asap. Don't worry, your order has been placed and will be shipped.");
finalSiteMsgShown = true;
}
LOG.warn("Order " + order.id + ": Payment error, going to queue..");
sendPaymentPossibleErrorMsg(o);
}
if (o.paid.equals(PaymentStatus.Trying) && System
.currentTimeMillis() - o.createdTime < paymentTime) {
var qt = new QueueTask(o, TaskType.Payment, -1);
if (o.paid.equals(PaymentStatus.TRYING) && System
.currentTimeMillis() - o.createdTime < paymentTime) {
var qt = new QueueTask(o, TaskType.PAYMENT, -1);
updateQueue(qt);
}
}
@@ -234,12 +236,12 @@ public class Commander {
// additional check not needed
LOG.trace("Order " + qt.order.id + ": Queue time for order over, failed..");
return;
} else if (qt.taskType.equals(TaskType.Payment) && !qt.order.paid.equals(PaymentStatus.Trying)
|| qt.taskType.equals(TaskType.Messaging) && (qt.messageType == 1
&& !qt.order.messageSent.equals(MessageSent.NoneSent)
|| qt.order.messageSent.equals(MessageSent.PaymentFail)
|| qt.order.messageSent.equals(MessageSent.PaymentSuccessful))
|| qt.taskType.equals(TaskType.EmployeeDb) && qt.order.addedToEmployeeHandle) {
} else if (qt.taskType.equals(TaskType.PAYMENT) && !qt.order.paid.equals(PaymentStatus.TRYING)
|| qt.taskType.equals(TaskType.MESSAGING) && (qt.messageType == 1
&& !qt.order.messageSent.equals(MessageSent.NONE_SENT)
|| qt.order.messageSent.equals(MessageSent.PAYMENT_FAIL)
|| qt.order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL))
|| qt.taskType.equals(TaskType.EMPLOYEE_DB) && qt.order.addedToEmployeeHandle) {
LOG.trace("Order " + qt.order.id + ": Not queueing task since task already done..");
return;
}
@@ -256,8 +258,8 @@ public class Commander {
tryDoingTasksInQueue();
};
Retry.HandleErrorIssue<QueueTask> handleError = (qt1, err) -> {
if (qt1.taskType.equals(TaskType.Payment)) {
qt1.order.paid = PaymentStatus.NotDone;
if (qt1.taskType.equals(TaskType.PAYMENT)) {
qt1.order.paid = PaymentStatus.NOT_DONE;
sendPaymentFailureMessage(qt1.order);
LOG.error("Order " + qt1.order.id + ": Unable to enqueue payment task,"
+ " payment failed..");
@@ -331,35 +333,9 @@ public class Commander {
}
var list = messagingService.exceptionsList;
Thread t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
LOG.debug("Order " + order.id + ": Error in connecting to messaging service "
+ "(Payment Success msg), trying again..");
} else {
LOG.debug("Order " + order.id + ": Error in creating Payment Success"
+ " messaging request..");
}
throw l.remove(0);
}
if (!order.messageSent.equals(MessageSent.PaymentFail)
&& !order.messageSent.equals(MessageSent.PaymentSuccessful)) {
var requestId = messagingService.receiveRequest(2);
order.messageSent = MessageSent.PaymentSuccessful;
LOG.info("Order " + order.id + ": Payment Success message sent,"
+ " request Id: " + requestId);
}
};
Retry.Operation op = handleSuccessMessageRetryOperation(order);
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent
.equals(MessageSent.PaymentTrying))
&& System.currentTimeMillis() - o.createdTime < messageTime) {
var qt = new QueueTask(order, TaskType.Messaging, 2);
updateQueue(qt);
LOG.info("Order " + order.id + ": Error in sending Payment Success message, trying to"
+ " queue task and add to employee handle..");
employeeHandleIssue(order);
}
handleSuccessMessageErrorIssue(order, o);
};
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
@@ -372,6 +348,40 @@ public class Commander {
t.start();
}
private void handleSuccessMessageErrorIssue(Order order, Order o) {
if ((o.messageSent.equals(MessageSent.NONE_SENT) || o.messageSent
.equals(MessageSent.PAYMENT_TRYING))
&& System.currentTimeMillis() - o.createdTime < messageTime) {
var qt = new QueueTask(order, TaskType.MESSAGING, 2);
updateQueue(qt);
LOG.info("Order " + order.id + ": Error in sending Payment Success message, trying to"
+ " queue task and add to employee handle..");
employeeHandleIssue(order);
}
}
private Retry.Operation handleSuccessMessageRetryOperation(Order order) {
return (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
LOG.debug("Order " + order.id + ": Error in connecting to messaging service "
+ "(Payment Success msg), trying again..");
} else {
LOG.debug("Order " + order.id + ": Error in creating Payment Success"
+ " messaging request..");
}
throw l.remove(0);
}
if (!order.messageSent.equals(MessageSent.PAYMENT_FAIL)
&& !order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) {
var requestId = messagingService.receiveRequest(2);
order.messageSent = MessageSent.PAYMENT_SUCCESSFUL;
LOG.info("Order " + order.id + ": Payment Success message sent,"
+ " request Id: " + requestId);
}
};
}
private void sendPaymentFailureMessage(Order order) {
if (System.currentTimeMillis() - order.createdTime >= this.messageTime) {
LOG.trace("Order " + order.id + ": Message time for order over, returning..");
@@ -380,34 +390,10 @@ public class Commander {
var list = messagingService.exceptionsList;
var t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
LOG.debug("Order " + order.id + ": Error in connecting to messaging service "
+ "(Payment Failure msg), trying again..");
} else {
LOG.debug("Order " + order.id + ": Error in creating Payment Failure"
+ " message request..");
}
throw l.remove(0);
}
if (!order.messageSent.equals(MessageSent.PaymentFail)
&& !order.messageSent.equals(MessageSent.PaymentSuccessful)) {
var requestId = messagingService.receiveRequest(0);
order.messageSent = MessageSent.PaymentFail;
LOG.info("Order " + order.id + ": Payment Failure message sent successfully,"
+ " request Id: " + requestId);
}
handlePaymentFailureRetryOperation(order, l);
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent
.equals(MessageSent.PaymentTrying))
&& System.currentTimeMillis() - o.createdTime < messageTime) {
var qt = new QueueTask(order, TaskType.Messaging, 0);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in sending Payment Failure message, "
+ "trying to queue task and add to employee handle..");
employeeHandleIssue(o);
}
handlePaymentErrorIssue(order, o);
};
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
@@ -420,6 +406,38 @@ public class Commander {
t.start();
}
private void handlePaymentErrorIssue(Order order, Order o) {
if ((o.messageSent.equals(MessageSent.NONE_SENT) || o.messageSent
.equals(MessageSent.PAYMENT_TRYING))
&& System.currentTimeMillis() - o.createdTime < messageTime) {
var qt = new QueueTask(order, TaskType.MESSAGING, 0);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in sending Payment Failure message, "
+ "trying to queue task and add to employee handle..");
employeeHandleIssue(o);
}
}
private void handlePaymentFailureRetryOperation(Order order, List<Exception> l) throws Exception {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
LOG.debug("Order " + order.id + ": Error in connecting to messaging service "
+ "(Payment Failure msg), trying again..");
} else {
LOG.debug("Order " + order.id + ": Error in creating Payment Failure"
+ " message request..");
}
throw l.remove(0);
}
if (!order.messageSent.equals(MessageSent.PAYMENT_FAIL)
&& !order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) {
var requestId = messagingService.receiveRequest(0);
order.messageSent = MessageSent.PAYMENT_FAIL;
LOG.info("Order " + order.id + ": Payment Failure message sent successfully,"
+ " request Id: " + requestId);
}
}
private void sendPaymentPossibleErrorMsg(Order order) {
if (System.currentTimeMillis() - order.createdTime >= this.messageTime) {
LOG.trace("Message time for order over, returning..");
@@ -428,34 +446,10 @@ public class Commander {
var list = messagingService.exceptionsList;
var t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
LOG.debug("Order " + order.id + ": Error in connecting to messaging service "
+ "(Payment Error msg), trying again..");
} else {
LOG.debug("Order " + order.id + ": Error in creating Payment Error"
+ " messaging request..");
}
throw l.remove(0);
}
if (order.paid.equals(PaymentStatus.Trying) && order.messageSent
.equals(MessageSent.NoneSent)) {
var requestId = messagingService.receiveRequest(1);
order.messageSent = MessageSent.PaymentTrying;
LOG.info("Order " + order.id + ": Payment Error message sent successfully,"
+ " request Id: " + requestId);
}
handlePaymentPossibleErrorMsgRetryOperation(order, l);
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
if (o.messageSent.equals(MessageSent.NoneSent) && order.paid
.equals(PaymentStatus.Trying)
&& System.currentTimeMillis() - o.createdTime < messageTime) {
var qt = new QueueTask(order, TaskType.Messaging, 1);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in sending Payment Error message, "
+ "trying to queue task and add to employee handle..");
employeeHandleIssue(o);
}
handlePaymentPossibleErrorMsgErrorIssue(order, o);
};
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
@@ -468,6 +462,39 @@ public class Commander {
t.start();
}
private void handlePaymentPossibleErrorMsgErrorIssue(Order order, Order o) {
if (o.messageSent.equals(MessageSent.NONE_SENT) && order.paid
.equals(PaymentStatus.TRYING)
&& System.currentTimeMillis() - o.createdTime < messageTime) {
var qt = new QueueTask(order, TaskType.MESSAGING, 1);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in sending Payment Error message, "
+ "trying to queue task and add to employee handle..");
employeeHandleIssue(o);
}
}
private void handlePaymentPossibleErrorMsgRetryOperation(Order order, List<Exception> l)
throws Exception {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
LOG.debug("Order " + order.id + ": Error in connecting to messaging service "
+ "(Payment Error msg), trying again..");
} else {
LOG.debug("Order " + order.id + ": Error in creating Payment Error"
+ " messaging request..");
}
throw l.remove(0);
}
if (order.paid.equals(PaymentStatus.TRYING) && order.messageSent
.equals(MessageSent.NONE_SENT)) {
var requestId = messagingService.receiveRequest(1);
order.messageSent = MessageSent.PAYMENT_TRYING;
LOG.info("Order " + order.id + ": Payment Error message sent successfully,"
+ " request Id: " + requestId);
}
}
private void employeeHandleIssue(Order order) {
if (System.currentTimeMillis() - order.createdTime >= this.employeeTime) {
LOG.trace("Order " + order.id + ": Employee handle time for order over, returning..");
@@ -490,7 +517,7 @@ public class Commander {
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
if (!o.addedToEmployeeHandle && System
.currentTimeMillis() - order.createdTime < employeeTime) {
var qt = new QueueTask(order, TaskType.EmployeeDb, -1);
var qt = new QueueTask(order, TaskType.EMPLOYEE_DB, -1);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in adding to employee db,"
+ " trying to queue task..");
@@ -520,21 +547,21 @@ public class Commander {
LOG.trace("Order " + qt.order.id + ": This queue task of type " + qt.getType()
+ " does not need to be done anymore (timeout), dequeue..");
} else {
if (qt.taskType.equals(TaskType.Payment)) {
if (!qt.order.paid.equals(PaymentStatus.Trying)) {
if (qt.taskType.equals(TaskType.PAYMENT)) {
if (!qt.order.paid.equals(PaymentStatus.TRYING)) {
tryDequeue();
LOG.trace("Order " + qt.order.id + ": This payment task already done, dequeueing..");
} else {
sendPaymentRequest(qt.order);
LOG.debug("Order " + qt.order.id + ": Trying to connect to payment service..");
}
} else if (qt.taskType.equals(TaskType.Messaging)) {
if (qt.order.messageSent.equals(MessageSent.PaymentFail)
|| qt.order.messageSent.equals(MessageSent.PaymentSuccessful)) {
} else if (qt.taskType.equals(TaskType.MESSAGING)) {
if (qt.order.messageSent.equals(MessageSent.PAYMENT_FAIL)
|| qt.order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) {
tryDequeue();
LOG.trace("Order " + qt.order.id + ": This messaging task already done, dequeue..");
} else if (qt.messageType == 1 && (!qt.order.messageSent.equals(MessageSent.NoneSent)
|| !qt.order.paid.equals(PaymentStatus.Trying))) {
} else if (qt.messageType == 1 && (!qt.order.messageSent.equals(MessageSent.NONE_SENT)
|| !qt.order.paid.equals(PaymentStatus.TRYING))) {
tryDequeue();
LOG.trace("Order " + qt.order.id + ": This messaging task does not need to be done,"
+ " dequeue..");
@@ -548,7 +575,7 @@ public class Commander {
sendSuccessMessage(qt.order);
LOG.debug("Order " + qt.order.id + ": Trying to connect to messaging service..");
}
} else if (qt.taskType.equals(TaskType.EmployeeDb)) {
} else if (qt.taskType.equals(TaskType.EMPLOYEE_DB)) {
if (qt.order.addedToEmployeeHandle) {
tryDequeue();
LOG.trace("Order " + qt.order.id + ": This employee handle task already done,"

View File

@@ -33,11 +33,11 @@ import java.util.Random;
public class Order { //can store all transactions ids also
enum PaymentStatus {
NotDone, Trying, Done
NOT_DONE, TRYING, DONE
}
enum MessageSent {
NoneSent, PaymentFail, PaymentTrying, PaymentSuccessful
NONE_SENT, PAYMENT_FAIL, PAYMENT_TRYING, PAYMENT_SUCCESSFUL
}
final User user;
@@ -65,8 +65,8 @@ public class Order { //can store all transactions ids also
}
this.id = id;
USED_IDS.put(this.id, true);
this.paid = PaymentStatus.Trying;
this.messageSent = MessageSent.NoneSent;
this.paid = PaymentStatus.TRYING;
this.messageSent = MessageSent.NONE_SENT;
this.addedToEmployeeHandle = false;
}

View File

@@ -38,7 +38,7 @@ public class MessagingService extends Service {
private static final Logger LOGGER = LoggerFactory.getLogger(MessagingService.class);
enum MessageToSend {
PaymentFail, PaymentTrying, PaymentSuccessful
PAYMENT_FAIL, PAYMENT_TRYING, PAYMENT_SUCCESSFUL
}
class MessageRequest {
@@ -63,11 +63,11 @@ public class MessagingService extends Service {
var id = generateId();
MessageToSend msg;
if (messageToSend == 0) {
msg = MessageToSend.PaymentFail;
msg = MessageToSend.PAYMENT_FAIL;
} else if (messageToSend == 1) {
msg = MessageToSend.PaymentTrying;
msg = MessageToSend.PAYMENT_TRYING;
} else { //messageToSend == 2
msg = MessageToSend.PaymentSuccessful;
msg = MessageToSend.PAYMENT_SUCCESSFUL;
}
var req = new MessageRequest(id, msg);
return updateDb(req);
@@ -84,10 +84,10 @@ public class MessagingService extends Service {
}
String sendMessage(MessageToSend m) {
if (m.equals(MessageToSend.PaymentSuccessful)) {
if (m.equals(MessageToSend.PAYMENT_SUCCESSFUL)) {
return "Msg: Your order has been placed and paid for successfully!"
+ " Thank you for shopping with us!";
} else if (m.equals(MessageToSend.PaymentTrying)) {
} else if (m.equals(MessageToSend.PAYMENT_TRYING)) {
return "Msg: There was an error in your payment process,"
+ " we are working on it and will return back to you shortly."
+ " Meanwhile, your order has been placed and will be shipped.";

View File

@@ -36,7 +36,7 @@ public class QueueTask {
*/
public enum TaskType {
Messaging, Payment, EmployeeDb
MESSAGING, PAYMENT, EMPLOYEE_DB
}
public Order order;
@@ -68,7 +68,7 @@ public class QueueTask {
* @return String representing type of task
*/
public String getType() {
if (!this.taskType.equals(TaskType.Messaging)) {
if (!this.taskType.equals(TaskType.MESSAGING)) {
return this.taskType.toString();
} else {
if (this.messageType == 0) {

View File

@@ -23,15 +23,23 @@
package com.iluwatar.composite;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
Assertions.assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,14 +25,24 @@ package com.iluwatar.converter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* App running test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void testMain() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,12 +25,22 @@ package com.iluwatar.dao;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that DAO example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() throws Exception {
App.main(new String[]{});
void shouldExecuteDaoWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -43,6 +43,6 @@ public class AiComponent implements Component {
@Override
public void render() {
// Do Nothing.
}
}

View File

@@ -40,7 +40,7 @@ public class AiComponentManager {
private final int numEntities;
private static final Component[] AI_COMPONENTS = new AiComponent[MAX_ENTITIES];
private final Component[] aiComponents = new AiComponent[MAX_ENTITIES];
public AiComponentManager(int numEntities) {
this.numEntities = numEntities;
@@ -51,7 +51,7 @@ public class AiComponentManager {
*/
public void start() {
LOGGER.info("Start AI Game Component");
IntStream.range(0, numEntities).forEach(i -> AI_COMPONENTS[i] = new AiComponent());
IntStream.range(0, numEntities).forEach(i -> aiComponents[i] = new AiComponent());
}
/**
@@ -60,7 +60,7 @@ public class AiComponentManager {
public void update() {
LOGGER.info("Update AI Game Component");
IntStream.range(0, numEntities)
.filter(i -> AI_COMPONENTS.length > i && AI_COMPONENTS[i] != null)
.forEach(i -> AI_COMPONENTS[i].update());
.filter(i -> aiComponents.length > i && aiComponents[i] != null)
.forEach(i -> aiComponents[i].update());
}
}

View File

@@ -40,7 +40,7 @@ public class PhysicsComponentManager {
private final int numEntities;
private static final Component[] PHYSICS_COMPONENTS = new PhysicsComponent[MAX_ENTITIES];
private final Component[] physicsComponents = new PhysicsComponent[MAX_ENTITIES];
public PhysicsComponentManager(int numEntities) {
this.numEntities = numEntities;
@@ -51,7 +51,7 @@ public class PhysicsComponentManager {
*/
public void start() {
LOGGER.info("Start Physics Game Component ");
IntStream.range(0, numEntities).forEach(i -> PHYSICS_COMPONENTS[i] = new PhysicsComponent());
IntStream.range(0, numEntities).forEach(i -> physicsComponents[i] = new PhysicsComponent());
}
@@ -62,7 +62,7 @@ public class PhysicsComponentManager {
LOGGER.info("Update Physics Game Component ");
// Process physics.
IntStream.range(0, numEntities)
.filter(i -> PHYSICS_COMPONENTS.length > i && PHYSICS_COMPONENTS[i] != null)
.forEach(i -> PHYSICS_COMPONENTS[i].update());
.filter(i -> physicsComponents.length > i && physicsComponents[i] != null)
.forEach(i -> physicsComponents[i].update());
}
}

View File

@@ -40,7 +40,7 @@ public class RenderComponentManager {
private final int numEntities;
private static final Component[] RENDER_COMPONENTS = new RenderComponent[MAX_ENTITIES];
private final Component[] renderComponents = new RenderComponent[MAX_ENTITIES];
public RenderComponentManager(int numEntities) {
this.numEntities = numEntities;
@@ -51,7 +51,7 @@ public class RenderComponentManager {
*/
public void start() {
LOGGER.info("Start Render Game Component ");
IntStream.range(0, numEntities).forEach(i -> RENDER_COMPONENTS[i] = new RenderComponent());
IntStream.range(0, numEntities).forEach(i -> renderComponents[i] = new RenderComponent());
}
@@ -62,7 +62,7 @@ public class RenderComponentManager {
LOGGER.info("Update Render Game Component ");
// Process Render.
IntStream.range(0, numEntities)
.filter(i -> RENDER_COMPONENTS.length > i && RENDER_COMPONENTS[i] != null)
.forEach(i -> RENDER_COMPONENTS[i].render());
.filter(i -> renderComponents.length > i && renderComponents[i] != null)
.forEach(i -> renderComponents[i].render());
}
}

View File

@@ -26,16 +26,22 @@ package com.iluwatar.data.locality;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Test Game Application
*/
class ApplicationTest {
/**
* Test run
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link Application#main(String[])}
* throws an exception.
*/
@Test
void main() {
Application.main(new String[] {});
void shouldExecuteGameApplicationWithoutException() {
assertDoesNotThrow(() -> Application.main(new String[] {}));
}
}

View File

@@ -24,14 +24,25 @@
package com.iluwatar.datamapper;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Data-Mapper example runs without errors.
*/
public final class AppTest {
final class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main();
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow((Executable) App::main);
}
}

View File

@@ -25,9 +25,19 @@ package com.iluwatar.datatransfer;
import org.junit.jupiter.api.Test;
public class AppTest {
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() throws Exception {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.decorator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,14 +25,23 @@ package com.iluwatar.delegation.simple;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application Test Entry
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.dependency.injection;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -31,7 +31,6 @@
<artifactId>java-design-patterns</artifactId>
<version>1.23.0-SNAPSHOT</version>
</parent>
<groupId>com.iluwatar</groupId>
<artifactId>dirty-flag</artifactId>
<version>1.23.0-SNAPSHOT</version>
<name>dirty-flag</name>
@@ -45,6 +44,12 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@@ -26,12 +26,22 @@ package org.dirty.flag;
import com.iluwatar.dirtyflag.App;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Dirty-Flag example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -23,29 +23,27 @@
package org.dirty.flag;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.dirtyflag.DataFetcher;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* Application test
*/
public class DirtyFlagTest {
class DirtyFlagTest {
@Test
public void testIsDirty() {
void testIsDirty() {
var df = new DataFetcher();
var countries = df.fetch();
assertFalse(countries.isEmpty());
Assertions.assertFalse(countries.isEmpty());
}
@Test
public void testIsNotDirty() {
void testIsNotDirty() {
var df = new DataFetcher();
df.fetch();
var countries = df.fetch();
assertTrue(countries.isEmpty());
Assertions.assertTrue(countries.isEmpty());
}
}

View File

@@ -44,6 +44,11 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@@ -25,14 +25,23 @@ package com.iluwatar.doublebuffer;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* App unit test.
*/
public class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void testMain() {
App.main(new String[]{});
public void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,23 @@ package com.iluwatar.doublechecked.locking;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,23 @@ package com.iluwatar.doubledispatch;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.eip.aggregator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Test for App class
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void testMain() throws Exception {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.eip.message.channel;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() throws Exception {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.eip.publish.subscribe;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() throws Exception {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.eip.splitter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Test for App class
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void testMain() throws Exception {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.eip.wiretap;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Test for App class
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void testMain() throws Exception {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,22 @@ package com.iluwatar.event.aggregator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,12 +25,22 @@ package com.iluwatar.event.asynchronous;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that EventAsynchronous example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,12 +25,22 @@ package com.iluwatar.eda;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Event Driven Architecture example runs without errors.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
*
* Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])}
* throws an exception.
*/
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -29,19 +29,21 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests execute-around example.
*/
public class AppTest {
class AppTest {
@Test
public void test() throws IOException {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
@BeforeEach
@AfterEach
public void cleanup() {
void cleanup() {
var file = new File("testfile.txt");
file.delete();
}

View File

@@ -45,4 +45,8 @@ public class Commander implements CommanderExtension {
public void commanderReady() {
LOGGER.info("[Commander] " + unit.getName() + " is ready!");
}
public CommanderUnit getUnit() {
return unit;
}
}

View File

@@ -43,6 +43,10 @@ public class Sergeant implements SergeantExtension {
@Override
public void sergeantReady() {
LOGGER.info("[Sergeant] " + unit.getName() + " is ready! ");
LOGGER.info("[Sergeant] " + unit.getName() + " is ready!");
}
public SergeantUnit getUnit() {
return unit;
}
}

View File

@@ -42,6 +42,10 @@ public class Soldier implements SoldierExtension {
@Override
public void soldierReady() {
LOGGER.info("[Solider] " + unit.getName() + " is ready!");
LOGGER.info("[Soldier] " + unit.getName() + " is ready!");
}
public SoldierUnit getUnit() {
return unit;
}
}

View File

@@ -23,13 +23,16 @@
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Created by Srdjan on 03-May-17.
*/
public class AppTest {
class AppTest {
@Test
public void main() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -23,17 +23,43 @@
package concreteextensions;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import units.CommanderUnit;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Created by Srdjan on 03-May-17.
*
* Modified by ToxicDreamz on 15-Aug-20
*/
public class CommanderTest {
class CommanderTest {
@Test
public void commanderReady() {
void shouldExecuteCommanderReady() {
Logger commanderLogger = (Logger) LoggerFactory.getLogger(Commander.class);
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
listAppender.start();
commanderLogger.addAppender(listAppender);
final var commander = new Commander(new CommanderUnit("CommanderUnitTest"));
commander.commanderReady();
List<ILoggingEvent> logsList = listAppender.list;
assertEquals("[Commander] " + commander.getUnit().getName() + " is ready!", logsList.get(0)
.getMessage());
assertEquals(Level.INFO, logsList.get(0)
.getLevel());
}
}

View File

@@ -23,17 +23,41 @@
package concreteextensions;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import units.SergeantUnit;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Created by Srdjan on 03-May-17.
*/
public class SergeantTest {
class SergeantTest {
@Test
public void sergeantReady() {
void sergeantReady() {
Logger sergeantLogger = (Logger) LoggerFactory.getLogger(Sergeant.class);
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
listAppender.start();
sergeantLogger.addAppender(listAppender);
final var sergeant = new Sergeant(new SergeantUnit("SergeantUnitTest"));
sergeant.sergeantReady();
List<ILoggingEvent> logsList = listAppender.list;
assertEquals("[Sergeant] " + sergeant.getUnit().getName() + " is ready!", logsList.get(0)
.getMessage());
assertEquals(Level.INFO, logsList.get(0)
.getLevel());
}
}

View File

@@ -23,17 +23,41 @@
package concreteextensions;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import units.SoldierUnit;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Created by Srdjan on 03-May-17.
*/
public class SoldierTest {
class SoldierTest {
@Test
public void soldierReady() {
void soldierReady() {
Logger soldierLogger = (Logger) LoggerFactory.getLogger(Soldier.class);
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
listAppender.start();
soldierLogger.addAppender(listAppender);
final var soldier = new Soldier(new SoldierUnit("SoldierUnitTest"));
soldier.soldierReady();
List<ILoggingEvent> logsList = listAppender.list;
assertEquals("[Soldier] " + soldier.getUnit().getName() + " is ready!", logsList.get(0)
.getMessage());
assertEquals(Level.INFO, logsList.get(0)
.getLevel());
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.facade;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -26,14 +26,16 @@ package com.iluwatar.factorykit.app;
import com.iluwatar.factorykit.App;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application Test Entrypoint
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,12 +25,15 @@ package com.iluwatar.factory.method;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests that Factory Method example runs without errors.
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.fluentinterface.app;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application Test Entry
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -57,15 +57,10 @@ public final class Dispatcher {
*/
public void menuItemSelected(MenuItem menuItem) {
dispatchAction(new MenuAction(menuItem));
switch (menuItem) {
case HOME:
case PRODUCTS:
default:
dispatchAction(new ContentAction(Content.PRODUCTS));
break;
case COMPANY:
dispatchAction(new ContentAction(Content.COMPANY));
break;
if (menuItem == MenuItem.COMPANY) {
dispatchAction(new ContentAction(Content.COMPANY));
} else {
dispatchAction(new ContentAction(Content.PRODUCTS));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.flux.app;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.flyweight;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.front.controller;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -39,6 +39,12 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@@ -25,14 +25,16 @@ package com.iluwatar.gameloop;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* App unit test class.
*/
public class AppTest {
@Test
public void testMain() {
new App().main(new String[]{});
public void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.halfsynchalfasync;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(null);
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(null));
}
}

View File

@@ -46,6 +46,7 @@ public class MongoTicketRepository implements LotteryTicketRepository {
private static final String DEFAULT_DB = "lotteryDB";
private static final String DEFAULT_TICKETS_COLLECTION = "lotteryTickets";
private static final String DEFAULT_COUNTERS_COLLECTION = "counters";
private static final String TICKET_ID = "ticketId";
private MongoClient mongoClient;
private MongoDatabase database;
@@ -93,7 +94,7 @@ public class MongoTicketRepository implements LotteryTicketRepository {
}
private void initCounters() {
var doc = new Document("_id", "ticketId").append("seq", 1);
var doc = new Document("_id", TICKET_ID).append("seq", 1);
countersCollection.insertOne(doc);
}
@@ -103,7 +104,7 @@ public class MongoTicketRepository implements LotteryTicketRepository {
* @return next ticket id
*/
public int getNextId() {
var find = new Document("_id", "ticketId");
var find = new Document("_id", TICKET_ID);
var increase = new Document("seq", 1);
var update = new Document("$inc", increase);
var result = countersCollection.findOneAndUpdate(find, update);
@@ -131,7 +132,7 @@ public class MongoTicketRepository implements LotteryTicketRepository {
@Override
public Optional<LotteryTicket> findById(LotteryTicketId id) {
return ticketsCollection
.find(new Document("ticketId", id.getId()))
.find(new Document(TICKET_ID, id.getId()))
.limit(1)
.into(new ArrayList<>())
.stream()
@@ -142,7 +143,7 @@ public class MongoTicketRepository implements LotteryTicketRepository {
@Override
public Optional<LotteryTicketId> save(LotteryTicket ticket) {
var ticketId = getNextId();
var doc = new Document("ticketId", ticketId);
var doc = new Document(TICKET_ID, ticketId);
doc.put("email", ticket.getPlayerDetails().getEmail());
doc.put("bank", ticket.getPlayerDetails().getBankAccount());
doc.put("phone", ticket.getPlayerDetails().getPhoneNumber());
@@ -173,7 +174,7 @@ public class MongoTicketRepository implements LotteryTicketRepository {
.map(Integer::parseInt)
.collect(Collectors.toSet());
var lotteryNumbers = LotteryNumbers.create(numbers);
var ticketId = new LotteryTicketId(doc.getInteger("ticketId"));
var ticketId = new LotteryTicketId(doc.getInteger(TICKET_ID));
return new LotteryTicket(ticketId, playerDetails, lotteryNumbers);
}
}

View File

@@ -36,6 +36,9 @@ public class MongoEventLog implements LotteryEventLog {
private static final String DEFAULT_DB = "lotteryDB";
private static final String DEFAULT_EVENTS_COLLECTION = "events";
private static final String EMAIL = "email";
private static final String PHONE = "phone";
public static final String MESSAGE = "message";
private MongoClient mongoClient;
private MongoDatabase database;
@@ -107,41 +110,41 @@ public class MongoEventLog implements LotteryEventLog {
@Override
public void ticketSubmitted(PlayerDetails details) {
var document = new Document("email", details.getEmail());
document.put("phone", details.getPhoneNumber());
var document = new Document(EMAIL, details.getEmail());
document.put(PHONE, details.getPhoneNumber());
document.put("bank", details.getBankAccount());
document
.put("message", "Lottery ticket was submitted and bank account was charged for 3 credits.");
.put(MESSAGE, "Lottery ticket was submitted and bank account was charged for 3 credits.");
eventsCollection.insertOne(document);
stdOutEventLog.ticketSubmitted(details);
}
@Override
public void ticketSubmitError(PlayerDetails details) {
var document = new Document("email", details.getEmail());
document.put("phone", details.getPhoneNumber());
var document = new Document(EMAIL, details.getEmail());
document.put(PHONE, details.getPhoneNumber());
document.put("bank", details.getBankAccount());
document.put("message", "Lottery ticket could not be submitted because lack of funds.");
document.put(MESSAGE, "Lottery ticket could not be submitted because lack of funds.");
eventsCollection.insertOne(document);
stdOutEventLog.ticketSubmitError(details);
}
@Override
public void ticketDidNotWin(PlayerDetails details) {
var document = new Document("email", details.getEmail());
document.put("phone", details.getPhoneNumber());
var document = new Document(EMAIL, details.getEmail());
document.put(PHONE, details.getPhoneNumber());
document.put("bank", details.getBankAccount());
document.put("message", "Lottery ticket was checked and unfortunately did not win this time.");
document.put(MESSAGE, "Lottery ticket was checked and unfortunately did not win this time.");
eventsCollection.insertOne(document);
stdOutEventLog.ticketDidNotWin(details);
}
@Override
public void ticketWon(PlayerDetails details, int prizeAmount) {
var document = new Document("email", details.getEmail());
document.put("phone", details.getPhoneNumber());
var document = new Document(EMAIL, details.getEmail());
document.put(PHONE, details.getPhoneNumber());
document.put("bank", details.getBankAccount());
document.put("message", String
document.put(MESSAGE, String
.format("Lottery ticket won! The bank account was deposited with %d credits.",
prizeAmount));
eventsCollection.insertOne(document);
@@ -150,10 +153,10 @@ public class MongoEventLog implements LotteryEventLog {
@Override
public void prizeError(PlayerDetails details, int prizeAmount) {
var document = new Document("email", details.getEmail());
document.put("phone", details.getPhoneNumber());
var document = new Document(EMAIL, details.getEmail());
document.put(PHONE, details.getPhoneNumber());
document.put("bank", details.getBankAccount());
document.put("message", String
document.put(MESSAGE, String
.format("Lottery ticket won! Unfortunately the bank credit transfer of %d failed.",
prizeAmount));
eventsCollection.insertOne(document);

View File

@@ -25,13 +25,16 @@ package com.iluwatar.hexagonal;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Unit test for simple App.
*/
class AppTest {
@Test
void testApp() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.intercepting.filter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test.
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.interpreter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
public class AppTest {
class AppTest {
@Test
public void test() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,13 +25,15 @@ package com.iluwatar.iterator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application Test
*/
class AppTest {
@Test
void testApp() {
App.main(new String[]{});
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -81,6 +81,7 @@ import java.util.List;
public class App {
private static final CakeBakingService cakeBakingService = new CakeBakingServiceImpl();
public static final String STRAWBERRY = "strawberry";
/**
* Application entry point.
@@ -103,10 +104,10 @@ public class App {
private static void initializeData(CakeBakingService cakeBakingService) {
cakeBakingService.saveNewLayer(new CakeLayerInfo("chocolate", 1200));
cakeBakingService.saveNewLayer(new CakeLayerInfo("banana", 900));
cakeBakingService.saveNewLayer(new CakeLayerInfo("strawberry", 950));
cakeBakingService.saveNewLayer(new CakeLayerInfo(STRAWBERRY, 950));
cakeBakingService.saveNewLayer(new CakeLayerInfo("lemon", 950));
cakeBakingService.saveNewLayer(new CakeLayerInfo("vanilla", 950));
cakeBakingService.saveNewLayer(new CakeLayerInfo("strawberry", 950));
cakeBakingService.saveNewLayer(new CakeLayerInfo(STRAWBERRY, 950));
cakeBakingService.saveNewTopping(new CakeToppingInfo("candies", 350));
cakeBakingService.saveNewTopping(new CakeToppingInfo("cherry", 350));
@@ -114,7 +115,7 @@ public class App {
var cake1 = new CakeInfo(new CakeToppingInfo("candies", 0), List.of(
new CakeLayerInfo("chocolate", 0),
new CakeLayerInfo("banana", 0),
new CakeLayerInfo("strawberry", 0)));
new CakeLayerInfo(STRAWBERRY, 0)));
try {
cakeBakingService.bakeNewCake(cake1);
} catch (CakeBakingException e) {
@@ -123,7 +124,7 @@ public class App {
var cake2 = new CakeInfo(new CakeToppingInfo("cherry", 0), List.of(
new CakeLayerInfo("vanilla", 0),
new CakeLayerInfo("lemon", 0),
new CakeLayerInfo("strawberry", 0)));
new CakeLayerInfo(STRAWBERRY, 0)));
try {
cakeBakingService.bakeNewCake(cake2);
} catch (CakeBakingException e) {

View File

@@ -23,19 +23,19 @@
package com.iluwatar.layers.app;
import com.iluwatar.layers.app.App;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
*
* Application test
*
*/
public class AppTest {
class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -25,16 +25,17 @@ package com.iluwatar.lazy.loading;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
*
* Application test
*
*/
public class AppTest {
class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@@ -36,6 +36,7 @@ public abstract class AbstractInstance implements Instance, Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractInstance.class);
protected static final int HEARTBEAT_INTERVAL = 5000;
private static final String INSTANCE = "Instance ";
protected MessageManager messageManager;
protected Queue<Message> messageQueue;
@@ -106,27 +107,27 @@ public abstract class AbstractInstance implements Instance, Runnable {
private void processMessage(Message message) {
switch (message.getType()) {
case ELECTION:
LOGGER.info("Instance " + localId + " - Election Message handling...");
LOGGER.info(INSTANCE + localId + " - Election Message handling...");
handleElectionMessage(message);
break;
case LEADER:
LOGGER.info("Instance " + localId + " - Leader Message handling...");
LOGGER.info(INSTANCE + localId + " - Leader Message handling...");
handleLeaderMessage(message);
break;
case HEARTBEAT:
LOGGER.info("Instance " + localId + " - Heartbeat Message handling...");
LOGGER.info(INSTANCE + localId + " - Heartbeat Message handling...");
handleHeartbeatMessage(message);
break;
case ELECTION_INVOKE:
LOGGER.info("Instance " + localId + " - Election Invoke Message handling...");
LOGGER.info(INSTANCE + localId + " - Election Invoke Message handling...");
handleElectionInvokeMessage();
break;
case LEADER_INVOKE:
LOGGER.info("Instance " + localId + " - Leader Invoke Message handling...");
LOGGER.info(INSTANCE + localId + " - Leader Invoke Message handling...");
handleLeaderInvokeMessage();
break;
case HEARTBEAT_INVOKE:
LOGGER.info("Instance " + localId + " - Heartbeat Invoke Message handling...");
LOGGER.info(INSTANCE + localId + " - Heartbeat Invoke Message handling...");
handleHeartbeatInvokeMessage();
break;
default:

View File

@@ -41,6 +41,7 @@ import org.slf4j.LoggerFactory;
public class BullyInstance extends AbstractInstance {
private static final Logger LOGGER = LoggerFactory.getLogger(BullyInstance.class);
private static final String INSTANCE = "Instance ";
/**
* Constructor of BullyInstance.
@@ -59,20 +60,20 @@ public class BullyInstance extends AbstractInstance {
try {
boolean isLeaderAlive = messageManager.sendHeartbeatMessage(leaderId);
if (isLeaderAlive) {
LOGGER.info("Instance " + localId + "- Leader is alive.");
LOGGER.info(INSTANCE + localId + "- Leader is alive.");
Thread.sleep(HEARTBEAT_INTERVAL);
messageManager.sendHeartbeatInvokeMessage(localId);
} else {
LOGGER.info("Instance " + localId + "- Leader is not alive. Start election.");
LOGGER.info(INSTANCE + localId + "- Leader is not alive. Start election.");
boolean electionResult =
messageManager.sendElectionMessage(localId, String.valueOf(localId));
if (electionResult) {
LOGGER.info("Instance " + localId + "- Succeed in election. Start leader notification.");
LOGGER.info(INSTANCE + localId + "- Succeed in election. Start leader notification.");
messageManager.sendLeaderMessage(localId, localId);
}
}
} catch (InterruptedException e) {
LOGGER.info("Instance " + localId + "- Interrupted.");
LOGGER.info(INSTANCE + localId + "- Interrupted.");
}
}
@@ -84,10 +85,10 @@ public class BullyInstance extends AbstractInstance {
@Override
protected void handleElectionInvokeMessage() {
if (!isLeader()) {
LOGGER.info("Instance " + localId + "- Start election.");
LOGGER.info(INSTANCE + localId + "- Start election.");
boolean electionResult = messageManager.sendElectionMessage(localId, String.valueOf(localId));
if (electionResult) {
LOGGER.info("Instance " + localId + "- Succeed in election. Start leader notification.");
LOGGER.info(INSTANCE + localId + "- Succeed in election. Start leader notification.");
leaderId = localId;
messageManager.sendLeaderMessage(localId, localId);
messageManager.sendHeartbeatInvokeMessage(localId);
@@ -101,25 +102,25 @@ public class BullyInstance extends AbstractInstance {
@Override
protected void handleLeaderMessage(Message message) {
leaderId = Integer.valueOf(message.getContent());
LOGGER.info("Instance " + localId + " - Leader update done.");
LOGGER.info(INSTANCE + localId + " - Leader update done.");
}
private boolean isLeader() {
return localId == leaderId;
}
/**
* Not used in Bully instance.
*/
@Override
protected void handleLeaderInvokeMessage() {
// Not used in Bully Instance
}
@Override
protected void handleHeartbeatMessage(Message message) {
// Not used in Bully Instance
}
@Override
protected void handleElectionMessage(Message message) {
// Not used in Bully Instance
}
}

View File

@@ -46,6 +46,7 @@ import org.slf4j.LoggerFactory;
public class RingInstance extends AbstractInstance {
private static final Logger LOGGER = LoggerFactory.getLogger(RingInstance.class);
private static final String INSTANCE = "Instance ";
/**
* Constructor of RingInstance.
@@ -64,15 +65,15 @@ public class RingInstance extends AbstractInstance {
try {
var isLeaderAlive = messageManager.sendHeartbeatMessage(this.leaderId);
if (isLeaderAlive) {
LOGGER.info("Instance " + localId + "- Leader is alive. Start next heartbeat in 5 second.");
LOGGER.info(INSTANCE + localId + "- Leader is alive. Start next heartbeat in 5 second.");
Thread.sleep(HEARTBEAT_INTERVAL);
messageManager.sendHeartbeatInvokeMessage(this.localId);
} else {
LOGGER.info("Instance " + localId + "- Leader is not alive. Start election.");
LOGGER.info(INSTANCE + localId + "- Leader is not alive. Start election.");
messageManager.sendElectionMessage(this.localId, String.valueOf(this.localId));
}
} catch (InterruptedException e) {
LOGGER.info("Instance " + localId + "- Interrupted.");
LOGGER.info(INSTANCE + localId + "- Interrupted.");
}
}
@@ -85,14 +86,14 @@ public class RingInstance extends AbstractInstance {
@Override
protected void handleElectionMessage(Message message) {
var content = message.getContent();
LOGGER.info("Instance " + localId + " - Election Message: " + content);
LOGGER.info(INSTANCE + localId + " - Election Message: " + content);
var candidateList = Arrays.stream(content.trim().split(","))
.map(Integer::valueOf)
.sorted()
.collect(Collectors.toList());
if (candidateList.contains(localId)) {
var newLeaderId = candidateList.get(0);
LOGGER.info("Instance " + localId + " - New leader should be " + newLeaderId + ".");
LOGGER.info(INSTANCE + localId + " - New leader should be " + newLeaderId + ".");
messageManager.sendLeaderMessage(localId, newLeaderId);
} else {
content += "," + localId;
@@ -108,11 +109,11 @@ public class RingInstance extends AbstractInstance {
protected void handleLeaderMessage(Message message) {
var newLeaderId = Integer.valueOf(message.getContent());
if (this.leaderId != newLeaderId) {
LOGGER.info("Instance " + localId + " - Update leaderID");
LOGGER.info(INSTANCE + localId + " - Update leaderID");
this.leaderId = newLeaderId;
messageManager.sendLeaderMessage(localId, newLeaderId);
} else {
LOGGER.info("Instance " + localId + " - Leader update done. Start heartbeat.");
LOGGER.info(INSTANCE + localId + " - Leader update done. Start heartbeat.");
messageManager.sendHeartbeatInvokeMessage(localId);
}
}
@@ -122,14 +123,17 @@ public class RingInstance extends AbstractInstance {
*/
@Override
protected void handleLeaderInvokeMessage() {
// Not used in Ring instance.
}
@Override
protected void handleHeartbeatMessage(Message message) {
// Not used in Ring instance.
}
@Override
protected void handleElectionInvokeMessage() {
// Not used in Ring instance.
}
}

View File

@@ -25,15 +25,16 @@ package com.iluwatar.leaderelection.bully;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* BullyApp unit test.
*/
public class BullyAppTest {
class BullyAppTest {
@Test
public void test() {
String[] args = {};
BullyApp.main(args);
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> BullyApp.main(new String[]{}));
}
}

View File

@@ -25,15 +25,16 @@ package com.iluwatar.leaderelection.ring;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* RingApp unit test.
*/
public class RingAppTest {
class RingAppTest {
@Test
public void test() {
String[] args = {};
RingApp.main(args);
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> RingApp.main(new String[]{}));
}
}

Some files were not shown because too many files have changed in this diff Show More