From b51bca1a6744f2d18d69f52047e70fd5948131f7 Mon Sep 17 00:00:00 2001 From: Arnab Sen Date: Sat, 16 Apr 2022 23:14:01 +0530 Subject: [PATCH] fix: monitor pattern is not being built (#1956) * fix: update the version in pom.xml * fixes the checksyle error and adds javadoc * fix: bugs and code-smells in sonarcloud * replaced logger library with Slf4j * fix tests and add a previously dropped method * adds license * fix: codesmells and bug * replace Random with SecureRandom * test: add tests for Main to improve coverage --- monitor/pom.xml | 4 +- .../main/java/com/iluwatar/monitor/Bank.java | 98 ++++++++++++++----- .../main/java/com/iluwatar/monitor/Main.java | 97 ++++++++++-------- .../test/java/com/iluwater/java/BankTest.java | 55 ----------- .../java/com/iluwatar/monitor/BankTest.java | 71 ++++++++++++++ .../java/com/iluwatar/monitor/MainTest.java | 42 ++++++++ pom.xml | 1 + 7 files changed, 245 insertions(+), 123 deletions(-) delete mode 100644 monitor/src/main/test/java/com/iluwater/java/BankTest.java create mode 100644 monitor/src/test/java/com/iluwatar/monitor/BankTest.java create mode 100644 monitor/src/test/java/com/iluwatar/monitor/MainTest.java diff --git a/monitor/pom.xml b/monitor/pom.xml index f33735019..9246f33ca 100644 --- a/monitor/pom.xml +++ b/monitor/pom.xml @@ -21,9 +21,9 @@ 4.0.0 - java-design-patterns com.iluwatar - 1.24.0-SNAPSHOT + java-design-patterns + 1.26.0-SNAPSHOT monitor diff --git a/monitor/src/main/java/com/iluwatar/monitor/Bank.java b/monitor/src/main/java/com/iluwatar/monitor/Bank.java index d4defa6d1..365212965 100644 --- a/monitor/src/main/java/com/iluwatar/monitor/Bank.java +++ b/monitor/src/main/java/com/iluwatar/monitor/Bank.java @@ -1,37 +1,87 @@ +/* +*The MIT License +*Copyright © 2014-2021 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.monitor; import java.util.Arrays; -import java.util.logging.Logger; +import lombok.extern.slf4j.Slf4j; -// Bank class implements the Monitor pattern +/** Bank Definition. */ +@Slf4j public class Bank { - private int[] accounts; - Logger logger; + private final int[] accounts; - public Bank(int accountNum, int baseAmount, Logger logger) { - this.logger = logger; - accounts = new int[accountNum]; - Arrays.fill(accounts, baseAmount); - } + /** + * Constructor. + * + * @param accountNum - account number + * @param baseAmount - base amount + */ + public Bank(int accountNum, int baseAmount) { + accounts = new int[accountNum]; + Arrays.fill(accounts, baseAmount); + } - public synchronized void transfer(int accountA, int accountB, int amount) { - if (accounts[accountA] >= amount) { - accounts[accountB] += amount; - accounts[accountA] -= amount; - logger.info("Transferred from account :" + accountA + " to account :" + accountB + " , amount :" + amount + " . balance :" + getBalance()); - } + /** + * Transfer amounts from one account to another. + * + * @param accountA - source account + * @param accountB - destination account + * @param amount - amount to be transferred + */ + public synchronized void transfer(int accountA, int accountB, int amount) { + if (accounts[accountA] >= amount) { + accounts[accountB] += amount; + accounts[accountA] -= amount; + LOGGER.info( + "Transferred from account: {} to account: {} , amount: {} , balance: {}", + accountA, + accountB, + amount, + getBalance()); } + } - public synchronized int getBalance() { - int balance = 0; - for (int account : accounts) { - balance += account; - } - return balance; + /** + * Calculates the total balance. + * + * @return balance + */ + public synchronized int getBalance() { + int balance = 0; + for (int account : accounts) { + balance += account; } + return balance; + } - public int[] getAccounts() { - return accounts; - } + /** + * Get all accounts. + * + * @return accounts + */ + public int[] getAccounts() { + return accounts; + } } diff --git a/monitor/src/main/java/com/iluwatar/monitor/Main.java b/monitor/src/main/java/com/iluwatar/monitor/Main.java index c1e1bcccb..317cbd337 100644 --- a/monitor/src/main/java/com/iluwatar/monitor/Main.java +++ b/monitor/src/main/java/com/iluwatar/monitor/Main.java @@ -1,60 +1,73 @@ /* - * The MIT License - * Copyright © 2014-2021 Ilkka Seppälä + *The MIT License + *Copyright © 2014-2021 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: + *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 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. + *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.monitor; -import java.util.*; +import java.security.SecureRandom; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.logging.Logger; +import lombok.extern.slf4j.Slf4j; /** - *

The Monitor pattern is used in concurrent algorithms to achieve mutual exclusion.

+ * The Monitor pattern is used in concurrent algorithms to achieve mutual exclusion. * - *

Bank is a simple class that transfers money from an account to another account using - * {@link Bank#transfer}. It can also return the balance of the bank account stored in the bank.

+ *

Bank is a simple class that transfers money from an account to another account using {@link + * Bank#transfer}. It can also return the balance of the bank account stored in the bank. * - *

Main class uses ThreadPool to run threads that do transactions on the bank accounts.

+ *

Main class uses ThreadPool to run threads that do transactions on the bank accounts. */ - +@Slf4j public class Main { - public static void main(String[] args) { - Logger logger = Logger.getLogger("monitor"); - var bank = new Bank(4, 1000, logger); - Runnable runnable = () -> { - try { - Thread.sleep((long) (Math.random() * 1000)); - Random random = new Random(); - for (int i = 0; i < 1000000; i++) - bank.transfer(random.nextInt(4), random.nextInt(4), (int) (Math.random() * 1000)); - } catch (InterruptedException e) { - logger.info(e.getMessage()); - } - }; - ExecutorService executorService = Executors.newFixedThreadPool(5); - for (int i = 0; i < 5; i++) { - executorService.execute(runnable); - } + /** + * Runner to perform a bunch of transfers and handle exception. + * + * @param bank bank object + */ + public static void runner(Bank bank) { + try { + SecureRandom random = new SecureRandom(); + Thread.sleep(random.nextInt(1000)); + for (int i = 0; i < 1000000; i++) { + bank.transfer(random.nextInt(4), random.nextInt(4), random.nextInt()); + } + } catch (InterruptedException e) { + LOGGER.info(e.getMessage()); + Thread.currentThread().interrupt(); } -} \ No newline at end of file + } + + /** + * Program entry point. + * + * @param args command line args + */ + public static void main(String[] args) { + var bank = new Bank(4, 1000); + Runnable runnable = () -> runner(bank); + ExecutorService executorService = Executors.newFixedThreadPool(5); + for (int i = 0; i < 5; i++) { + executorService.execute(runnable); + } + } +} diff --git a/monitor/src/main/test/java/com/iluwater/java/BankTest.java b/monitor/src/main/test/java/com/iluwater/java/BankTest.java deleted file mode 100644 index eab7d7a3c..000000000 --- a/monitor/src/main/test/java/com/iluwater/java/BankTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.iluwater.java; - -import com.iluwatar.monitor.Bank; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assumptions.*; - -import java.util.logging.Logger; - -public class BankTest { - - private static Bank bank; - private static final int ACCOUNT_NUM = 4; - private static final int BASE_AMOUNT = 1000; - private static final Logger LOGGER = Logger.getLogger("monitor"); - - @BeforeAll - public static void Setup() { - bank = new Bank(ACCOUNT_NUM, BASE_AMOUNT, LOGGER); - } - - @Test - public void GetAccountHaveNotBeNull() { - assertNotNull(bank.getAccounts()); - } - - @Test - public void LengthOfAccountsHaveToEqualsToAccountNumConstant() { - assumeTrue(bank.getAccounts() != null); - assertEquals(ACCOUNT_NUM, bank.getAccounts().length); - } - - @Test - public void TransferMethodHaveToTransferAmountFromAnAccountToOtherAccount() { - bank.transfer(0, 1, 1000); - int accounts[] = bank.getAccounts(); - assertEquals(0, accounts[0]); - assertEquals(2000, 2000); - } - - @Test - public void BalanceHaveToBeOK() { - assertEquals(4000, bank.getBalance()); - } - - - @AfterAll - public static void TearDown() { - bank = null; - } - -} diff --git a/monitor/src/test/java/com/iluwatar/monitor/BankTest.java b/monitor/src/test/java/com/iluwatar/monitor/BankTest.java new file mode 100644 index 000000000..a961ec091 --- /dev/null +++ b/monitor/src/test/java/com/iluwatar/monitor/BankTest.java @@ -0,0 +1,71 @@ +/* + *The MIT License + *Copyright © 2014-2021 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.monitor; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +public class BankTest { + + private static final int ACCOUNT_NUM = 4; + private static final int BASE_AMOUNT = 1000; + private static Bank bank; + + @BeforeAll + public static void Setup() { + bank = new Bank(ACCOUNT_NUM, BASE_AMOUNT); + } + + @AfterAll + public static void TearDown() { + bank = null; + } + + @Test + void GetAccountHaveNotBeNull() { + assertNotNull(bank.getAccounts()); + } + + @Test + void LengthOfAccountsHaveToEqualsToAccountNumConstant() { + assumeTrue(bank.getAccounts() != null); + assertEquals(ACCOUNT_NUM, bank.getAccounts().length); + } + + @Test + void TransferMethodHaveToTransferAmountFromAnAccountToOtherAccount() { + bank.transfer(0, 1, 1000); + int[] accounts = bank.getAccounts(); + assertEquals(0, accounts[0]); + assertEquals(2000, accounts[1]); + } + + @Test + void BalanceHaveToBeOK() { + assertEquals(4000, bank.getBalance()); + } +} diff --git a/monitor/src/test/java/com/iluwatar/monitor/MainTest.java b/monitor/src/test/java/com/iluwatar/monitor/MainTest.java new file mode 100644 index 000000000..75a313519 --- /dev/null +++ b/monitor/src/test/java/com/iluwatar/monitor/MainTest.java @@ -0,0 +1,42 @@ +/* + *The MIT License + *Copyright © 2014-2021 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.monitor; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +/** Test if the application starts without throwing an exception. */ +class MainTest { + + @Test + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> Main.main(new String[] {})); + } + + @Test + void RunnerExecuteWithoutException() { + var bank = new Bank(4, 1000); + assertDoesNotThrow(() -> Main.runner(bank)); + } +} diff --git a/pom.xml b/pom.xml index e58146c72..064e7c1a7 100644 --- a/pom.xml +++ b/pom.xml @@ -85,6 +85,7 @@ abstract-factory + monitor tls builder factory-method