mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-16 16:59:24 +00:00
docs: Content SEO updates (#2990)
* update yaml frontmatter format * update abstract document * update abstract factory * use the new pattern template * acyclic visitor seo * adapter seo * ambassador seo * acl seo * aaa seo * async method invocation seo * balking seo * bridge seo * builder seo * business delegate and bytecode seo * caching seo * callback seo * chain seo * update headings * circuit breaker seo * client session + collecting parameter seo * collection pipeline seo * combinator SEO * command seo * cqrs seo * commander seo * component seo * composite seo * composite entity seo * composite view seo * context object seo * converter seo * crtp seo * currying seo * dao seo * data bus seo * data locality seo * data mapper seo * dto seo * decorator seo * delegation seo * di seo * dirty flag seo * domain model seo * double buffer seo * double checked locking seo * double dispatch seo * dynamic proxy seo * event aggregator seo * event-based asynchronous seo * eda seo * event queue seo * event sourcing seo * execute around seo * extension objects seo * facade seo * factory seo * factory kit seo * factory method seo * fanout/fanin seo * feature toggle seo * filterer seo * fluent interface seo * flux seo * flyweight seo * front controller seo * function composition seo * game loop seo * gateway seo * guarded suspension seo * half-sync/half-async seo * health check seo * hexagonal seo * identity map seo * intercepting filter seo * interpreter seo * iterator seo * layers seo * lazy loading seo * leader election seo * leader/followers seo * lockable object seo * rename and add seo for marker interface * master-worker seo * mediator seo * memento seo * metadata mapping seo * microservice aggregator seo * api gw seo * microservices log aggregration seo * mvc seo * mvi seo * mvp seo * mvvm seo * monad seo * monitor seo * monostate seo * multiton seo * mute idiom seo * naked objects & notification seo * null object seo * object mother seo * object pool seo * observer seo * optimistic locking seo * page controller seo * page object seo * parameter object seo * partial response seo * pipeline seo * poison pill seo * presentation model seo * private class data seo * producer-consumer seo * promise seo * property seo * prototype seo * proxy seo * queue-based load leveling seo * reactor seo * registry seo * repository seo * RAII seo * retry seo * role object seo * saga seo * separated interface seo * serialized entity seo * serialized lob seo * servant seo * server session seo * service layer seo * service locator seo * service to worker seo * sharding seo * single table inheritance seo * singleton seo * spatial partition seo * special case seo * specification seo * state seo * step builder seo * strangler seo * strategy seo * subclass sandbox seo * table module seo * template method seo * throttling seo * tolerant reader seo * trampoline seo * transaction script seo * twin seo * type object seo * unit of work seo * update method seo * value object seo * version number seo * virtual proxy seo * visitor seo * seo enhancements * seo improvements * SEO enhancements * SEO improvements * SEO additions * SEO improvements * more SEO improvements * rename hexagonal + SEO improvements * SEO improvements * more SEO stuff * SEO improvements * SEO optimizations * SEO enhancements * enchance SEO * improve SEO * SEO improvements * update headers
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.google.inject.Guice;
|
||||
import com.iluwatar.hexagonal.domain.LotteryAdministration;
|
||||
import com.iluwatar.hexagonal.domain.LotteryService;
|
||||
import com.iluwatar.hexagonal.module.LotteryTestingModule;
|
||||
import com.iluwatar.hexagonal.sampledata.SampleData;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>The primary ports for the application are console interfaces {@link
|
||||
* com.iluwatar.hexagonal.administration.ConsoleAdministration} through which the lottery round is
|
||||
* initiated and run and {@link com.iluwatar.hexagonal.service.ConsoleLottery} that allows players
|
||||
* to submit lottery tickets for the draw.
|
||||
*
|
||||
* <p>The secondary ports that application core uses are{@link
|
||||
* com.iluwatar.hexagonal.banking.WireTransfers} which is a banking service, {@link
|
||||
* com.iluwatar.hexagonal.eventlog.LotteryEventLog} that delivers eventlog as lottery events occur
|
||||
* and {@link com.iluwatar.hexagonal.database.LotteryTicketRepository} that is the storage for the
|
||||
* lottery tickets.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
var injector = Guice.createInjector(new LotteryTestingModule());
|
||||
|
||||
// start new lottery round
|
||||
var administration = injector.getInstance(LotteryAdministration.class);
|
||||
administration.resetLottery();
|
||||
|
||||
// submit some lottery tickets
|
||||
var service = injector.getInstance(LotteryService.class);
|
||||
SampleData.submitTickets(service, 20);
|
||||
|
||||
// perform lottery
|
||||
administration.performLottery();
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.google.inject.Guice;
|
||||
import com.iluwatar.hexagonal.domain.LotteryAdministration;
|
||||
import com.iluwatar.hexagonal.domain.LotteryService;
|
||||
import com.iluwatar.hexagonal.module.LotteryModule;
|
||||
import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader;
|
||||
import com.iluwatar.hexagonal.sampledata.SampleData;
|
||||
import java.util.Scanner;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Console interface for lottery administration.
|
||||
*/
|
||||
@Slf4j
|
||||
public class ConsoleAdministration {
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
MongoConnectionPropertiesLoader.load();
|
||||
var injector = Guice.createInjector(new LotteryModule());
|
||||
var administration = injector.getInstance(LotteryAdministration.class);
|
||||
var service = injector.getInstance(LotteryService.class);
|
||||
SampleData.submitTickets(service, 20);
|
||||
var consoleAdministration = new ConsoleAdministrationSrvImpl(administration, LOGGER);
|
||||
try (var scanner = new Scanner(System.in)) {
|
||||
var exit = false;
|
||||
while (!exit) {
|
||||
printMainMenu();
|
||||
var cmd = readString(scanner);
|
||||
if ("1".equals(cmd)) {
|
||||
consoleAdministration.getAllSubmittedTickets();
|
||||
} else if ("2".equals(cmd)) {
|
||||
consoleAdministration.performLottery();
|
||||
} else if ("3".equals(cmd)) {
|
||||
consoleAdministration.resetLottery();
|
||||
} else if ("4".equals(cmd)) {
|
||||
exit = true;
|
||||
} else {
|
||||
LOGGER.info("Unknown command: {}", cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printMainMenu() {
|
||||
LOGGER.info("");
|
||||
LOGGER.info("### Lottery Administration Console ###");
|
||||
LOGGER.info("(1) Show all submitted tickets");
|
||||
LOGGER.info("(2) Perform lottery draw");
|
||||
LOGGER.info("(3) Reset lottery ticket database");
|
||||
LOGGER.info("(4) Exit");
|
||||
}
|
||||
|
||||
private static String readString(Scanner scanner) {
|
||||
LOGGER.info("> ");
|
||||
return scanner.next();
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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;
|
||||
|
||||
/**
|
||||
* Console interface for lottery administration.
|
||||
*/
|
||||
public interface ConsoleAdministrationSrv {
|
||||
|
||||
/**
|
||||
* Get all submitted tickets.
|
||||
*/
|
||||
void getAllSubmittedTickets();
|
||||
|
||||
/**
|
||||
* Draw lottery numbers.
|
||||
*/
|
||||
void performLottery();
|
||||
|
||||
/**
|
||||
* Begin new lottery round.
|
||||
*/
|
||||
void resetLottery();
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.domain.LotteryAdministration;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* Console implementation for lottery administration.
|
||||
*/
|
||||
public class ConsoleAdministrationSrvImpl implements ConsoleAdministrationSrv {
|
||||
private final LotteryAdministration administration;
|
||||
private final Logger logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public ConsoleAdministrationSrvImpl(LotteryAdministration administration, Logger logger) {
|
||||
this.administration = administration;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAllSubmittedTickets() {
|
||||
administration.getAllSubmittedTickets()
|
||||
.forEach((k, v) -> logger.info("Key: {}, Value: {}", k, v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performLottery() {
|
||||
var numbers = administration.performLottery();
|
||||
logger.info("The winning numbers: {}", numbers.getNumbersAsString());
|
||||
logger.info("Time to reset the database for next round, eh?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLottery() {
|
||||
administration.resetLottery();
|
||||
logger.info("The lottery ticket database was cleared.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.domain.LotteryConstants;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Banking implementation.
|
||||
*/
|
||||
public class InMemoryBank implements WireTransfers {
|
||||
|
||||
private static final Map<String, Integer> accounts = new HashMap<>();
|
||||
|
||||
static {
|
||||
accounts
|
||||
.put(LotteryConstants.SERVICE_BANK_ACCOUNT, LotteryConstants.SERVICE_BANK_ACCOUNT_BALANCE);
|
||||
}
|
||||
|
||||
@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 sourceAccount, String destinationAccount) {
|
||||
if (accounts.getOrDefault(sourceAccount, 0) >= amount) {
|
||||
accounts.put(sourceAccount, accounts.get(sourceAccount) - amount);
|
||||
accounts.put(destinationAccount, accounts.get(destinationAccount) + amount);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import java.util.ArrayList;
|
||||
import lombok.Getter;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Mongo based banking adapter.
|
||||
*/
|
||||
public class MongoBank implements WireTransfers {
|
||||
|
||||
private static final String DEFAULT_DB = "lotteryDB";
|
||||
private static final String DEFAULT_ACCOUNTS_COLLECTION = "accounts";
|
||||
|
||||
@Getter
|
||||
private MongoClient mongoClient;
|
||||
@Getter
|
||||
private MongoDatabase database;
|
||||
@Getter
|
||||
private MongoCollection<Document> accountsCollection;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public MongoBank() {
|
||||
connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor accepting parameters.
|
||||
*/
|
||||
public MongoBank(String dbName, String accountsCollectionName) {
|
||||
connect(dbName, accountsCollectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database with default parameters.
|
||||
*/
|
||||
public void connect() {
|
||||
connect(DEFAULT_DB, DEFAULT_ACCOUNTS_COLLECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database with given parameters.
|
||||
*/
|
||||
public void connect(String dbName, String accountsCollectionName) {
|
||||
if (mongoClient != null) {
|
||||
mongoClient.close();
|
||||
}
|
||||
mongoClient = new MongoClient(System.getProperty("mongo-host"),
|
||||
Integer.parseInt(System.getProperty("mongo-port")));
|
||||
database = mongoClient.getDatabase(dbName);
|
||||
accountsCollection = database.getCollection(accountsCollectionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFunds(String bankAccount, int amount) {
|
||||
var search = new Document("_id", bankAccount);
|
||||
var update = new Document("_id", bankAccount).append("funds", amount);
|
||||
var updateOptions = new UpdateOptions().upsert(true);
|
||||
accountsCollection.updateOne(search, new Document("$set", update), updateOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFunds(String bankAccount) {
|
||||
return accountsCollection
|
||||
.find(new Document("_id", bankAccount))
|
||||
.limit(1)
|
||||
.into(new ArrayList<>())
|
||||
.stream()
|
||||
.findFirst()
|
||||
.map(x -> x.getInteger("funds"))
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transferFunds(int amount, String sourceAccount, String destinationAccount) {
|
||||
var sourceFunds = getFunds(sourceAccount);
|
||||
if (sourceFunds < amount) {
|
||||
return false;
|
||||
} else {
|
||||
var destFunds = getFunds(destinationAccount);
|
||||
setFunds(sourceAccount, sourceFunds - amount);
|
||||
setFunds(destinationAccount, destFunds + amount);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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);
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.domain.LotteryTicket;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicketId;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Mock database for lottery tickets.
|
||||
*/
|
||||
public class InMemoryTicketRepository implements LotteryTicketRepository {
|
||||
|
||||
private static final Map<LotteryTicketId, LotteryTicket> tickets = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Optional<LotteryTicket> findById(LotteryTicketId id) {
|
||||
return Optional.ofNullable(tickets.get(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<LotteryTicketId> save(LotteryTicket ticket) {
|
||||
var id = new LotteryTicketId();
|
||||
tickets.put(id, ticket);
|
||||
return Optional.of(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<LotteryTicketId, LotteryTicket> findAll() {
|
||||
return tickets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll() {
|
||||
tickets.clear();
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.domain.LotteryTicket;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicketId;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Interface for accessing lottery tickets in database.
|
||||
*/
|
||||
public interface LotteryTicketRepository {
|
||||
|
||||
/**
|
||||
* Find lottery ticket by id.
|
||||
*/
|
||||
Optional<LotteryTicket> findById(LotteryTicketId id);
|
||||
|
||||
/**
|
||||
* Save lottery ticket.
|
||||
*/
|
||||
Optional<LotteryTicketId> save(LotteryTicket ticket);
|
||||
|
||||
/**
|
||||
* Get all lottery tickets.
|
||||
*/
|
||||
Map<LotteryTicketId, LotteryTicket> findAll();
|
||||
|
||||
/**
|
||||
* Delete all lottery tickets.
|
||||
*/
|
||||
void deleteAll();
|
||||
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.domain.LotteryNumbers;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicket;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicketId;
|
||||
import com.iluwatar.hexagonal.domain.PlayerDetails;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Getter;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Mongo lottery ticket database.
|
||||
*/
|
||||
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;
|
||||
@Getter
|
||||
private MongoCollection<Document> ticketsCollection;
|
||||
@Getter
|
||||
private MongoCollection<Document> countersCollection;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public MongoTicketRepository() {
|
||||
connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor accepting parameters.
|
||||
*/
|
||||
public MongoTicketRepository(String dbName, String ticketsCollectionName,
|
||||
String countersCollectionName) {
|
||||
connect(dbName, ticketsCollectionName, countersCollectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database with default parameters.
|
||||
*/
|
||||
public void connect() {
|
||||
connect(DEFAULT_DB, DEFAULT_TICKETS_COLLECTION, DEFAULT_COUNTERS_COLLECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database with given parameters.
|
||||
*/
|
||||
public void connect(String dbName, String ticketsCollectionName,
|
||||
String countersCollectionName) {
|
||||
if (mongoClient != null) {
|
||||
mongoClient.close();
|
||||
}
|
||||
mongoClient = new MongoClient(System.getProperty("mongo-host"),
|
||||
Integer.parseInt(System.getProperty("mongo-port")));
|
||||
database = mongoClient.getDatabase(dbName);
|
||||
ticketsCollection = database.getCollection(ticketsCollectionName);
|
||||
countersCollection = database.getCollection(countersCollectionName);
|
||||
if (countersCollection.countDocuments() <= 0) {
|
||||
initCounters();
|
||||
}
|
||||
}
|
||||
|
||||
private void initCounters() {
|
||||
var doc = new Document("_id", TICKET_ID).append("seq", 1);
|
||||
countersCollection.insertOne(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next ticket id.
|
||||
*
|
||||
* @return next ticket id
|
||||
*/
|
||||
public int getNextId() {
|
||||
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);
|
||||
return result.getInteger("seq");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<LotteryTicket> findById(LotteryTicketId id) {
|
||||
return ticketsCollection
|
||||
.find(new Document(TICKET_ID, id.getId()))
|
||||
.limit(1)
|
||||
.into(new ArrayList<>())
|
||||
.stream()
|
||||
.findFirst()
|
||||
.map(this::docToTicket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<LotteryTicketId> save(LotteryTicket ticket) {
|
||||
var ticketId = getNextId();
|
||||
var doc = new Document(TICKET_ID, ticketId);
|
||||
doc.put("email", ticket.playerDetails().email());
|
||||
doc.put("bank", ticket.playerDetails().bankAccount());
|
||||
doc.put("phone", ticket.playerDetails().phoneNumber());
|
||||
doc.put("numbers", ticket.lotteryNumbers().getNumbersAsString());
|
||||
ticketsCollection.insertOne(doc);
|
||||
return Optional.of(new LotteryTicketId(ticketId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<LotteryTicketId, LotteryTicket> findAll() {
|
||||
return ticketsCollection
|
||||
.find(new Document())
|
||||
.into(new ArrayList<>())
|
||||
.stream()
|
||||
.map(this::docToTicket)
|
||||
.collect(Collectors.toMap(LotteryTicket::id, Function.identity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll() {
|
||||
ticketsCollection.deleteMany(new Document());
|
||||
}
|
||||
|
||||
private LotteryTicket docToTicket(Document doc) {
|
||||
var playerDetails = new PlayerDetails(doc.getString("email"), doc.getString("bank"),
|
||||
doc.getString("phone"));
|
||||
var numbers = Arrays.stream(doc.getString("numbers").split(","))
|
||||
.map(Integer::parseInt)
|
||||
.collect(Collectors.toSet());
|
||||
var lotteryNumbers = LotteryNumbers.create(numbers);
|
||||
var ticketId = new LotteryTicketId(doc.getInteger(TICKET_ID));
|
||||
return new LotteryTicket(ticketId, playerDetails, lotteryNumbers);
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.domain.LotteryConstants.PRIZE_AMOUNT;
|
||||
import static com.iluwatar.hexagonal.domain.LotteryConstants.SERVICE_BANK_ACCOUNT;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.iluwatar.hexagonal.banking.WireTransfers;
|
||||
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
|
||||
import com.iluwatar.hexagonal.eventlog.LotteryEventLog;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Lottery administration implementation.
|
||||
*/
|
||||
public class LotteryAdministration {
|
||||
|
||||
private final LotteryTicketRepository repository;
|
||||
private final LotteryEventLog notifications;
|
||||
private final WireTransfers wireTransfers;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@Inject
|
||||
public LotteryAdministration(LotteryTicketRepository repository, LotteryEventLog notifications,
|
||||
WireTransfers wireTransfers) {
|
||||
this.repository = repository;
|
||||
this.notifications = notifications;
|
||||
this.wireTransfers = wireTransfers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the lottery tickets submitted for lottery.
|
||||
*/
|
||||
public Map<LotteryTicketId, LotteryTicket> getAllSubmittedTickets() {
|
||||
return repository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw lottery numbers.
|
||||
*/
|
||||
public LotteryNumbers performLottery() {
|
||||
var numbers = LotteryNumbers.createRandom();
|
||||
var tickets = getAllSubmittedTickets();
|
||||
for (var id : tickets.keySet()) {
|
||||
var lotteryTicket = tickets.get(id);
|
||||
var playerDetails = lotteryTicket.playerDetails();
|
||||
var playerAccount = playerDetails.bankAccount();
|
||||
var result = LotteryUtils.checkTicketForPrize(repository, id, numbers).getResult();
|
||||
if (result == LotteryTicketCheckResult.CheckResult.WIN_PRIZE) {
|
||||
if (wireTransfers.transferFunds(PRIZE_AMOUNT, SERVICE_BANK_ACCOUNT, playerAccount)) {
|
||||
notifications.ticketWon(playerDetails, PRIZE_AMOUNT);
|
||||
} else {
|
||||
notifications.prizeError(playerDetails, PRIZE_AMOUNT);
|
||||
}
|
||||
} else if (result == LotteryTicketCheckResult.CheckResult.NO_PRIZE) {
|
||||
notifications.ticketDidNotWin(playerDetails);
|
||||
}
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin new lottery round.
|
||||
*/
|
||||
public void resetLottery() {
|
||||
repository.deleteAll();
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 {
|
||||
|
||||
private 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_BALANCE = 150000;
|
||||
public static final int PLAYER_MAX_BALANCE = 100;
|
||||
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.google.common.base.Joiner;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Set;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* Value object representing lottery numbers. This lottery uses sets of 4 numbers. The numbers must
|
||||
* be unique and between 1 and 20.
|
||||
*/
|
||||
@EqualsAndHashCode
|
||||
@ToString
|
||||
public class LotteryNumbers {
|
||||
|
||||
private final Set<Integer> 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<Integer> givenNumbers) {
|
||||
numbers = new HashSet<>();
|
||||
numbers.addAll(givenNumbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a random lottery number.
|
||||
*
|
||||
* @return random LotteryNumbers
|
||||
*/
|
||||
public static LotteryNumbers createRandom() {
|
||||
return new LotteryNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates lottery number from given set of numbers.
|
||||
*
|
||||
* @return given LotteryNumbers
|
||||
*/
|
||||
public static LotteryNumbers create(Set<Integer> givenNumbers) {
|
||||
return new LotteryNumbers(givenNumbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get numbers.
|
||||
*
|
||||
* @return lottery numbers
|
||||
*/
|
||||
public Set<Integer> getNumbers() {
|
||||
return Collections.unmodifiableSet(numbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get numbers as string.
|
||||
*
|
||||
* @return numbers as comma separated string
|
||||
*/
|
||||
public String getNumbersAsString() {
|
||||
return Joiner.on(',').join(numbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates 4 unique random numbers between 1-20 into numbers set.
|
||||
*/
|
||||
private void generateRandomNumbers() {
|
||||
numbers.clear();
|
||||
var generator = new RandomNumberGenerator(MIN_NUMBER, MAX_NUMBER);
|
||||
while (numbers.size() < NUM_NUMBERS) {
|
||||
var num = generator.nextInt();
|
||||
numbers.add(num);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for generating random numbers.
|
||||
*/
|
||||
private static class RandomNumberGenerator {
|
||||
|
||||
private final 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 SecureRandom().ints(min, max + 1).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets next random integer in [min, max] range.
|
||||
*
|
||||
* @return a random number in the range (min, max)
|
||||
*/
|
||||
public int nextInt() {
|
||||
return randomIterator.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.domain.LotteryConstants.SERVICE_BANK_ACCOUNT;
|
||||
import static com.iluwatar.hexagonal.domain.LotteryConstants.TICKET_PRIZE;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.iluwatar.hexagonal.banking.WireTransfers;
|
||||
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
|
||||
import com.iluwatar.hexagonal.eventlog.LotteryEventLog;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Implementation for lottery service.
|
||||
*/
|
||||
public class LotteryService {
|
||||
|
||||
private final LotteryTicketRepository repository;
|
||||
private final LotteryEventLog notifications;
|
||||
private final WireTransfers wireTransfers;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@Inject
|
||||
public LotteryService(LotteryTicketRepository repository, LotteryEventLog notifications,
|
||||
WireTransfers wireTransfers) {
|
||||
this.repository = repository;
|
||||
this.notifications = notifications;
|
||||
this.wireTransfers = wireTransfers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit lottery ticket to participate in the lottery.
|
||||
*/
|
||||
public Optional<LotteryTicketId> submitTicket(LotteryTicket ticket) {
|
||||
var playerDetails = ticket.playerDetails();
|
||||
var playerAccount = playerDetails.bankAccount();
|
||||
var result = wireTransfers.transferFunds(TICKET_PRIZE, playerAccount, SERVICE_BANK_ACCOUNT);
|
||||
if (!result) {
|
||||
notifications.ticketSubmitError(playerDetails);
|
||||
return Optional.empty();
|
||||
}
|
||||
var optional = repository.save(ticket);
|
||||
if (optional.isPresent()) {
|
||||
notifications.ticketSubmitted(playerDetails);
|
||||
}
|
||||
return optional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if lottery ticket has won.
|
||||
*/
|
||||
public LotteryTicketCheckResult checkTicketForPrize(
|
||||
LotteryTicketId id,
|
||||
LotteryNumbers winningNumbers
|
||||
) {
|
||||
return LotteryUtils.checkTicketForPrize(repository, id, winningNumbers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 record LotteryTicket(LotteryTicketId id, PlayerDetails playerDetails, LotteryNumbers lotteryNumbers) {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final var prime = 31;
|
||||
var 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;
|
||||
}
|
||||
var other = (LotteryTicket) obj;
|
||||
if (lotteryNumbers == null) {
|
||||
if (other.lotteryNumbers != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!lotteryNumbers.equals(other.lotteryNumbers)) {
|
||||
return false;
|
||||
}
|
||||
if (playerDetails == null) {
|
||||
return other.playerDetails == null;
|
||||
} else {
|
||||
return playerDetails.equals(other.playerDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* Represents lottery ticket check result.
|
||||
*/
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
public class LotteryTicketCheckResult {
|
||||
|
||||
/**
|
||||
* Enumeration of Type of Outcomes of a Lottery.
|
||||
*/
|
||||
public enum CheckResult {
|
||||
WIN_PRIZE,
|
||||
NO_PRIZE,
|
||||
TICKET_NOT_SUBMITTED
|
||||
}
|
||||
|
||||
private final CheckResult result;
|
||||
private final int prizeAmount;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public LotteryTicketCheckResult(CheckResult result) {
|
||||
this.result = result;
|
||||
prizeAmount = 0;
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.concurrent.atomic.AtomicInteger;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* Lottery ticked id.
|
||||
*/
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
public class LotteryTicketId {
|
||||
|
||||
private static final AtomicInteger numAllocated = new AtomicInteger(0);
|
||||
private final int id;
|
||||
|
||||
public LotteryTicketId() {
|
||||
this.id = numAllocated.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%d", id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.database.LotteryTicketRepository;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
|
||||
|
||||
/**
|
||||
* Lottery utilities.
|
||||
*/
|
||||
public class LotteryUtils {
|
||||
|
||||
private LotteryUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if lottery ticket has won.
|
||||
*/
|
||||
public static LotteryTicketCheckResult checkTicketForPrize(
|
||||
LotteryTicketRepository repository,
|
||||
LotteryTicketId id,
|
||||
LotteryNumbers winningNumbers
|
||||
) {
|
||||
var optional = repository.findById(id);
|
||||
if (optional.isPresent()) {
|
||||
if (optional.get().lotteryNumbers().equals(winningNumbers)) {
|
||||
return new LotteryTicketCheckResult(CheckResult.WIN_PRIZE, 1000);
|
||||
} else {
|
||||
return new LotteryTicketCheckResult(CheckResult.NO_PRIZE);
|
||||
}
|
||||
} else {
|
||||
return new LotteryTicketCheckResult(CheckResult.TICKET_NOT_SUBMITTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 record PlayerDetails(String email, String bankAccount, String phoneNumber) {}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.eventlog;
|
||||
|
||||
import com.iluwatar.hexagonal.domain.PlayerDetails;
|
||||
|
||||
/**
|
||||
* Event log for lottery events.
|
||||
*/
|
||||
public interface LotteryEventLog {
|
||||
|
||||
/**
|
||||
* lottery ticket submitted.
|
||||
*/
|
||||
void ticketSubmitted(PlayerDetails details);
|
||||
|
||||
/**
|
||||
* error submitting lottery ticket.
|
||||
*/
|
||||
void ticketSubmitError(PlayerDetails details);
|
||||
|
||||
/**
|
||||
* lottery ticket did not win.
|
||||
*/
|
||||
void ticketDidNotWin(PlayerDetails details);
|
||||
|
||||
/**
|
||||
* lottery ticket won.
|
||||
*/
|
||||
void ticketWon(PlayerDetails details, int prizeAmount);
|
||||
|
||||
/**
|
||||
* error paying the prize.
|
||||
*/
|
||||
void prizeError(PlayerDetails details, int prizeAmount);
|
||||
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.eventlog;
|
||||
|
||||
import com.iluwatar.hexagonal.domain.PlayerDetails;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import lombok.Getter;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Mongo based event log.
|
||||
*/
|
||||
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";
|
||||
|
||||
@Getter
|
||||
private MongoClient mongoClient;
|
||||
@Getter
|
||||
private MongoDatabase database;
|
||||
@Getter
|
||||
private MongoCollection<Document> eventsCollection;
|
||||
|
||||
private final StdOutEventLog stdOutEventLog = new StdOutEventLog();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public MongoEventLog() {
|
||||
connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor accepting parameters.
|
||||
*/
|
||||
public MongoEventLog(String dbName, String eventsCollectionName) {
|
||||
connect(dbName, eventsCollectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database with default parameters.
|
||||
*/
|
||||
public void connect() {
|
||||
connect(DEFAULT_DB, DEFAULT_EVENTS_COLLECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database with given parameters.
|
||||
*/
|
||||
public void connect(String dbName, String eventsCollectionName) {
|
||||
if (mongoClient != null) {
|
||||
mongoClient.close();
|
||||
}
|
||||
mongoClient = new MongoClient(System.getProperty("mongo-host"),
|
||||
Integer.parseInt(System.getProperty("mongo-port")));
|
||||
database = mongoClient.getDatabase(dbName);
|
||||
eventsCollection = database.getCollection(eventsCollectionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ticketSubmitted(PlayerDetails details) {
|
||||
var document = new Document(EMAIL, details.email());
|
||||
document.put(PHONE, details.phoneNumber());
|
||||
document.put("bank", details.bankAccount());
|
||||
document
|
||||
.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.email());
|
||||
document.put(PHONE, details.phoneNumber());
|
||||
document.put("bank", details.bankAccount());
|
||||
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.email());
|
||||
document.put(PHONE, details.phoneNumber());
|
||||
document.put("bank", details.bankAccount());
|
||||
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.email());
|
||||
document.put(PHONE, details.phoneNumber());
|
||||
document.put("bank", details.bankAccount());
|
||||
document.put(MESSAGE, String
|
||||
.format("Lottery ticket won! The bank account was deposited with %d credits.",
|
||||
prizeAmount));
|
||||
eventsCollection.insertOne(document);
|
||||
stdOutEventLog.ticketWon(details, prizeAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prizeError(PlayerDetails details, int prizeAmount) {
|
||||
var document = new Document(EMAIL, details.email());
|
||||
document.put(PHONE, details.phoneNumber());
|
||||
document.put("bank", details.bankAccount());
|
||||
document.put(MESSAGE, String
|
||||
.format("Lottery ticket won! Unfortunately the bank credit transfer of %d failed.",
|
||||
prizeAmount));
|
||||
eventsCollection.insertOne(document);
|
||||
stdOutEventLog.prizeError(details, prizeAmount);
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.eventlog;
|
||||
|
||||
import com.iluwatar.hexagonal.domain.PlayerDetails;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Standard output event log.
|
||||
*/
|
||||
@Slf4j
|
||||
public class StdOutEventLog implements LotteryEventLog {
|
||||
|
||||
@Override
|
||||
public void ticketSubmitted(PlayerDetails details) {
|
||||
LOGGER.info("Lottery ticket for {} was submitted. Bank account {} was charged for 3 credits.",
|
||||
details.email(), details.bankAccount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ticketDidNotWin(PlayerDetails details) {
|
||||
LOGGER.info("Lottery ticket for {} was checked and unfortunately did not win this time.",
|
||||
details.email());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ticketWon(PlayerDetails details, int prizeAmount) {
|
||||
LOGGER.info("Lottery ticket for {} has won! The bank account {} was deposited with {} credits.",
|
||||
details.email(), details.bankAccount(), prizeAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prizeError(PlayerDetails details, int prizeAmount) {
|
||||
LOGGER.error("Lottery ticket for {} has won! Unfortunately the bank credit transfer of"
|
||||
+ " {} failed.", details.email(), prizeAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ticketSubmitError(PlayerDetails details) {
|
||||
LOGGER.error("Lottery ticket for {} could not be submitted because the credit transfer"
|
||||
+ " of 3 credits failed.", details.email());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.iluwatar.hexagonal.banking.MongoBank;
|
||||
import com.iluwatar.hexagonal.banking.WireTransfers;
|
||||
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
|
||||
import com.iluwatar.hexagonal.database.MongoTicketRepository;
|
||||
import com.iluwatar.hexagonal.eventlog.LotteryEventLog;
|
||||
import com.iluwatar.hexagonal.eventlog.MongoEventLog;
|
||||
|
||||
/**
|
||||
* Guice module for binding production dependencies.
|
||||
*/
|
||||
public class LotteryModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(LotteryTicketRepository.class).to(MongoTicketRepository.class);
|
||||
bind(LotteryEventLog.class).to(MongoEventLog.class);
|
||||
bind(WireTransfers.class).to(MongoBank.class);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.iluwatar.hexagonal.banking.InMemoryBank;
|
||||
import com.iluwatar.hexagonal.banking.WireTransfers;
|
||||
import com.iluwatar.hexagonal.database.InMemoryTicketRepository;
|
||||
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
|
||||
import com.iluwatar.hexagonal.eventlog.LotteryEventLog;
|
||||
import com.iluwatar.hexagonal.eventlog.StdOutEventLog;
|
||||
|
||||
/**
|
||||
* Guice module for testing dependencies.
|
||||
*/
|
||||
public class LotteryTestingModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(LotteryTicketRepository.class).to(InMemoryTicketRepository.class);
|
||||
bind(LotteryEventLog.class).to(StdOutEventLog.class);
|
||||
bind(WireTransfers.class).to(InMemoryBank.class);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.mongo;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Properties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Mongo connection properties loader.
|
||||
*/
|
||||
@Slf4j
|
||||
public class MongoConnectionPropertiesLoader {
|
||||
|
||||
private static final String DEFAULT_HOST = "localhost";
|
||||
private static final int DEFAULT_PORT = 27017;
|
||||
|
||||
/**
|
||||
* Try to load connection properties from file. Fall back to default connection properties.
|
||||
*/
|
||||
public static void load() {
|
||||
var host = DEFAULT_HOST;
|
||||
var port = DEFAULT_PORT;
|
||||
var path = System.getProperty("hexagonal.properties.path");
|
||||
var properties = new Properties();
|
||||
if (path != null) {
|
||||
try (var fin = new FileInputStream(path)) {
|
||||
properties.load(fin);
|
||||
host = properties.getProperty("mongo-host");
|
||||
port = Integer.parseInt(properties.getProperty("mongo-port"));
|
||||
} catch (Exception e) {
|
||||
// error occurred, use default properties
|
||||
LOGGER.error("Error occurred: ", e);
|
||||
}
|
||||
}
|
||||
System.setProperty("mongo-host", host);
|
||||
System.setProperty("mongo-port", String.format("%d", port));
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.sampledata;
|
||||
|
||||
import com.iluwatar.hexagonal.banking.InMemoryBank;
|
||||
import com.iluwatar.hexagonal.domain.LotteryConstants;
|
||||
import com.iluwatar.hexagonal.domain.LotteryNumbers;
|
||||
import com.iluwatar.hexagonal.domain.LotteryService;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicket;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicketId;
|
||||
import com.iluwatar.hexagonal.domain.PlayerDetails;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Utilities for creating sample lottery tickets.
|
||||
*/
|
||||
public class SampleData {
|
||||
|
||||
private static final List<PlayerDetails> PLAYERS;
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
static {
|
||||
PLAYERS = List.of(
|
||||
new PlayerDetails("john@google.com", "312-342", "+3242434242"),
|
||||
new PlayerDetails("mary@google.com", "234-987", "+23452346"),
|
||||
new PlayerDetails("steve@google.com", "833-836", "+63457543"),
|
||||
new PlayerDetails("wayne@google.com", "319-826", "+24626"),
|
||||
new PlayerDetails("johnie@google.com", "983-322", "+3635635"),
|
||||
new PlayerDetails("andy@google.com", "934-734", "+0898245"),
|
||||
new PlayerDetails("richard@google.com", "536-738", "+09845325"),
|
||||
new PlayerDetails("kevin@google.com", "453-936", "+2423532"),
|
||||
new PlayerDetails("arnold@google.com", "114-988", "+5646346524"),
|
||||
new PlayerDetails("ian@google.com", "663-765", "+928394235"),
|
||||
new PlayerDetails("robin@google.com", "334-763", "+35448"),
|
||||
new PlayerDetails("ted@google.com", "735-964", "+98752345"),
|
||||
new PlayerDetails("larry@google.com", "734-853", "+043842423"),
|
||||
new PlayerDetails("calvin@google.com", "334-746", "+73294135"),
|
||||
new PlayerDetails("jacob@google.com", "444-766", "+358042354"),
|
||||
new PlayerDetails("edwin@google.com", "895-345", "+9752435"),
|
||||
new PlayerDetails("mary@google.com", "760-009", "+34203542"),
|
||||
new PlayerDetails("lolita@google.com", "425-907", "+9872342"),
|
||||
new PlayerDetails("bruno@google.com", "023-638", "+673824122"),
|
||||
new PlayerDetails("peter@google.com", "335-886", "+5432503945"),
|
||||
new PlayerDetails("warren@google.com", "225-946", "+9872341324"),
|
||||
new PlayerDetails("monica@google.com", "265-748", "+134124"),
|
||||
new PlayerDetails("ollie@google.com", "190-045", "+34453452"),
|
||||
new PlayerDetails("yngwie@google.com", "241-465", "+9897641231"),
|
||||
new PlayerDetails("lars@google.com", "746-936", "+42345298345"),
|
||||
new PlayerDetails("bobbie@google.com", "946-384", "+79831742"),
|
||||
new PlayerDetails("tyron@google.com", "310-992", "+0498837412"),
|
||||
new PlayerDetails("tyrell@google.com", "032-045", "+67834134"),
|
||||
new PlayerDetails("nadja@google.com", "000-346", "+498723"),
|
||||
new PlayerDetails("wendy@google.com", "994-989", "+987324454"),
|
||||
new PlayerDetails("luke@google.com", "546-634", "+987642435"),
|
||||
new PlayerDetails("bjorn@google.com", "342-874", "+7834325"),
|
||||
new PlayerDetails("lisa@google.com", "024-653", "+980742154"),
|
||||
new PlayerDetails("anton@google.com", "834-935", "+876423145"),
|
||||
new PlayerDetails("bruce@google.com", "284-936", "+09843212345"),
|
||||
new PlayerDetails("ray@google.com", "843-073", "+678324123"),
|
||||
new PlayerDetails("ron@google.com", "637-738", "+09842354"),
|
||||
new PlayerDetails("xavier@google.com", "143-947", "+375245"),
|
||||
new PlayerDetails("harriet@google.com", "842-404", "+131243252")
|
||||
);
|
||||
var wireTransfers = new InMemoryBank();
|
||||
PLAYERS.stream()
|
||||
.map(PlayerDetails::bankAccount)
|
||||
.map(e -> new SimpleEntry<>(e, RANDOM.nextInt(LotteryConstants.PLAYER_MAX_BALANCE)))
|
||||
.collect(Collectors.toMap(SimpleEntry::getKey, SimpleEntry::getValue))
|
||||
.forEach(wireTransfers::setFunds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts lottery tickets into the database based on the sample data.
|
||||
*/
|
||||
public static void submitTickets(LotteryService lotteryService, int numTickets) {
|
||||
for (var i = 0; i < numTickets; i++) {
|
||||
var randomPlayerDetails = getRandomPlayerDetails();
|
||||
var lotteryNumbers = LotteryNumbers.createRandom();
|
||||
var lotteryTicketId = new LotteryTicketId();
|
||||
var ticket = new LotteryTicket(lotteryTicketId, randomPlayerDetails, lotteryNumbers);
|
||||
lotteryService.submitTicket(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
private static PlayerDetails getRandomPlayerDetails() {
|
||||
return PLAYERS.get(RANDOM.nextInt(PLAYERS.size()));
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.google.inject.Guice;
|
||||
import com.iluwatar.hexagonal.banking.WireTransfers;
|
||||
import com.iluwatar.hexagonal.domain.LotteryService;
|
||||
import com.iluwatar.hexagonal.module.LotteryModule;
|
||||
import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader;
|
||||
import java.util.Scanner;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Console interface for lottery players.
|
||||
*/
|
||||
@Slf4j
|
||||
public class ConsoleLottery {
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
MongoConnectionPropertiesLoader.load();
|
||||
var injector = Guice.createInjector(new LotteryModule());
|
||||
var service = injector.getInstance(LotteryService.class);
|
||||
var bank = injector.getInstance(WireTransfers.class);
|
||||
try (Scanner scanner = new Scanner(System.in)) {
|
||||
var exit = false;
|
||||
while (!exit) {
|
||||
printMainMenu();
|
||||
var cmd = readString(scanner);
|
||||
var lotteryConsoleService = new LotteryConsoleServiceImpl(LOGGER);
|
||||
if ("1".equals(cmd)) {
|
||||
lotteryConsoleService.queryLotteryAccountFunds(bank, scanner);
|
||||
} else if ("2".equals(cmd)) {
|
||||
lotteryConsoleService.addFundsToLotteryAccount(bank, scanner);
|
||||
} else if ("3".equals(cmd)) {
|
||||
lotteryConsoleService.submitTicket(service, scanner);
|
||||
} else if ("4".equals(cmd)) {
|
||||
lotteryConsoleService.checkTicket(service, scanner);
|
||||
} else if ("5".equals(cmd)) {
|
||||
exit = true;
|
||||
} else {
|
||||
LOGGER.info("Unknown command");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printMainMenu() {
|
||||
LOGGER.info("");
|
||||
LOGGER.info("### Lottery Service Console ###");
|
||||
LOGGER.info("(1) Query lottery account funds");
|
||||
LOGGER.info("(2) Add funds to lottery account");
|
||||
LOGGER.info("(3) Submit ticket");
|
||||
LOGGER.info("(4) Check ticket");
|
||||
LOGGER.info("(5) Exit");
|
||||
}
|
||||
|
||||
private static String readString(Scanner scanner) {
|
||||
LOGGER.info("> ");
|
||||
return scanner.next();
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.banking.WireTransfers;
|
||||
import com.iluwatar.hexagonal.domain.LotteryService;
|
||||
import java.util.Scanner;
|
||||
|
||||
|
||||
/**
|
||||
* Console interface for lottery service.
|
||||
*/
|
||||
public interface LotteryConsoleService {
|
||||
|
||||
void checkTicket(LotteryService service, Scanner scanner);
|
||||
|
||||
/**
|
||||
* Submit lottery ticket to participate in the lottery.
|
||||
*/
|
||||
void submitTicket(LotteryService service, Scanner scanner);
|
||||
|
||||
/**
|
||||
* Add funds to lottery account.
|
||||
*/
|
||||
void addFundsToLotteryAccount(WireTransfers bank, Scanner scanner);
|
||||
|
||||
|
||||
/**
|
||||
* Recovery funds from lottery account.
|
||||
*/
|
||||
void queryLotteryAccountFunds(WireTransfers bank, Scanner scanner);
|
||||
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.hexagonal.banking.WireTransfers;
|
||||
import com.iluwatar.hexagonal.domain.LotteryNumbers;
|
||||
import com.iluwatar.hexagonal.domain.LotteryService;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicket;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
|
||||
import com.iluwatar.hexagonal.domain.LotteryTicketId;
|
||||
import com.iluwatar.hexagonal.domain.PlayerDetails;
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* Console implementation for lottery console service.
|
||||
*/
|
||||
public class LotteryConsoleServiceImpl implements LotteryConsoleService {
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public LotteryConsoleServiceImpl(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkTicket(LotteryService service, Scanner scanner) {
|
||||
logger.info("What is the ID of the lottery ticket?");
|
||||
var id = readString(scanner);
|
||||
logger.info("Give the 4 comma separated winning numbers?");
|
||||
var numbers = readString(scanner);
|
||||
try {
|
||||
var winningNumbers = Arrays.stream(numbers.split(","))
|
||||
.map(Integer::parseInt)
|
||||
.limit(4)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
final var lotteryTicketId = new LotteryTicketId(Integer.parseInt(id));
|
||||
final var lotteryNumbers = LotteryNumbers.create(winningNumbers);
|
||||
var result = service.checkTicketForPrize(lotteryTicketId, lotteryNumbers);
|
||||
|
||||
if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.WIN_PRIZE)) {
|
||||
logger.info("Congratulations! The lottery ticket has won!");
|
||||
} else if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.NO_PRIZE)) {
|
||||
logger.info("Unfortunately the lottery ticket did not win.");
|
||||
} else {
|
||||
logger.info("Such lottery ticket has not been submitted.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.info("Failed checking the lottery ticket - please try again.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitTicket(LotteryService service, Scanner scanner) {
|
||||
logger.info("What is your email address?");
|
||||
var email = readString(scanner);
|
||||
logger.info("What is your bank account number?");
|
||||
var account = readString(scanner);
|
||||
logger.info("What is your phone number?");
|
||||
var phone = readString(scanner);
|
||||
var details = new PlayerDetails(email, account, phone);
|
||||
logger.info("Give 4 comma separated lottery numbers?");
|
||||
var numbers = readString(scanner);
|
||||
try {
|
||||
var chosen = Arrays.stream(numbers.split(","))
|
||||
.map(Integer::parseInt)
|
||||
.collect(Collectors.toSet());
|
||||
var lotteryNumbers = LotteryNumbers.create(chosen);
|
||||
var lotteryTicket = new LotteryTicket(new LotteryTicketId(), details, lotteryNumbers);
|
||||
service.submitTicket(lotteryTicket).ifPresentOrElse(
|
||||
(id) -> logger.info("Submitted lottery ticket with id: {}", id),
|
||||
() -> logger.info("Failed submitting lottery ticket - please try again.")
|
||||
);
|
||||
} catch (Exception e) {
|
||||
logger.info("Failed submitting lottery ticket - please try again.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFundsToLotteryAccount(WireTransfers bank, Scanner scanner) {
|
||||
logger.info("What is the account number?");
|
||||
var account = readString(scanner);
|
||||
logger.info("How many credits do you want to deposit?");
|
||||
var amount = readString(scanner);
|
||||
bank.setFunds(account, Integer.parseInt(amount));
|
||||
logger.info("The account {} now has {} credits.", account, bank.getFunds(account));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryLotteryAccountFunds(WireTransfers bank, Scanner scanner) {
|
||||
logger.info("What is the account number?");
|
||||
var account = readString(scanner);
|
||||
logger.info("The account {} has {} credits.", account, bank.getFunds(account));
|
||||
}
|
||||
|
||||
private String readString(Scanner scanner) {
|
||||
logger.info("> ");
|
||||
return scanner.next();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user