diff --git a/hexagonal/README.md b/hexagonal/README.md
new file mode 100644
index 000000000..5e954e90c
--- /dev/null
+++ b/hexagonal/README.md
@@ -0,0 +1,34 @@
+---
+layout: pattern
+title: Hexagonal Architecture
+folder: hexagonal
+permalink: /patterns/hexagonal/
+categories: Architectural
+tags:
+ - Java
+ - Difficulty-Expert
+---
+
+## Also known as
+Ports and Adapters
+Clean Architecture
+Onion Architecture
+
+## Intent
+Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.
+
+
+
+## Applicability
+Use Hexagonal Architecture pattern when
+
+* it is important that the application is fully testable
+* you use Domain Driven Design methodology and/or Microservices architectural style
+
+## Real world examples
+
+* [Apache Isis](https://isis.apache.org/)
+
+## Credits
+
+* [Alistair Cockburn - Hexagonal Architecture](http://alistair.cockburn.us/Hexagonal+architecture)
diff --git a/hexagonal/etc/hexagonal.png b/hexagonal/etc/hexagonal.png
new file mode 100644
index 000000000..8c03d375f
Binary files /dev/null and b/hexagonal/etc/hexagonal.png differ
diff --git a/hexagonal/etc/hexagonal.ucls b/hexagonal/etc/hexagonal.ucls
new file mode 100644
index 000000000..b54e2abf7
--- /dev/null
+++ b/hexagonal/etc/hexagonal.ucls
@@ -0,0 +1,325 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml
new file mode 100644
index 000000000..54f81cf14
--- /dev/null
+++ b/hexagonal/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.12.0-SNAPSHOT
+
+ hexagonal
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java
new file mode 100644
index 000000000..3ae55b706
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java
@@ -0,0 +1,151 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import com.iluwatar.hexagonal.administration.LotteryAdministration;
+import com.iluwatar.hexagonal.administration.LotteryAdministrationImpl;
+import com.iluwatar.hexagonal.banking.WireTransfersImpl;
+import com.iluwatar.hexagonal.domain.LotteryConstants;
+import com.iluwatar.hexagonal.domain.LotteryNumbers;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.PlayerDetails;
+import com.iluwatar.hexagonal.service.LotteryService;
+import com.iluwatar.hexagonal.service.LotteryServiceImpl;
+
+/**
+ *
+ * Hexagonal Architecture pattern decouples the application core from the
+ * services it uses. This allows the services to be plugged in and the
+ * application will run with or without the services.
+ *
+ * The core logic, or business logic, of an application consists of the
+ * algorithms that are essential to its purpose. They implement the use
+ * cases that are the heart of the application. When you change them, you
+ * change the essence of the application.
+ *
+ * The services are not essential. They can be replaced without changing
+ * the purpose of the application. Examples: database access and other
+ * types of storage, user interface components, e-mail and other
+ * communication components, hardware devices.
+ *
+ * This example demonstrates Hexagonal Architecture with a lottery system.
+ * The application core is separate from the services that drive it and
+ * from the services it uses.
+ *
+ * The primary ports for the application are {@link LotteryAdministration}
+ * through which the lottery round is initiated and run and
+ * {@link LotteryService} that allows players to submit lottery tickets for
+ * the draw.
+ *
+ * The secondary ports that application core uses are {@link WireTransfers}
+ * which is a banking service, {@link LotteryNotifications} that delivers
+ * notifications as lottery events occur and {@link LotteryTicketRepository}
+ * that is the storage for the lottery tickets.
+ *
+ */
+public class App {
+
+ private static List allPlayerDetails;
+
+ static {
+ allPlayerDetails = new ArrayList<>();
+ allPlayerDetails.add(PlayerDetails.create("john@google.com", "312-342", "+3242434242"));
+ allPlayerDetails.add(PlayerDetails.create("mary@google.com", "234-987", "+23452346"));
+ allPlayerDetails.add(PlayerDetails.create("steve@google.com", "833-836", "+63457543"));
+ allPlayerDetails.add(PlayerDetails.create("wayne@google.com", "319-826", "+24626"));
+ allPlayerDetails.add(PlayerDetails.create("johnie@google.com", "983-322", "+3635635"));
+ allPlayerDetails.add(PlayerDetails.create("andy@google.com", "934-734", "+0898245"));
+ allPlayerDetails.add(PlayerDetails.create("richard@google.com", "536-738", "+09845325"));
+ allPlayerDetails.add(PlayerDetails.create("kevin@google.com", "453-936", "+2423532"));
+ allPlayerDetails.add(PlayerDetails.create("arnold@google.com", "114-988", "+5646346524"));
+ allPlayerDetails.add(PlayerDetails.create("ian@google.com", "663-765", "+928394235"));
+ allPlayerDetails.add(PlayerDetails.create("robin@google.com", "334-763", "+35448"));
+ allPlayerDetails.add(PlayerDetails.create("ted@google.com", "735-964", "+98752345"));
+ allPlayerDetails.add(PlayerDetails.create("larry@google.com", "734-853", "+043842423"));
+ allPlayerDetails.add(PlayerDetails.create("calvin@google.com", "334-746", "+73294135"));
+ allPlayerDetails.add(PlayerDetails.create("jacob@google.com", "444-766", "+358042354"));
+ allPlayerDetails.add(PlayerDetails.create("edwin@google.com", "895-345", "+9752435"));
+ allPlayerDetails.add(PlayerDetails.create("mary@google.com", "760-009", "+34203542"));
+ allPlayerDetails.add(PlayerDetails.create("lolita@google.com", "425-907", "+9872342"));
+ allPlayerDetails.add(PlayerDetails.create("bruno@google.com", "023-638", "+673824122"));
+ allPlayerDetails.add(PlayerDetails.create("peter@google.com", "335-886", "+5432503945"));
+ allPlayerDetails.add(PlayerDetails.create("warren@google.com", "225-946", "+9872341324"));
+ allPlayerDetails.add(PlayerDetails.create("monica@google.com", "265-748", "+134124"));
+ allPlayerDetails.add(PlayerDetails.create("ollie@google.com", "190-045", "+34453452"));
+ allPlayerDetails.add(PlayerDetails.create("yngwie@google.com", "241-465", "+9897641231"));
+ allPlayerDetails.add(PlayerDetails.create("lars@google.com", "746-936", "+42345298345"));
+ allPlayerDetails.add(PlayerDetails.create("bobbie@google.com", "946-384", "+79831742"));
+ allPlayerDetails.add(PlayerDetails.create("tyron@google.com", "310-992", "+0498837412"));
+ allPlayerDetails.add(PlayerDetails.create("tyrell@google.com", "032-045", "+67834134"));
+ allPlayerDetails.add(PlayerDetails.create("nadja@google.com", "000-346", "+498723"));
+ allPlayerDetails.add(PlayerDetails.create("wendy@google.com", "994-989", "+987324454"));
+ allPlayerDetails.add(PlayerDetails.create("luke@google.com", "546-634", "+987642435"));
+ allPlayerDetails.add(PlayerDetails.create("bjorn@google.com", "342-874", "+7834325"));
+ allPlayerDetails.add(PlayerDetails.create("lisa@google.com", "024-653", "+980742154"));
+ allPlayerDetails.add(PlayerDetails.create("anton@google.com", "834-935", "+876423145"));
+ allPlayerDetails.add(PlayerDetails.create("bruce@google.com", "284-936", "+09843212345"));
+ allPlayerDetails.add(PlayerDetails.create("ray@google.com", "843-073", "+678324123"));
+ allPlayerDetails.add(PlayerDetails.create("ron@google.com", "637-738", "+09842354"));
+ allPlayerDetails.add(PlayerDetails.create("xavier@google.com", "143-947", "+375245"));
+ allPlayerDetails.add(PlayerDetails.create("harriet@google.com", "842-404", "+131243252"));
+ WireTransfersImpl wireTransfers = new WireTransfersImpl();
+ Random random = new Random();
+ for (int i = 0; i < allPlayerDetails.size(); i++) {
+ wireTransfers.setFunds(allPlayerDetails.get(i).getBankAccount(),
+ random.nextInt(LotteryConstants.PLAYER_MAX_SALDO));
+ }
+ }
+
+ /**
+ * Program entry point
+ */
+ public static void main(String[] args) {
+ // start new lottery round
+ LotteryAdministration administartion = new LotteryAdministrationImpl();
+ administartion.resetLottery();
+
+ // submit some lottery tickets
+ LotteryServiceImpl service = new LotteryServiceImpl();
+ submitTickets(service, 20);
+
+ // perform lottery
+ administartion.performLottery();
+ }
+
+ private static void submitTickets(LotteryService lotteryService, int numTickets) {
+ for (int i = 0; i < numTickets; i++) {
+ LotteryTicket ticket = LotteryTicket.create(getRandomPlayerDetails(), LotteryNumbers.createRandom());
+ lotteryService.submitTicket(ticket);
+ }
+ }
+
+ private static PlayerDetails getRandomPlayerDetails() {
+ Random random = new Random();
+ int idx = random.nextInt(allPlayerDetails.size());
+ return allPlayerDetails.get(idx);
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java
new file mode 100644
index 000000000..bc625b230
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java
@@ -0,0 +1,53 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.administration;
+
+import java.util.Map;
+
+import com.iluwatar.hexagonal.domain.LotteryNumbers;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+
+/**
+ *
+ * Administrator interface for lottery service.
+ *
+ */
+public interface LotteryAdministration {
+
+ /**
+ * Get all the lottery tickets submitted for lottery
+ */
+ Map getAllSubmittedTickets();
+
+ /**
+ * Draw lottery numbers
+ */
+ LotteryNumbers performLottery();
+
+ /**
+ * Begin new lottery round
+ */
+ void resetLottery();
+
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministrationImpl.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministrationImpl.java
new file mode 100644
index 000000000..a452600aa
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministrationImpl.java
@@ -0,0 +1,87 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.administration;
+
+import java.util.Map;
+
+import com.iluwatar.hexagonal.banking.WireTransfers;
+import com.iluwatar.hexagonal.banking.WireTransfersImpl;
+import com.iluwatar.hexagonal.database.LotteryTicketRepository;
+import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
+import com.iluwatar.hexagonal.domain.LotteryConstants;
+import com.iluwatar.hexagonal.domain.LotteryNumbers;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+import com.iluwatar.hexagonal.notifications.LotteryNotifications;
+import com.iluwatar.hexagonal.notifications.LotteryNotificationsImpl;
+import com.iluwatar.hexagonal.service.LotteryService;
+import com.iluwatar.hexagonal.service.LotteryServiceImpl;
+
+/**
+ *
+ * Lottery administration implementation
+ *
+ */
+public class LotteryAdministrationImpl implements LotteryAdministration {
+
+ private final LotteryTicketRepository repository;
+ private final LotteryService service = new LotteryServiceImpl();
+ private final LotteryNotifications notifications = new LotteryNotificationsImpl();
+ private final WireTransfers bank = new WireTransfersImpl();
+ public LotteryAdministrationImpl() {
+ repository = new LotteryTicketInMemoryRepository();
+ }
+
+ @Override
+ public Map getAllSubmittedTickets() {
+ return repository.findAll();
+ }
+
+ @Override
+ public LotteryNumbers performLottery() {
+ LotteryNumbers numbers = LotteryNumbers.createRandom();
+ Map tickets = getAllSubmittedTickets();
+ for (LotteryTicketId id: tickets.keySet()) {
+ LotteryTicketCheckResult result = service.checkTicketForPrize(id, numbers);
+ if (result.getResult().equals(CheckResult.WIN_PRIZE)) {
+ boolean transferred = bank.transferFunds(LotteryConstants.PRIZE_AMOUNT, LotteryConstants.SERVICE_BANK_ACCOUNT,
+ tickets.get(id).getPlayerDetails().getBankAccount());
+ if (transferred) {
+ notifications.notifyPrize(tickets.get(id).getPlayerDetails(), LotteryConstants.PRIZE_AMOUNT);
+ } else {
+ notifications.notifyPrizeError(tickets.get(id).getPlayerDetails(), LotteryConstants.PRIZE_AMOUNT);
+ }
+ } else if (result.getResult().equals(CheckResult.NO_PRIZE)) {
+ notifications.notifyNoWin(tickets.get(id).getPlayerDetails());
+ }
+ }
+ return numbers;
+ }
+
+ @Override
+ public void resetLottery() {
+ repository.deleteAll();
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfers.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfers.java
new file mode 100644
index 000000000..7d21e7bf3
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfers.java
@@ -0,0 +1,47 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.banking;
+
+/**
+ *
+ * Interface to bank accounts.
+ *
+ */
+public interface WireTransfers {
+
+ /**
+ * Set amount of funds for bank account
+ */
+ void setFunds(String bankAccount, int amount);
+
+ /**
+ * Get amount of funds for bank account
+ */
+ int getFunds(String bankAccount);
+
+ /**
+ * Transfer funds from one bank account to another
+ */
+ boolean transferFunds(int amount, String sourceBackAccount, String destinationBankAccount);
+
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfersImpl.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfersImpl.java
new file mode 100644
index 000000000..19c1bb1c0
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfersImpl.java
@@ -0,0 +1,63 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.banking;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.iluwatar.hexagonal.domain.LotteryConstants;
+
+/**
+ *
+ * Banking implementation
+ *
+ */
+public class WireTransfersImpl implements WireTransfers {
+
+ private static Map accounts = new HashMap<>();
+
+ static {
+ accounts.put(LotteryConstants.SERVICE_BANK_ACCOUNT, LotteryConstants.SERVICE_BANK_ACCOUNT_SALDO);
+ }
+
+ @Override
+ public void setFunds(String bankAccount, int amount) {
+ accounts.put(bankAccount, amount);
+ }
+
+ @Override
+ public int getFunds(String bankAccount) {
+ return accounts.getOrDefault(bankAccount, 0);
+ }
+
+ @Override
+ public boolean transferFunds(int amount, String sourceBackAccount, String destinationBankAccount) {
+ if (accounts.getOrDefault(sourceBackAccount, 0) >= amount) {
+ accounts.put(sourceBackAccount, accounts.get(sourceBackAccount) - amount);
+ accounts.put(destinationBankAccount, accounts.get(destinationBankAccount) + amount);
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketInMemoryRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketInMemoryRepository.java
new file mode 100644
index 000000000..fe17d8cdf
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketInMemoryRepository.java
@@ -0,0 +1,67 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.database;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+
+/**
+ *
+ * Mock database for lottery tickets.
+ *
+ */
+public class LotteryTicketInMemoryRepository implements LotteryTicketRepository {
+
+ private static Map tickets = new HashMap<>();
+
+ @Override
+ public Optional findById(LotteryTicketId id) {
+ LotteryTicket ticket = tickets.get(id);
+ if (ticket == null) {
+ return Optional.empty();
+ } else {
+ return Optional.of(ticket);
+ }
+ }
+
+ @Override
+ public Optional save(LotteryTicket ticket) {
+ LotteryTicketId id = new LotteryTicketId();
+ tickets.put(id, ticket);
+ return Optional.of(id);
+ }
+
+ @Override
+ public Map findAll() {
+ return tickets;
+ }
+
+ @Override
+ public void deleteAll() {
+ tickets.clear();
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketRepository.java
new file mode 100644
index 000000000..4c6522838
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketRepository.java
@@ -0,0 +1,58 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.database;
+
+import java.util.Map;
+import java.util.Optional;
+
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+
+/**
+ *
+ * Interface for accessing lottery tickets in database.
+ *
+ */
+public interface LotteryTicketRepository {
+
+ /**
+ * Find lottery ticket by id
+ */
+ Optional findById(LotteryTicketId id);
+
+ /**
+ * Save lottery ticket
+ */
+ Optional save(LotteryTicket ticket);
+
+ /**
+ * Get all lottery tickets
+ */
+ Map findAll();
+
+ /**
+ * Delete all lottery tickets
+ */
+ void deleteAll();
+
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java
new file mode 100644
index 000000000..fb4c8025f
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java
@@ -0,0 +1,38 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+/**
+ *
+ * Lottery domain constants
+ *
+ */
+public class LotteryConstants {
+
+ public static final int PRIZE_AMOUNT = 100000;
+ public static final String SERVICE_BANK_ACCOUNT = "123-123";
+ public static final int TICKET_PRIZE = 3;
+ public static final int SERVICE_BANK_ACCOUNT_SALDO = 150000;
+ public static final int PLAYER_MAX_SALDO = 100;
+
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java
new file mode 100644
index 000000000..6f54e743b
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java
@@ -0,0 +1,152 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.PrimitiveIterator;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ *
+ * Value object representing lottery numbers. This lottery uses sets of 4 numbers. The numbers must be unique and
+ * between 1 and 20.
+ *
+ */
+public class LotteryNumbers {
+
+ private final Set numbers;
+
+ public static final int MIN_NUMBER = 1;
+ public static final int MAX_NUMBER = 20;
+ public static final int NUM_NUMBERS = 4;
+
+ /**
+ * Constructor. Creates random lottery numbers.
+ */
+ private LotteryNumbers() {
+ numbers = new HashSet<>();
+ generateRandomNumbers();
+ }
+
+ /**
+ * Constructor. Uses given numbers.
+ */
+ private LotteryNumbers(Set givenNumbers) {
+ numbers = new HashSet<>();
+ numbers.addAll(givenNumbers);
+ }
+
+ /**
+ * @return random LotteryNumbers
+ */
+ public static LotteryNumbers createRandom() {
+ return new LotteryNumbers();
+ }
+
+ /**
+ * @return given LotteryNumbers
+ */
+ public static LotteryNumbers create(Set givenNumbers) {
+ return new LotteryNumbers(givenNumbers);
+ }
+
+ /**
+ * @return lottery numbers
+ */
+ public Set getNumbers() {
+ return Collections.unmodifiableSet(numbers);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((numbers == null) ? 0 : numbers.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ LotteryNumbers other = (LotteryNumbers) obj;
+ if (numbers == null) {
+ if (other.numbers != null) {
+ return false;
+ }
+ } else if (!numbers.equals(other.numbers)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Generates 4 unique random numbers between 1-20 into numbers set.
+ */
+ private void generateRandomNumbers() {
+ numbers.clear();
+ RandomNumberGenerator generator = new RandomNumberGenerator(MIN_NUMBER, MAX_NUMBER);
+ while (numbers.size() < NUM_NUMBERS) {
+ int num = generator.nextInt();
+ if (!numbers.contains(num)) {
+ numbers.add(num);
+ }
+ }
+ }
+
+ /**
+ *
+ * Helper class for generating random numbers.
+ *
+ */
+ private static class RandomNumberGenerator {
+
+ private PrimitiveIterator.OfInt randomIterator;
+
+ /**
+ * Initialize a new random number generator that generates random numbers in the range [min, max]
+ *
+ * @param min the min value (inclusive)
+ * @param max the max value (inclusive)
+ */
+ public RandomNumberGenerator(int min, int max) {
+ randomIterator = new Random().ints(min, max + 1).iterator();
+ }
+
+ /**
+ * @return a random number in the range (min, max)
+ */
+ public int nextInt() {
+ return randomIterator.nextInt();
+ }
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java
new file mode 100644
index 000000000..e5828cfbf
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java
@@ -0,0 +1,101 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+/**
+ *
+ * Immutable value object representing lottery ticket.
+ *
+ */
+public class LotteryTicket {
+
+ private final PlayerDetails playerDetails;
+ private final LotteryNumbers lotteryNumbers;
+
+ /**
+ * Constructor.
+ */
+ private LotteryTicket(PlayerDetails details, LotteryNumbers numbers) {
+ playerDetails = details;
+ lotteryNumbers = numbers;
+ }
+
+ /**
+ * Factory for creating lottery tickets;
+ */
+ public static LotteryTicket create(PlayerDetails details, LotteryNumbers numbers) {
+ return new LotteryTicket(details, numbers);
+ }
+
+ /**
+ * @return player details
+ */
+ public PlayerDetails getPlayerDetails() {
+ return playerDetails;
+ }
+
+ /**
+ * @return lottery numbers
+ */
+ public LotteryNumbers getNumbers() {
+ return lotteryNumbers;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((lotteryNumbers == null) ? 0 : lotteryNumbers.hashCode());
+ result = prime * result + ((playerDetails == null) ? 0 : playerDetails.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ LotteryTicket other = (LotteryTicket) obj;
+ if (lotteryNumbers == null) {
+ if (other.lotteryNumbers != null) {
+ return false;
+ }
+ } else if (!lotteryNumbers.equals(other.lotteryNumbers)) {
+ return false;
+ }
+ if (playerDetails == null) {
+ if (other.playerDetails != null) {
+ return false;
+ }
+ } else if (!playerDetails.equals(other.playerDetails)) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResult.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResult.java
new file mode 100644
index 000000000..ded65d270
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResult.java
@@ -0,0 +1,96 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+/**
+ *
+ * Represents lottery ticket check result.
+ *
+ */
+public class LotteryTicketCheckResult {
+
+ public enum CheckResult { WIN_PRIZE, NO_PRIZE, TICKET_NOT_SUBMITTED };
+
+ private final CheckResult checkResult;
+ private final int prizeAmount;
+
+ /**
+ * Constructor.
+ */
+ public LotteryTicketCheckResult(CheckResult result) {
+ checkResult = result;
+ prizeAmount = 0;
+ }
+
+ /**
+ * Constructor.
+ */
+ public LotteryTicketCheckResult(CheckResult result, int amount) {
+ checkResult = result;
+ prizeAmount = amount;
+ }
+
+ /**
+ * @return check result
+ */
+ public CheckResult getResult() {
+ return checkResult;
+ }
+
+ /**
+ * @return prize amount
+ */
+ public int getPrizeAmount() {
+ return prizeAmount;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((checkResult == null) ? 0 : checkResult.hashCode());
+ result = prime * result + prizeAmount;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ LotteryTicketCheckResult other = (LotteryTicketCheckResult) obj;
+ if (checkResult != other.checkResult) {
+ return false;
+ }
+ if (prizeAmount != other.prizeAmount) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java
new file mode 100644
index 000000000..710091222
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java
@@ -0,0 +1,41 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+import java.util.UUID;
+
+/**
+ * Lottery ticked id
+ */
+public class LotteryTicketId {
+
+ private final UUID id;
+
+ public LotteryTicketId() {
+ id = UUID.randomUUID();
+ }
+
+ public UUID getId() {
+ return id;
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java
new file mode 100644
index 000000000..2fcdb6eb3
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java
@@ -0,0 +1,118 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+/**
+ *
+ * Immutable value object containing lottery player details.
+ *
+ */
+public class PlayerDetails {
+
+ private final String emailAddress;
+ private final String bankAccountNumber;
+ private final String phoneNumber;
+
+ /**
+ * Constructor.
+ */
+ private PlayerDetails(String email, String bankAccount, String phone) {
+ emailAddress = email;
+ bankAccountNumber = bankAccount;
+ phoneNumber = phone;
+ }
+
+ /**
+ * Factory for creating new objects.
+ */
+ public static PlayerDetails create(String email, String bankAccount, String phone) {
+ return new PlayerDetails(email, bankAccount, phone);
+ }
+
+ /**
+ * @return email
+ */
+ public String getEmail() {
+ return emailAddress;
+ }
+
+ /**
+ * @return bank account number
+ */
+ public String getBankAccount() {
+ return bankAccountNumber;
+ }
+
+ /**
+ * @return phone number
+ */
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((bankAccountNumber == null) ? 0 : bankAccountNumber.hashCode());
+ result = prime * result + ((emailAddress == null) ? 0 : emailAddress.hashCode());
+ result = prime * result + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ PlayerDetails other = (PlayerDetails) obj;
+ if (bankAccountNumber == null) {
+ if (other.bankAccountNumber != null) {
+ return false;
+ }
+ } else if (!bankAccountNumber.equals(other.bankAccountNumber)) {
+ return false;
+ }
+ if (emailAddress == null) {
+ if (other.emailAddress != null) {
+ return false;
+ }
+ } else if (!emailAddress.equals(other.emailAddress)) {
+ return false;
+ }
+ if (phoneNumber == null) {
+ if (other.phoneNumber != null) {
+ return false;
+ }
+ } else if (!phoneNumber.equals(other.phoneNumber)) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotifications.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotifications.java
new file mode 100644
index 000000000..d7a0cc870
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotifications.java
@@ -0,0 +1,59 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.notifications;
+
+import com.iluwatar.hexagonal.domain.PlayerDetails;
+
+/**
+ *
+ * Provides notifications for lottery events.
+ *
+ */
+public interface LotteryNotifications {
+
+ /**
+ * Notify lottery ticket was submitted
+ */
+ void notifyTicketSubmitted(PlayerDetails details);
+
+ /**
+ * Notify there was an error submitting lottery ticket
+ */
+ void notifyTicketSubmitError(PlayerDetails details);
+
+ /**
+ * Notify lottery ticket did not win
+ */
+ void notifyNoWin(PlayerDetails details);
+
+ /**
+ * Notify that prize has been paid
+ */
+ void notifyPrize(PlayerDetails details, int prizeAmount);
+
+ /**
+ * Notify that there was an error paying the prize
+ */
+ void notifyPrizeError(PlayerDetails details, int prizeAmount);
+
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotificationsImpl.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotificationsImpl.java
new file mode 100644
index 000000000..c59a47970
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotificationsImpl.java
@@ -0,0 +1,61 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.notifications;
+
+import com.iluwatar.hexagonal.domain.PlayerDetails;
+
+public class LotteryNotificationsImpl implements LotteryNotifications {
+
+ @Override
+ public void notifyTicketSubmitted(PlayerDetails details) {
+ System.out.println(String.format("Lottery ticket for %s was submitted. Bank account %s was charged for 3 credits.",
+ details.getEmail(), details.getBankAccount()));
+ }
+
+ @Override
+ public void notifyNoWin(PlayerDetails details) {
+ System.out.println(String.format("Lottery ticket for %s was checked and unfortunately did not win this time.",
+ details.getEmail()));
+ }
+
+ @Override
+ public void notifyPrize(PlayerDetails details, int prizeAmount) {
+ System.out
+ .println(String.format("Lottery ticket for %s has won! The bank account %s was deposited with %d credits.",
+ details.getEmail(), details.getBankAccount(), prizeAmount));
+ }
+
+ @Override
+ public void notifyPrizeError(PlayerDetails details, int prizeAmount) {
+ System.out
+ .println(String.format("Lottery ticket for %s has won! Unfortunately the bank credit transfer of %d failed.",
+ details.getEmail(), prizeAmount));
+ }
+
+ @Override
+ public void notifyTicketSubmitError(PlayerDetails details) {
+ System.out.println(
+ String.format("Lottery ticket for %s could not be submitted because the credit transfer of 3 credits failed.",
+ details.getEmail()));
+ }
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryService.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryService.java
new file mode 100644
index 000000000..0056e794b
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryService.java
@@ -0,0 +1,48 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.service;
+
+import java.util.Optional;
+
+import com.iluwatar.hexagonal.domain.LotteryNumbers;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+
+/**
+ *
+ * Interface for submitting and checking lottery tickets.
+ *
+ */
+public interface LotteryService {
+
+ /**
+ * Submit lottery ticket to participate in the lottery
+ */
+ Optional submitTicket(LotteryTicket ticket);
+
+ /**
+ * Check if lottery ticket has won
+ */
+ LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers);
+}
diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryServiceImpl.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryServiceImpl.java
new file mode 100644
index 000000000..58df1c7c8
--- /dev/null
+++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryServiceImpl.java
@@ -0,0 +1,88 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.service;
+
+import java.util.Optional;
+
+import com.iluwatar.hexagonal.banking.WireTransfers;
+import com.iluwatar.hexagonal.banking.WireTransfersImpl;
+import com.iluwatar.hexagonal.database.LotteryTicketRepository;
+import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
+import com.iluwatar.hexagonal.domain.LotteryConstants;
+import com.iluwatar.hexagonal.domain.LotteryNumbers;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
+import com.iluwatar.hexagonal.notifications.LotteryNotifications;
+import com.iluwatar.hexagonal.notifications.LotteryNotificationsImpl;
+
+/**
+ *
+ * Implementation for lottery service
+ *
+ */
+public class LotteryServiceImpl implements LotteryService {
+
+ private final LotteryTicketRepository repository;
+
+ private final WireTransfers bank = new WireTransfersImpl();
+
+ private final LotteryNotifications notifications = new LotteryNotificationsImpl();
+
+ /**
+ * Constructor
+ */
+ public LotteryServiceImpl() {
+ repository = new LotteryTicketInMemoryRepository();
+ }
+
+ @Override
+ public Optional submitTicket(LotteryTicket ticket) {
+ boolean result = bank.transferFunds(LotteryConstants.TICKET_PRIZE, ticket.getPlayerDetails().getBankAccount(),
+ LotteryConstants.SERVICE_BANK_ACCOUNT);
+ if (result == false) {
+ notifications.notifyTicketSubmitError(ticket.getPlayerDetails());
+ return Optional.empty();
+ }
+ Optional optional = repository.save(ticket);
+ if (optional.isPresent()) {
+ notifications.notifyTicketSubmitted(ticket.getPlayerDetails());
+ }
+ return optional;
+ }
+
+ @Override
+ public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) {
+ Optional optional = repository.findById(id);
+ if (optional.isPresent()) {
+ if (optional.get().getNumbers().equals(winningNumbers)) {
+ return new LotteryTicketCheckResult(CheckResult.WIN_PRIZE, 1000);
+ } else {
+ return new LotteryTicketCheckResult(CheckResult.NO_PRIZE);
+ }
+ } else {
+ return new LotteryTicketCheckResult(CheckResult.TICKET_NOT_SUBMITTED);
+ }
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/AppTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/AppTest.java
new file mode 100644
index 000000000..8e19cca35
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/AppTest.java
@@ -0,0 +1,37 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal;
+
+import org.junit.Test;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest {
+
+ @Test
+ public void testApp() {
+ String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java
new file mode 100644
index 000000000..0274feca3
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java
@@ -0,0 +1,50 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.banking;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ *
+ * Tests for banking
+ *
+ */
+public class WireTransfersTest {
+
+ private final WireTransfers bank = new WireTransfersImpl();
+
+ @Test
+ public void testInit() {
+ assertEquals(bank.getFunds("foo"), 0);
+ bank.setFunds("foo", 100);
+ assertEquals(bank.getFunds("foo"), 100);
+ bank.setFunds("bar", 150);
+ assertEquals(bank.getFunds("bar"), 150);
+ assertTrue(bank.transferFunds(50, "bar", "foo"));
+ assertEquals(bank.getFunds("foo"), 150);
+ assertEquals(bank.getFunds("bar"), 100);
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/LotteryTicketRepositoryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/LotteryTicketRepositoryTest.java
new file mode 100644
index 000000000..b20e928c8
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/LotteryTicketRepositoryTest.java
@@ -0,0 +1,64 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Optional;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.iluwatar.hexagonal.database.LotteryTicketRepository;
+import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+import com.iluwatar.hexagonal.test.LotteryTestUtils;
+
+/**
+ *
+ * Tests for {@link LotteryTicketRepository}
+ *
+ */
+public class LotteryTicketRepositoryTest {
+
+ private final LotteryTicketRepository repository = new LotteryTicketInMemoryRepository();
+
+ @Before
+ public void clear() {
+ repository.deleteAll();
+ }
+
+ @Test
+ public void testCrudOperations() {
+ LotteryTicketRepository repository = new LotteryTicketInMemoryRepository();
+ assertEquals(repository.findAll().size(), 0);
+ LotteryTicket ticket = LotteryTestUtils.createLotteryTicket();
+ Optional id = repository.save(ticket);
+ assertTrue(id.isPresent());
+ assertEquals(repository.findAll().size(), 1);
+ Optional optionalTicket = repository.findById(id.get());
+ assertTrue(optionalTicket.isPresent());
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryNumbersTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryNumbersTest.java
new file mode 100644
index 000000000..4f2751167
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryNumbersTest.java
@@ -0,0 +1,76 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.junit.Test;
+
+/**
+ *
+ * Unit tests for {@link LotteryNumbers}
+ *
+ */
+public class LotteryNumbersTest {
+
+ @Test
+ public void testGivenNumbers() {
+ LotteryNumbers numbers = LotteryNumbers.create(
+ new HashSet<>(Arrays.asList(1, 2, 3, 4)));
+ assertEquals(numbers.getNumbers().size(), 4);
+ assertTrue(numbers.getNumbers().contains(1));
+ assertTrue(numbers.getNumbers().contains(2));
+ assertTrue(numbers.getNumbers().contains(3));
+ assertTrue(numbers.getNumbers().contains(4));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testNumbersCantBeModified() {
+ LotteryNumbers numbers = LotteryNumbers.create(
+ new HashSet<>(Arrays.asList(1, 2, 3, 4)));
+ numbers.getNumbers().add(5);
+ }
+
+ @Test
+ public void testRandomNumbers() {
+ LotteryNumbers numbers = LotteryNumbers.createRandom();
+ assertEquals(numbers.getNumbers().size(), LotteryNumbers.NUM_NUMBERS);
+ }
+
+ @Test
+ public void testEquals() {
+ LotteryNumbers numbers1 = LotteryNumbers.create(
+ new HashSet<>(Arrays.asList(1, 2, 3, 4)));
+ LotteryNumbers numbers2 = LotteryNumbers.create(
+ new HashSet<>(Arrays.asList(1, 2, 3, 4)));
+ assertTrue(numbers1.equals(numbers2));
+ LotteryNumbers numbers3 = LotteryNumbers.create(
+ new HashSet<>(Arrays.asList(11, 12, 13, 14)));
+ assertFalse(numbers1.equals(numbers3));
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResultTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResultTest.java
new file mode 100644
index 000000000..237ab85d3
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResultTest.java
@@ -0,0 +1,47 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
+
+/**
+ *
+ * Unit tests for {@link LotteryTicketCheckResult}
+ *
+ */
+public class LotteryTicketCheckResultTest {
+
+ @Test
+ public void testEquals() {
+ LotteryTicketCheckResult result1 = new LotteryTicketCheckResult(CheckResult.NO_PRIZE);
+ LotteryTicketCheckResult result2 = new LotteryTicketCheckResult(CheckResult.NO_PRIZE);
+ assertEquals(result1, result2);
+ LotteryTicketCheckResult result3 = new LotteryTicketCheckResult(CheckResult.WIN_PRIZE, 300000);
+ assertFalse(result1.equals(result3));
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketTest.java
new file mode 100644
index 000000000..e1918686a
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketTest.java
@@ -0,0 +1,49 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.junit.Test;
+
+public class LotteryTicketTest {
+
+ @Test
+ public void testEquals() {
+ PlayerDetails details1 = PlayerDetails.create("bob@foo.bar", "1212-121212", "+34332322");
+ LotteryNumbers numbers1 = LotteryNumbers.create(new HashSet(Arrays.asList(1, 2, 3, 4)));
+ LotteryTicket ticket1 = LotteryTicket.create(details1, numbers1);
+ PlayerDetails details2 = PlayerDetails.create("bob@foo.bar", "1212-121212", "+34332322");
+ LotteryNumbers numbers2 = LotteryNumbers.create(new HashSet(Arrays.asList(1, 2, 3, 4)));
+ LotteryTicket ticket2 = LotteryTicket.create(details2, numbers2);
+ assertEquals(ticket1, ticket2);
+ PlayerDetails details3 = PlayerDetails.create("elsa@foo.bar", "1223-121212", "+49332322");
+ LotteryNumbers numbers3 = LotteryNumbers.create(new HashSet(Arrays.asList(1, 2, 3, 8)));
+ LotteryTicket ticket3 = LotteryTicket.create(details3, numbers3);
+ assertFalse(ticket1.equals(ticket3));
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/PlayerDetailsTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/PlayerDetailsTest.java
new file mode 100644
index 000000000..813b035a2
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/PlayerDetailsTest.java
@@ -0,0 +1,45 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.domain;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+
+/**
+ *
+ * Unit tests for {@link PlayerDetails}
+ *
+ */
+public class PlayerDetailsTest {
+
+ @Test
+ public void testEquals() {
+ PlayerDetails details1 = PlayerDetails.create("tom@foo.bar", "11212-123434", "+12323425");
+ PlayerDetails details2 = PlayerDetails.create("tom@foo.bar", "11212-123434", "+12323425");
+ assertEquals(details1, details2);
+ PlayerDetails details3 = PlayerDetails.create("john@foo.bar", "16412-123439", "+34323432");
+ assertFalse(details1.equals(details3));
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/lottery/LotteryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/lottery/LotteryTest.java
new file mode 100644
index 000000000..27e5bb6e4
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/lottery/LotteryTest.java
@@ -0,0 +1,116 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.lottery;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.iluwatar.hexagonal.administration.LotteryAdministration;
+import com.iluwatar.hexagonal.administration.LotteryAdministrationImpl;
+import com.iluwatar.hexagonal.banking.WireTransfers;
+import com.iluwatar.hexagonal.banking.WireTransfersImpl;
+import com.iluwatar.hexagonal.database.LotteryTicketRepository;
+import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
+import com.iluwatar.hexagonal.domain.LotteryNumbers;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
+import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
+import com.iluwatar.hexagonal.domain.LotteryTicketId;
+import com.iluwatar.hexagonal.service.LotteryService;
+import com.iluwatar.hexagonal.service.LotteryServiceImpl;
+import com.iluwatar.hexagonal.test.LotteryTestUtils;
+
+/**
+ *
+ * Test the lottery system
+ *
+ */
+public class LotteryTest {
+
+ private final LotteryAdministration admin = new LotteryAdministrationImpl();
+ private final LotteryService service = new LotteryServiceImpl();
+ private final LotteryTicketRepository repository = new LotteryTicketInMemoryRepository();
+ private final WireTransfers wireTransfers = new WireTransfersImpl();
+
+ @Before
+ public void clear() {
+ repository.deleteAll();
+ }
+
+ @Test
+ public void testLottery() {
+
+ // setup bank account with funds
+ wireTransfers.setFunds("123-12312", 100);
+
+ // admin resets the lottery
+ admin.resetLottery();
+ assertEquals(admin.getAllSubmittedTickets().size(), 0);
+
+ // players submit the lottery tickets
+ Optional ticket1 = service.submitTicket(LotteryTestUtils.createLotteryTicket("cvt@bbb.com",
+ "123-12312", "+32425255", new HashSet<>(Arrays.asList(1, 2, 3, 4))));
+ assertTrue(ticket1.isPresent());
+ Optional ticket2 = service.submitTicket(LotteryTestUtils.createLotteryTicket("ant@bac.com",
+ "123-12312", "+32423455", new HashSet<>(Arrays.asList(11, 12, 13, 14))));
+ assertTrue(ticket2.isPresent());
+ Optional ticket3 = service.submitTicket(LotteryTestUtils.createLotteryTicket("arg@boo.com",
+ "123-12312", "+32421255", new HashSet<>(Arrays.asList(6, 8, 13, 19))));
+ assertTrue(ticket3.isPresent());
+ assertEquals(admin.getAllSubmittedTickets().size(), 3);
+
+ // perform lottery
+ LotteryNumbers winningNumbers = admin.performLottery();
+
+ // cheat a bit for testing sake, use winning numbers to submit another ticket
+ Optional ticket4 = service.submitTicket(LotteryTestUtils.createLotteryTicket("lucky@orb.com",
+ "123-12312", "+12421255", winningNumbers.getNumbers()));
+ assertTrue(ticket4.isPresent());
+ assertEquals(admin.getAllSubmittedTickets().size(), 4);
+
+ // check winners
+ Map tickets = admin.getAllSubmittedTickets();
+ for (LotteryTicketId id: tickets.keySet()) {
+ LotteryTicketCheckResult checkResult = service.checkTicketForPrize(id, winningNumbers);
+ assertTrue(checkResult.getResult() != CheckResult.TICKET_NOT_SUBMITTED);
+ if (checkResult.getResult().equals(CheckResult.WIN_PRIZE)) {
+ assertTrue(checkResult.getPrizeAmount() > 0);
+ } else if (checkResult.getResult().equals(CheckResult.WIN_PRIZE)) {
+ assertEquals(checkResult.getPrizeAmount(), 0);
+ }
+ }
+
+ // check another ticket that has not been submitted
+ LotteryTicketCheckResult checkResult = service.checkTicketForPrize(new LotteryTicketId(), winningNumbers);
+ assertTrue(checkResult.getResult() == CheckResult.TICKET_NOT_SUBMITTED);
+ assertEquals(checkResult.getPrizeAmount(), 0);
+ }
+}
diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/test/LotteryTestUtils.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/test/LotteryTestUtils.java
new file mode 100644
index 000000000..883c8127f
--- /dev/null
+++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/test/LotteryTestUtils.java
@@ -0,0 +1,56 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 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.hexagonal.test;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.iluwatar.hexagonal.domain.LotteryNumbers;
+import com.iluwatar.hexagonal.domain.LotteryTicket;
+import com.iluwatar.hexagonal.domain.PlayerDetails;
+
+/**
+ *
+ * Utilities for lottery tests
+ *
+ */
+public class LotteryTestUtils {
+
+ /**
+ * @return lottery ticket
+ */
+ public static LotteryTicket createLotteryTicket() {
+ return createLotteryTicket("foo@bar.com", "12231-213132", "+99324554", new HashSet<>(Arrays.asList(1, 2, 3, 4)));
+ }
+
+ /**
+ * @return lottery ticket
+ */
+ public static LotteryTicket createLotteryTicket(String email, String account, String phone,
+ Set givenNumbers) {
+ PlayerDetails details = PlayerDetails.create(email, account, phone);
+ LotteryNumbers numbers = LotteryNumbers.create(givenNumbers);
+ return LotteryTicket.create(details, numbers);
+ }
+}
diff --git a/pom.xml b/pom.xml
index 176ea9ee6..af807b8ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,9 +17,7 @@
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.
--->
-
+-->
4.0.0
com.iluwatar
@@ -126,7 +124,8 @@
mute-idiom
mutex
semaphore
-
+ hexagonal
+
@@ -425,4 +424,4 @@
-
\ No newline at end of file
+