From e685512ed59a46f02e3b7670b8ee6731fc3279e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 11 Sep 2016 23:19:02 +0300 Subject: [PATCH] Hexagonal pattern: Added Mongo based banking adapter and bound it in Guice production module --- .../iluwatar/hexagonal/banking/MongoBank.java | 134 ++++++++++++++++++ .../hexagonal/module/LotteryModule.java | 4 +- ...ansfersTest.java => InMemoryBankTest.java} | 2 +- .../hexagonal/banking/MongoBankTest.java | 68 +++++++++ .../database/MongoTicketRepositoryTest.java | 6 +- 5 files changed, 208 insertions(+), 6 deletions(-) create mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java rename hexagonal/src/test/java/com/iluwatar/hexagonal/banking/{WireTransfersTest.java => InMemoryBankTest.java} (98%) create mode 100644 hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java new file mode 100644 index 000000000..3da65e156 --- /dev/null +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java @@ -0,0 +1,134 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.hexagonal.banking; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.UpdateOptions; +import org.bson.Document; + +import java.util.ArrayList; + +/** + * Mongo based banking adapter + */ +public class MongoBank implements WireTransfers { + + private static final String DEFAULT_HOST = "localhost"; + private static final int DEFAULT_PORT = 27017; + private static final String DEFAULT_DB = "lotteryDB"; + private static final String DEFAULT_ACCOUNTS_COLLECTION = "accounts"; + + private MongoClient mongoClient; + private MongoDatabase database; + private MongoCollection accountsCollection; + + /** + * Constructor + */ + public MongoBank() { + connect(); + } + + /** + * Constructor accepting parameters + */ + public MongoBank(String host, int port, String dbName, String accountsCollectionName) { + connect(host, port, dbName, accountsCollectionName); + } + + /** + * Connect to database with default parameters + */ + public void connect() { + connect(DEFAULT_HOST, DEFAULT_PORT, DEFAULT_DB, DEFAULT_ACCOUNTS_COLLECTION); + } + + /** + * Connect to database with given parameters + */ + public void connect(String host, int port, String dbName, String accountsCollectionName) { + if (mongoClient != null) { + mongoClient.close(); + } + mongoClient = new MongoClient(host , port); + database = mongoClient.getDatabase(dbName); + accountsCollection = database.getCollection(accountsCollectionName); + } + + /** + * @return mongo client + */ + public MongoClient getMongoClient() { + return mongoClient; + } + + /** + * + * @return mongo database + */ + public MongoDatabase getMongoDatabase() { + return database; + } + + /** + * + * @return accounts collection + */ + public MongoCollection getAccountsCollection() { + return accountsCollection; + } + + + @Override + public void setFunds(String bankAccount, int amount) { + Document search = new Document("_id", bankAccount); + Document update = new Document("_id", bankAccount).append("funds", amount); + accountsCollection.updateOne(search, new Document("$set", update), new UpdateOptions().upsert(true)); + } + + @Override + public int getFunds(String bankAccount) { + Document search = new Document("_id", bankAccount); + ArrayList results = accountsCollection.find(search).limit(1).into(new ArrayList()); + if (results.size() > 0) { + return results.get(0).getInteger("funds"); + } else { + return 0; + } + } + + @Override + public boolean transferFunds(int amount, String sourceBackAccount, String destinationBankAccount) { + int sourceFunds = getFunds(sourceBackAccount); + if (sourceFunds < amount) { + return false; + } else { + int destFunds = getFunds(destinationBankAccount); + setFunds(sourceBackAccount, sourceFunds - amount); + setFunds(destinationBankAccount, destFunds + amount); + return true; + } + } +} diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java index 0a0177f25..c9bc301fc 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java @@ -23,7 +23,7 @@ package com.iluwatar.hexagonal.module; import com.google.inject.AbstractModule; -import com.iluwatar.hexagonal.banking.InMemoryBank; +import com.iluwatar.hexagonal.banking.MongoBank; import com.iluwatar.hexagonal.banking.WireTransfers; import com.iluwatar.hexagonal.database.LotteryTicketRepository; import com.iluwatar.hexagonal.database.MongoTicketRepository; @@ -38,6 +38,6 @@ public class LotteryModule extends AbstractModule { protected void configure() { bind(LotteryTicketRepository.class).to(MongoTicketRepository.class); bind(LotteryNotifications.class).to(StdOutNotifications.class); - bind(WireTransfers.class).to(InMemoryBank.class); + bind(WireTransfers.class).to(MongoBank.class); } } diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/InMemoryBankTest.java similarity index 98% rename from hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java rename to hexagonal/src/test/java/com/iluwatar/hexagonal/banking/InMemoryBankTest.java index 25fbf460c..c5efda240 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/InMemoryBankTest.java @@ -32,7 +32,7 @@ import org.junit.Test; * Tests for banking * */ -public class WireTransfersTest { +public class InMemoryBankTest { private final WireTransfers bank = new InMemoryBank(); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java new file mode 100644 index 000000000..ad142f028 --- /dev/null +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java @@ -0,0 +1,68 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.hexagonal.banking; + +import com.mongodb.MongoClient; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Tests for Mongo banking adapter + */ +@Ignore +public class MongoBankTest { + + private static final String TEST_HOST = "localhost"; + private static final int TEST_PORT = 27017; + private static final String TEST_DB = "lotteryDBTest"; + private static final String TEST_ACCOUNTS_COLLECTION = "testAccounts"; + + private MongoBank mongoBank; + + @Before + public void init() { + MongoClient mongoClient = new MongoClient(TEST_HOST, TEST_PORT); + mongoClient.dropDatabase(TEST_DB); + mongoClient.close(); + mongoBank = new MongoBank(TEST_HOST, TEST_PORT, TEST_DB, TEST_ACCOUNTS_COLLECTION); + } + + @Test + public void testSetup() { + assertEquals(0, mongoBank.getAccountsCollection().count()); + } + + @Test + public void testFundTransfers() { + assertEquals(0, mongoBank.getFunds("000-000")); + mongoBank.setFunds("000-000", 10); + assertEquals(10, mongoBank.getFunds("000-000")); + assertEquals(0, mongoBank.getFunds("111-111")); + mongoBank.transferFunds(9, "000-000", "111-111"); + assertEquals(1, mongoBank.getFunds("000-000")); + assertEquals(9, mongoBank.getFunds("111-111")); + } +} diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java index 09a2772bd..45fa1cc67 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java @@ -44,9 +44,9 @@ public class MongoTicketRepositoryTest { private static final String TEST_HOST = "localhost"; private static final int TEST_PORT = 27017; - private static final String TEST_DB = "lotteryDB"; - private static final String TEST_TICKETS_COLLECTION = "lotteryTickets"; - private static final String TEST_COUNTERS_COLLECTION = "counters"; + private static final String TEST_DB = "lotteryTestDB"; + private static final String TEST_TICKETS_COLLECTION = "lotteryTestTickets"; + private static final String TEST_COUNTERS_COLLECTION = "testCounters"; private MongoTicketRepository repository;