Java 11 migration: patterns (remaining b-c) (#1081)

* Moves business-delegate pattern  to java 11

* Moves bytecode pattern  to java 11

* Moves caching pattern  to java 11

* Moves callback pattern  to java 11

* Moves chain pattern  to java 11

* Moves circuit-breaker pattern  to java 11

* Moves collection-pipeline pattern  to java 11

* Moves command pattern  to java 11

* Moves commander pattern  to java 11

* Moves composite pattern  to java 11

* Corrects test cases
This commit is contained in:
Anurag Agarwal 2019-11-13 01:26:46 +05:30 committed by Ilkka Seppälä
parent 6ef840f3cf
commit 33ea7335b1
63 changed files with 798 additions and 979 deletions

View File

@ -46,15 +46,15 @@ public class App {
*/
public static void main(String[] args) {
BusinessDelegate businessDelegate = new BusinessDelegate();
BusinessLookup businessLookup = new BusinessLookup();
var businessDelegate = new BusinessDelegate();
var businessLookup = new BusinessLookup();
businessLookup.setEjbService(new EjbService());
businessLookup.setJmsService(new JmsService());
businessDelegate.setLookupService(businessLookup);
businessDelegate.setServiceType(ServiceType.EJB);
Client client = new Client(businessDelegate);
var client = new Client(businessDelegate);
client.doTask();
businessDelegate.setServiceType(ServiceType.JMS);

View File

@ -76,7 +76,7 @@ public class BusinessDelegateTest {
public void testBusinessDelegate() {
// setup a client object
Client client = new Client(businessDelegate);
var client = new Client(businessDelegate);
// set the service type
businessDelegate.setServiceType(ServiceType.EJB);

View File

@ -24,7 +24,6 @@
package com.iluwatar.bytecode;
import com.iluwatar.bytecode.util.InstructionConverterUtil;
import java.util.Stack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -51,12 +50,12 @@ public class App {
*/
public static void main(String[] args) {
Wizard wizard = new Wizard();
var wizard = new Wizard();
wizard.setHealth(45);
wizard.setAgility(7);
wizard.setWisdom(11);
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.getWizards()[0] = wizard;
interpretInstruction("LITERAL 0", vm);
@ -74,9 +73,8 @@ public class App {
}
private static void interpretInstruction(String instruction, VirtualMachine vm) {
InstructionConverterUtil converter = new InstructionConverterUtil();
vm.execute(converter.convertToByteCode(instruction));
Stack<Integer> stack = vm.getStack();
vm.execute(InstructionConverterUtil.convertToByteCode(instruction));
var stack = vm.getStack();
LOGGER.info(instruction + String.format("%" + (12 - instruction.length()) + "s", "") + stack);
}
}

View File

@ -40,7 +40,7 @@ public enum Instruction {
ADD(10),
DIVIDE(11);
private int value;
private final int value;
Instruction(int value) {
this.value = value;
@ -57,7 +57,7 @@ public enum Instruction {
* @return representation of the instruction
*/
public static Instruction getInstruction(int value) {
for (int i = 0; i < Instruction.values().length; i++) {
for (var i = 0; i < Instruction.values().length; i++) {
if (Instruction.values()[i].getIntValue() == value) {
return Instruction.values()[i];
}

View File

@ -30,7 +30,7 @@ import java.util.Stack;
*/
public class VirtualMachine {
private Stack<Integer> stack = new Stack();
private Stack<Integer> stack = new Stack<>();
private Wizard[] wizards = new Wizard[2];
@ -38,7 +38,7 @@ public class VirtualMachine {
* Constructor.
*/
public VirtualMachine() {
for (int i = 0; i < wizards.length; i++) {
for (var i = 0; i < wizards.length; i++) {
wizards[i] = new Wizard();
}
}
@ -49,10 +49,8 @@ public class VirtualMachine {
* @param bytecode to execute
*/
public void execute(int[] bytecode) {
for (int i = 0; i < bytecode.length; i++) {
for (var i = 0; i < bytecode.length; i++) {
Instruction instruction = Instruction.getInstruction(bytecode[i]);
int wizard;
int amount;
switch (instruction) {
case LITERAL:
// Read the next byte from the bytecode.
@ -60,8 +58,8 @@ public class VirtualMachine {
stack.push(value);
break;
case SET_AGILITY:
amount = stack.pop();
wizard = stack.pop();
var amount = stack.pop();
var wizard = stack.pop();
setAgility(wizard, amount);
break;
case SET_WISDOM:
@ -87,8 +85,8 @@ public class VirtualMachine {
stack.push(getWisdom(wizard));
break;
case ADD:
int a = stack.pop();
int b = stack.pop();
var a = stack.pop();
var b = stack.pop();
stack.push(a + b);
break;
case DIVIDE:

View File

@ -40,15 +40,15 @@ public class InstructionConverterUtil {
return new int[0];
}
String[] splitedInstructions = instructions.trim().split(" ");
int[] bytecode = new int[splitedInstructions.length];
for (int i = 0; i < splitedInstructions.length; i++) {
var splitedInstructions = instructions.trim().split(" ");
var bytecode = new int[splitedInstructions.length];
for (var i = 0; i < splitedInstructions.length; i++) {
if (isValidInstruction(splitedInstructions[i])) {
bytecode[i] = Instruction.valueOf(splitedInstructions[i]).getIntValue();
} else if (isValidInt(splitedInstructions[i])) {
bytecode[i] = Integer.valueOf(splitedInstructions[i]);
bytecode[i] = Integer.parseInt(splitedInstructions[i]);
} else {
String errorMessage = "Invalid instruction or number: " + splitedInstructions[i];
var errorMessage = "Invalid instruction or number: " + splitedInstructions[i];
throw new IllegalArgumentException(errorMessage);
}
}

View File

@ -32,7 +32,6 @@ public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -36,11 +36,11 @@ public class VirtualMachineTest {
@Test
public void testLiteral() {
int[] bytecode = new int[2];
var bytecode = new int[2];
bytecode[0] = LITERAL.getIntValue();
bytecode[1] = 10;
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.execute(bytecode);
assertEquals(1, vm.getStack().size());
@ -49,15 +49,15 @@ public class VirtualMachineTest {
@Test
public void testSetHealth() {
int wizardNumber = 0;
int[] bytecode = new int[5];
var wizardNumber = 0;
var bytecode = new int[5];
bytecode[0] = LITERAL.getIntValue();
bytecode[1] = wizardNumber;
bytecode[2] = LITERAL.getIntValue();
bytecode[3] = 50; // health amount
bytecode[4] = SET_HEALTH.getIntValue();
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.execute(bytecode);
assertEquals(50, vm.getWizards()[wizardNumber].getHealth());
@ -65,15 +65,15 @@ public class VirtualMachineTest {
@Test
public void testSetAgility() {
int wizardNumber = 0;
int[] bytecode = new int[5];
var wizardNumber = 0;
var bytecode = new int[5];
bytecode[0] = LITERAL.getIntValue();
bytecode[1] = wizardNumber;
bytecode[2] = LITERAL.getIntValue();
bytecode[3] = 50; // agility amount
bytecode[4] = SET_AGILITY.getIntValue();
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.execute(bytecode);
assertEquals(50, vm.getWizards()[wizardNumber].getAgility());
@ -81,15 +81,15 @@ public class VirtualMachineTest {
@Test
public void testSetWisdom() {
int wizardNumber = 0;
int[] bytecode = new int[5];
var wizardNumber = 0;
var bytecode = new int[5];
bytecode[0] = LITERAL.getIntValue();
bytecode[1] = wizardNumber;
bytecode[2] = LITERAL.getIntValue();
bytecode[3] = 50; // wisdom amount
bytecode[4] = SET_WISDOM.getIntValue();
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.execute(bytecode);
assertEquals(50, vm.getWizards()[wizardNumber].getWisdom());
@ -97,8 +97,8 @@ public class VirtualMachineTest {
@Test
public void testGetHealth() {
int wizardNumber = 0;
int[] bytecode = new int[8];
var wizardNumber = 0;
var bytecode = new int[8];
bytecode[0] = LITERAL.getIntValue();
bytecode[1] = wizardNumber;
bytecode[2] = LITERAL.getIntValue();
@ -108,7 +108,7 @@ public class VirtualMachineTest {
bytecode[6] = wizardNumber;
bytecode[7] = GET_HEALTH.getIntValue();
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.execute(bytecode);
assertEquals(Integer.valueOf(50), vm.getStack().pop());
@ -116,13 +116,13 @@ public class VirtualMachineTest {
@Test
public void testPlaySound() {
int wizardNumber = 0;
int[] bytecode = new int[3];
var wizardNumber = 0;
var bytecode = new int[3];
bytecode[0] = LITERAL.getIntValue();
bytecode[1] = wizardNumber;
bytecode[2] = PLAY_SOUND.getIntValue();
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.execute(bytecode);
assertEquals(0, vm.getStack().size());
@ -131,13 +131,13 @@ public class VirtualMachineTest {
@Test
public void testSpawnParticles() {
int wizardNumber = 0;
int[] bytecode = new int[3];
var wizardNumber = 0;
var bytecode = new int[3];
bytecode[0] = LITERAL.getIntValue();
bytecode[1] = wizardNumber;
bytecode[2] = SPAWN_PARTICLES.getIntValue();
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
vm.execute(bytecode);
assertEquals(0, vm.getStack().size());
@ -146,9 +146,9 @@ public class VirtualMachineTest {
@Test
public void testInvalidInstruction() {
int[] bytecode = new int[1];
var bytecode = new int[1];
bytecode[0] = 999;
VirtualMachine vm = new VirtualMachine();
var vm = new VirtualMachine();
assertThrows(IllegalArgumentException.class, () -> vm.execute(bytecode));
}

View File

@ -34,19 +34,19 @@ import org.junit.jupiter.api.Test;
public class InstructionConverterUtilTest {
@Test
public void testEmptyInstruction() {
String instruction = "";
var instruction = "";
int[] bytecode = InstructionConverterUtil.convertToByteCode(instruction);
var bytecode = InstructionConverterUtil.convertToByteCode(instruction);
Assertions.assertEquals(0, bytecode.length);
}
@Test
public void testInstructions() {
String instructions =
"LITERAL 35 SET_HEALTH SET_WISDOM SET_AGILITY PLAY_SOUND SPAWN_PARTICLES GET_HEALTH ADD DIVIDE";
var instructions = "LITERAL 35 SET_HEALTH SET_WISDOM SET_AGILITY PLAY_SOUND"
+ " SPAWN_PARTICLES GET_HEALTH ADD DIVIDE";
int[] bytecode = InstructionConverterUtil.convertToByteCode(instructions);
var bytecode = InstructionConverterUtil.convertToByteCode(instructions);
Assertions.assertEquals(10, bytecode.length);
Assertions.assertEquals(Instruction.LITERAL.getIntValue(), bytecode[0]);

View File

@ -76,7 +76,7 @@ public class App {
// true to run the tests with MongoDB (provided that MongoDB is
// installed and socket connection is open).
AppManager.initCacheCapacity(3);
App app = new App();
var app = new App();
app.useReadAndWriteThroughStrategy();
app.useReadThroughAndWriteAroundStrategy();
app.useReadThroughAndWriteBehindStrategy();
@ -90,7 +90,7 @@ public class App {
LOGGER.info("# CachingPolicy.THROUGH");
AppManager.initCachingPolicy(CachingPolicy.THROUGH);
UserAccount userAccount1 = new UserAccount("001", "John", "He is a boy.");
var userAccount1 = new UserAccount("001", "John", "He is a boy.");
AppManager.save(userAccount1);
LOGGER.info(AppManager.printCacheContent());
@ -105,7 +105,7 @@ public class App {
LOGGER.info("# CachingPolicy.AROUND");
AppManager.initCachingPolicy(CachingPolicy.AROUND);
UserAccount userAccount2 = new UserAccount("002", "Jane", "She is a girl.");
var userAccount2 = new UserAccount("002", "Jane", "She is a girl.");
AppManager.save(userAccount2);
LOGGER.info(AppManager.printCacheContent());
@ -127,9 +127,9 @@ public class App {
LOGGER.info("# CachingPolicy.BEHIND");
AppManager.initCachingPolicy(CachingPolicy.BEHIND);
UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food.");
UserAccount userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
UserAccount userAccount5 = new UserAccount("005", "Isaac", "He is allergic to mustard.");
var userAccount3 = new UserAccount("003", "Adam", "He likes food.");
var userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
var userAccount5 = new UserAccount("005", "Isaac", "He is allergic to mustard.");
AppManager.save(userAccount3);
AppManager.save(userAccount4);
@ -152,9 +152,9 @@ public class App {
AppManager.initCachingPolicy(CachingPolicy.ASIDE);
LOGGER.info(AppManager.printCacheContent());
UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food.");
UserAccount userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
UserAccount userAccount5 = new UserAccount("005", "Isaac", "He is allergic to mustard.");
var userAccount3 = new UserAccount("003", "Adam", "He likes food.");
var userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
var userAccount5 = new UserAccount("005", "Isaac", "He is allergic to mustard.");
AppManager.save(userAccount3);
AppManager.save(userAccount4);
AppManager.save(userAccount5);

View File

@ -24,6 +24,7 @@
package com.iluwatar.caching;
import java.text.ParseException;
import java.util.Optional;
/**
* AppManager helps to bridge the gap in communication between the main class and the application's
@ -116,16 +117,12 @@ public final class AppManager {
* Cache-Aside find user account helper.
*/
private static UserAccount findAside(String userId) {
UserAccount userAccount = CacheStore.get(userId);
if (userAccount != null) {
return userAccount;
}
userAccount = DbManager.readFromDb(userId);
if (userAccount != null) {
CacheStore.set(userId, userAccount);
}
return Optional.ofNullable(CacheStore.get(userId))
.or(() -> {
Optional<UserAccount> userAccount = Optional.ofNullable(DbManager.readFromDb(userId));
userAccount.ifPresent(account -> CacheStore.set(userId, account));
return userAccount;
})
.orElse(null);
}
}

View File

@ -24,6 +24,8 @@
package com.iluwatar.caching;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,7 +36,7 @@ public class CacheStore {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheStore.class);
static LruCache cache;
private static LruCache cache;
private CacheStore() {
}
@ -134,27 +136,22 @@ public class CacheStore {
*/
public static void flushCache() {
LOGGER.info("# flushCache...");
if (null == cache) {
return;
}
List<UserAccount> listOfUserAccounts = cache.getCacheDataInListForm();
for (UserAccount userAccount : listOfUserAccounts) {
DbManager.upsertDb(userAccount);
}
Optional.ofNullable(cache)
.map(LruCache::getCacheDataInListForm)
.orElse(List.of())
.forEach(DbManager::updateDb);
}
/**
* Print user accounts.
*/
public static String print() {
List<UserAccount> listOfUserAccounts = cache.getCacheDataInListForm();
StringBuilder sb = new StringBuilder();
sb.append("\n--CACHE CONTENT--\n");
for (UserAccount userAccount : listOfUserAccounts) {
sb.append(userAccount.toString() + "\n");
}
sb.append("----\n");
return sb.toString();
return Optional.ofNullable(cache)
.map(LruCache::getCacheDataInListForm)
.orElse(List.of())
.stream()
.map(userAccount -> userAccount.toString() + "\n")
.collect(Collectors.joining("", "\n--CACHE CONTENT--\n", "----\n"));
}
/**

View File

@ -25,7 +25,6 @@ package com.iluwatar.caching;
import com.iluwatar.caching.constants.CachingConstants;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.UpdateOptions;
import java.text.ParseException;
@ -87,7 +86,7 @@ public final class DbManager {
e.printStackTrace();
}
}
FindIterable<Document> iterable = db
var iterable = db
.getCollection(CachingConstants.USER_ACCOUNT)
.find(new Document(CachingConstants.USER_ID, userId));
if (iterable == null) {

View File

@ -67,7 +67,7 @@ public class LruCache {
*/
public UserAccount get(String userId) {
if (cache.containsKey(userId)) {
Node node = cache.get(userId);
var node = cache.get(userId);
remove(node);
setHead(node);
return node.userAccount;
@ -111,12 +111,12 @@ public class LruCache {
*/
public void set(String userId, UserAccount userAccount) {
if (cache.containsKey(userId)) {
Node old = cache.get(userId);
var old = cache.get(userId);
old.userAccount = userAccount;
remove(old);
setHead(old);
} else {
Node newNode = new Node(userId, userAccount);
var newNode = new Node(userId, userAccount);
if (cache.size() >= capacity) {
LOGGER.info("# Cache is FULL! Removing {} from cache...", end.userId);
cache.remove(end.userId); // remove LRU data from cache.
@ -137,7 +137,7 @@ public class LruCache {
* Invalidate cache for user.
*/
public void invalidate(String userId) {
Node toBeRemoved = cache.remove(userId);
var toBeRemoved = cache.remove(userId);
if (toBeRemoved != null) {
LOGGER.info("# {} has been updated! Removing older version from cache...", userId);
remove(toBeRemoved);
@ -165,8 +165,8 @@ public class LruCache {
* Returns cache data in list form.
*/
public List<UserAccount> getCacheDataInListForm() {
List<UserAccount> listOfCacheData = new ArrayList<>();
Node temp = head;
var listOfCacheData = new ArrayList<UserAccount>();
var temp = head;
while (temp != null) {
listOfCacheData.add(temp.userAccount);
temp = temp.next;

View File

@ -32,8 +32,7 @@ import java.io.IOException;
*/
public class AppTest {
@Test
public void test() throws IOException {
String[] args = {};
App.main(args);
public void test() {
App.main(new String[]{});
}
}

View File

@ -27,22 +27,21 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class CachingTest {
App app;
private App app;
/**
* Setup of application test includes: initializing DB connection and cache size/capacity.
*/
@BeforeEach
public void setUp() {
AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
// VirtualDB (instead of MongoDB) was used in running the JUnit tests
// to avoid Maven compilation errors. Set flag to true to run the
// tests with MongoDB (provided that MongoDB is installed and socket
// connection is open).
AppManager.initDb(false);
AppManager.initCacheCapacity(3);
app = new App();
}

View File

@ -43,8 +43,7 @@ public final class App {
* Program entry point.
*/
public static void main(final String[] args) {
Task task = new SimpleTask();
Callback callback = () -> LOGGER.info("I'm done now.");
task.executeWith(callback);
var task = new SimpleTask();
task.executeWith(() -> LOGGER.info("I'm done now."));
}
}

View File

@ -42,8 +42,7 @@ public final class LambdasApp {
* Program entry point.
*/
public static void main(final String[] args) {
Task task = new SimpleTask();
Callback c = () -> LOGGER.info("I'm done now.");
task.executeWith(c);
var task = new SimpleTask();
task.executeWith(() -> LOGGER.info("I'm done now."));
}
}

View File

@ -23,6 +23,8 @@
package com.iluwatar.callback;
import java.util.Optional;
/**
* Template-method class for callback hook execution.
*/
@ -33,9 +35,7 @@ public abstract class Task {
*/
final void executeWith(final Callback callback) {
execute();
if (callback != null) {
callback.call();
}
Optional.ofNullable(callback).ifPresent(Callback::call);
}
public abstract void execute();

View File

@ -25,15 +25,12 @@ package com.iluwatar.callback;
import org.junit.jupiter.api.Test;
import java.io.IOException;
/**
* Tests that Callback example runs without errors.
*/
public class AppTest {
@Test
public void test() throws IOException {
String[] args = {};
App.main(args);
public void test() {
App.main(new String[]{});
}
}

View File

@ -23,14 +23,14 @@
package com.iluwatar.callback;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
* Add a field as a counter. Every time the callback method is called increment this field. Unit
* test checks that the field is being incremented.
*
* <p>
* Could be done with mock objects as well where the call method call is verified.
*/
public class CallbackTest {
@ -41,17 +41,17 @@ public class CallbackTest {
public void test() {
Callback callback = () -> callingCount++;
Task task = new SimpleTask();
var task = new SimpleTask();
assertEquals(new Integer(0), callingCount, "Initial calling count of 0");
assertEquals(Integer.valueOf(0), callingCount, "Initial calling count of 0");
task.executeWith(callback);
assertEquals(new Integer(1), callingCount, "Callback called once");
assertEquals(Integer.valueOf(1), callingCount, "Callback called once");
task.executeWith(callback);
assertEquals(new Integer(2), callingCount, "Callback called twice");
assertEquals(Integer.valueOf(2), callingCount, "Callback called twice");
}
}

View File

@ -43,7 +43,7 @@ public class App {
*/
public static void main(String[] args) {
OrcKing king = new OrcKing();
var king = new OrcKing();
king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));

View File

@ -28,7 +28,7 @@ package com.iluwatar.chain;
*/
public class OrcKing {
RequestHandler chain;
private RequestHandler chain;
public OrcKing() {
buildChain();

View File

@ -26,15 +26,12 @@ package com.iluwatar.chain;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,10 +23,11 @@
package com.iluwatar.chain;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.junit.jupiter.api.Test;
/**
* Date: 12/6/15 - 9:29 PM
*
@ -37,24 +38,23 @@ public class OrcKingTest {
/**
* All possible requests
*/
private static final Request[] REQUESTS = new Request[]{
private static final List<Request> REQUESTS = List.of(
new Request(RequestType.DEFEND_CASTLE, "Don't let the barbarians enter my castle!!"),
new Request(RequestType.TORTURE_PRISONER, "Don't just stand there, tickle him!"),
new Request(RequestType.COLLECT_TAX, "Don't steal, the King hates competition ..."),
};
new Request(RequestType.COLLECT_TAX, "Don't steal, the King hates competition ...")
);
@Test
public void testMakeRequest() {
final OrcKing king = new OrcKing();
final var king = new OrcKing();
for (final Request request : REQUESTS) {
REQUESTS.forEach(request -> {
king.makeRequest(request);
assertTrue(
request.isHandled(),
"Expected all requests from King to be handled, but [" + request + "] was not!"
);
}
});
}
}

View File

@ -24,12 +24,11 @@
package com.iluwatar.circuitbreaker;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
*
* Circuit Breaker test
*
*/
public class CircuitBreakerTest {
@ -71,7 +70,8 @@ public class CircuitBreakerTest {
try {
//Call with the paramater start_time set to huge amount of time in past so that service
//replies with "Ok". Also, state is CLOSED in start
var response = circuitBreaker.call("delayedService", System.nanoTime() - 60 * 1000 * 1000 * 1000);
var serviceStartTime = System.nanoTime() - 60 * 1000 * 1000 * 1000;
var response = circuitBreaker.call("delayedService", serviceStartTime);
assertEquals(response, "Delayed service is working");
} catch (Exception e) {
System.out.println(e.getMessage());

View File

@ -24,12 +24,11 @@
package com.iluwatar.circuitbreaker;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
*
* Monitoring Service test
*
*/
public class DelayedServiceTest {

View File

@ -24,12 +24,11 @@
package com.iluwatar.circuitbreaker;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
*
* Monitoring Service test
*
*/
public class MonitoringServiceTest {
@ -53,11 +52,11 @@ public class MonitoringServiceTest {
@Test
public void testRemoteResponse2() {
MonitoringService monitoringService = new MonitoringService();
CircuitBreaker circuitBreaker = new CircuitBreaker(1,1,100);
var monitoringService = new MonitoringService();
var circuitBreaker = new CircuitBreaker(1, 1, 100);
//Set time as current time as initially server fails
long serverStartTime = System.nanoTime();
String response = monitoringService.remoteResourceResponse(circuitBreaker, serverStartTime);
var serverStartTime = System.nanoTime();
var response = monitoringService.remoteResourceResponse(circuitBreaker, serverStartTime);
assertEquals(response, "Remote service not responding");
}
}

View File

@ -24,7 +24,6 @@
package com.iluwatar.collectionpipeline;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -46,31 +45,26 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
var cars = CarFactory.createCars();
List<Car> cars = CarFactory.createCars();
List<String> modelsImperative = ImperativeProgramming.getModelsAfter2000(cars);
var modelsImperative = ImperativeProgramming.getModelsAfter2000(cars);
LOGGER.info(modelsImperative.toString());
List<String> modelsFunctional = FunctionalProgramming.getModelsAfter2000(cars);
var modelsFunctional = FunctionalProgramming.getModelsAfter2000(cars);
LOGGER.info(modelsFunctional.toString());
Map<Category, List<Car>> groupingByCategoryImperative =
ImperativeProgramming.getGroupingOfCarsByCategory(cars);
var groupingByCategoryImperative = ImperativeProgramming.getGroupingOfCarsByCategory(cars);
LOGGER.info(groupingByCategoryImperative.toString());
Map<Category, List<Car>> groupingByCategoryFunctional =
FunctionalProgramming.getGroupingOfCarsByCategory(cars);
var groupingByCategoryFunctional = FunctionalProgramming.getGroupingOfCarsByCategory(cars);
LOGGER.info(groupingByCategoryFunctional.toString());
Person john = new Person(cars);
var john = new Person(cars);
List<Car> sedansOwnedImperative =
ImperativeProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
var sedansOwnedImperative = ImperativeProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
LOGGER.info(sedansOwnedImperative.toString());
List<Car> sedansOwnedFunctional =
FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
var sedansOwnedFunctional = FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
LOGGER.info(sedansOwnedFunctional.toString());
}
}

View File

@ -23,12 +23,12 @@
package com.iluwatar.collectionpipeline;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Imperative-style programming to iterate over the list and get the names of cars made later than
@ -57,26 +57,11 @@ public class ImperativeProgramming {
* @return {@link List} of {@link String} of car models built after year 2000
*/
public static List<String> getModelsAfter2000(List<Car> cars) {
List<Car> carsSortedByYear = new ArrayList<>();
for (Car car : cars) {
if (car.getYear() > 2000) {
carsSortedByYear.add(car);
}
}
Collections.sort(carsSortedByYear, new Comparator<Car>() {
public int compare(Car car1, Car car2) {
return new Integer(car1.getYear()).compareTo(car2.getYear());
}
});
List<String> models = new ArrayList<>();
for (Car car : carsSortedByYear) {
models.add(car.getModel());
}
return models;
return cars.stream()
.filter(car -> car.getYear() > 2000)
.sorted(Comparator.comparingInt(Car::getYear))
.map(Car::getModel)
.collect(Collectors.toList());
}
/**
@ -86,17 +71,7 @@ public class ImperativeProgramming {
* @return {@link Map} with category as key and cars belonging to that category as value
*/
public static Map<Category, List<Car>> getGroupingOfCarsByCategory(List<Car> cars) {
Map<Category, List<Car>> groupingByCategory = new HashMap<>();
for (Car car : cars) {
if (groupingByCategory.containsKey(car.getCategory())) {
groupingByCategory.get(car.getCategory()).add(car);
} else {
List<Car> categoryCars = new ArrayList<>();
categoryCars.add(car);
groupingByCategory.put(car.getCategory(), categoryCars);
}
}
return groupingByCategory;
return cars.stream().collect(Collectors.groupingBy(Car::getCategory));
}
/**
@ -107,25 +82,11 @@ public class ImperativeProgramming {
* @return {@link List} of {@link Car} to belonging to the group
*/
public static List<Car> getSedanCarsOwnedSortedByDate(List<Person> persons) {
List<Car> cars = new ArrayList<>();
for (Person person : persons) {
cars.addAll(person.getCars());
}
List<Car> sedanCars = new ArrayList<>();
for (Car car : cars) {
if (Category.SEDAN.equals(car.getCategory())) {
sedanCars.add(car);
}
}
sedanCars.sort(new Comparator<Car>() {
@Override
public int compare(Car o1, Car o2) {
return o1.getYear() - o2.getYear();
}
});
return sedanCars;
return persons.stream()
.map(Person::getCars)
.flatMap(Collection::stream)
.filter(car -> car.getCategory() == Category.SEDAN)
.sorted(Comparator.comparingInt(Car::getYear))
.collect(Collectors.toList());
}
}

View File

@ -54,12 +54,18 @@ public class AppTest {
@Test
public void testGetGroupingOfCarsByCategory() {
var modelsExpected = Map.of(
Category.CONVERTIBLE, List.of(new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
new Car("Chevrolet", "Geo Metro", 1992, Category.CONVERTIBLE)),
Category.SEDAN, List.of(new Car("Dodge", "Avenger", 2010, Category.SEDAN),
new Car("Ford", "Focus", 2012, Category.SEDAN)),
Category.JEEP, List.of(new Car("Jeep", "Wrangler", 2011, Category.JEEP),
new Car("Jeep", "Comanche", 1990, Category.JEEP)));
Category.CONVERTIBLE, List.of(
new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
new Car("Chevrolet", "Geo Metro", 1992, Category.CONVERTIBLE)
),
Category.SEDAN, List.of(
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
new Car("Ford", "Focus", 2012, Category.SEDAN)
),
Category.JEEP, List.of(
new Car("Jeep", "Wrangler", 2011, Category.JEEP),
new Car("Jeep", "Comanche", 1990, Category.JEEP))
);
var modelsFunctional = FunctionalProgramming.getGroupingOfCarsByCategory(cars);
var modelsImperative = ImperativeProgramming.getGroupingOfCarsByCategory(cars);
LOGGER.info("Category " + modelsFunctional);
@ -70,8 +76,10 @@ public class AppTest {
@Test
public void testGetSedanCarsOwnedSortedByDate() {
var john = new Person(cars);
var modelsExpected = List.of(new Car("Dodge", "Avenger", 2010, Category.SEDAN),
new Car("Ford", "Focus", 2012, Category.SEDAN));
var modelsExpected = List.of(
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
new Car("Ford", "Focus", 2012, Category.SEDAN)
);
var modelsFunctional = FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
var modelsImperative = ImperativeProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
assertEquals(modelsExpected, modelsFunctional);

View File

@ -49,8 +49,8 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
Wizard wizard = new Wizard();
Goblin goblin = new Goblin();
var wizard = new Wizard();
var goblin = new Goblin();
goblin.printStatus();

View File

@ -41,7 +41,7 @@ public class ShrinkSpell extends Command {
@Override
public void undo() {
if (oldSize != null && target != null) {
Size temp = target.getSize();
var temp = target.getSize();
target.setSize(oldSize);
oldSize = temp;
}

View File

@ -56,7 +56,7 @@ public class Wizard {
*/
public void undoLastSpell() {
if (!undoStack.isEmpty()) {
Command previousSpell = undoStack.pollLast();
var previousSpell = undoStack.pollLast();
redoStack.offerLast(previousSpell);
LOGGER.info("{} undoes {}", this, previousSpell);
previousSpell.undo();
@ -68,7 +68,7 @@ public class Wizard {
*/
public void redoLastSpell() {
if (!redoStack.isEmpty()) {
Command previousSpell = redoStack.pollLast();
var previousSpell = redoStack.pollLast();
undoStack.offerLast(previousSpell);
LOGGER.info("{} redoes {}", this, previousSpell);
previousSpell.redo();

View File

@ -25,15 +25,12 @@ package com.iluwatar.command;
import org.junit.jupiter.api.Test;
import java.io.IOException;
/**
* Tests that Command example runs without errors.
*/
public class AppTest {
@Test
public void test() throws IOException {
String[] args = {};
App.main(args);
public void test() {
App.main(new String[]{});
}
}

View File

@ -23,23 +23,23 @@
package com.iluwatar.command;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
* The Command pattern is a behavioral design pattern in which an object is used to encapsulate all
* information needed to perform an action or trigger an event at a later time. This information
* includes the method name, the object that owns the method and values for the method parameters.
*
* <p>Four terms always associated with the command pattern are command, receiver, invoker and
* client. A command object (spell) knows about the receiver (target) and invokes a method of
* the receiver.Values for parameters of the receiver method are stored in the command. The receiver
* client. A command object (spell) knows about the receiver (target) and invokes a method of the
* receiver.Values for parameters of the receiver method are stored in the command. The receiver
* then does the work. An invoker object (wizard) knows how to execute a command, and optionally
* does bookkeeping about the command execution. The invoker does not know anything about a
* concrete command, it knows only about command interface. Both an invoker object and several
* command objects are held by a client object (app). The client decides which commands to execute
* at which points. To execute a command, it passes the command object to the invoker object.
* does bookkeeping about the command execution. The invoker does not know anything about a concrete
* command, it knows only about command interface. Both an invoker object and several command
* objects are held by a client object (app). The client decides which commands to execute at which
* points. To execute a command, it passes the command object to the invoker object.
*/
public class CommandTest {
@ -53,8 +53,8 @@ public class CommandTest {
@Test
public void testCommand() {
Wizard wizard = new Wizard();
Goblin goblin = new Goblin();
var wizard = new Wizard();
var goblin = new Goblin();
wizard.castSpell(new ShrinkSpell(), goblin);
verifyGoblin(goblin, GOBLIN, Size.SMALL, Visibility.VISIBLE);
@ -79,7 +79,8 @@ public class CommandTest {
* This method asserts that the passed goblin object has the name as expectedName, size as
* expectedSize and visibility as expectedVisibility.
*
* @param goblin a goblin object whose state is to be verified against other parameters
* @param goblin a goblin object whose state is to be verified against other
* parameters
* @param expectedName expectedName of the goblin
* @param expectedSize expected size of the goblin
* @param expectedVisibility expected visibility of the goblin

View File

@ -40,51 +40,47 @@ import com.iluwatar.commander.shippingservice.ShippingService;
* available/unavailable.
*/
public class AppEmployeeDbFailCases {
final int numOfRetries = 3;
final long retryDuration = 30000;
final long queueTime = 240000; //4 mins
final long queueTaskTime = 60000; //1 min
final long paymentTime = 120000; //2 mins
final long messageTime = 150000; //2.5 mins
final long employeeTime = 240000; //4 mins
private final int numOfRetries = 3;
private final long retryDuration = 30000;
private final long queueTime = 240000; //4 mins
private final long queueTaskTime = 60000; //1 min
private final long paymentTime = 120000; //2 mins
private final long messageTime = 150000; //2.5 mins
private final long employeeTime = 240000; //4 mins
void employeeDatabaseUnavailableCase() throws Exception {
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh =
new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(),
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
QueueDatabase qdb =
var qdb =
new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException());
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void employeeDbSuccessCase() throws Exception {
PaymentService ps = new PaymentService(new PaymentDatabase());
ShippingService ss =
new ShippingService(new ShippingDatabase(), new ItemUnavailableException());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh =
new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase());
var ss = new ShippingService(new ShippingDatabase(), new ItemUnavailableException());
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
@ -95,7 +91,7 @@ public class AppEmployeeDbFailCases {
*/
public static void main(String[] args) throws Exception {
AppEmployeeDbFailCases aefc = new AppEmployeeDbFailCases();
var aefc = new AppEmployeeDbFailCases();
//aefc.employeeDatabaseUnavailableCase();
aefc.employeeDbSuccessCase();
}

View File

@ -40,42 +40,39 @@ import com.iluwatar.commander.shippingservice.ShippingService;
*/
public class AppMessagingFailCases {
final int numOfRetries = 3;
final long retryDuration = 30000;
final long queueTime = 240000; //4 mins
final long queueTaskTime = 60000; //1 min
final long paymentTime = 120000; //2 mins
final long messageTime = 150000; //2.5 mins
final long employeeTime = 240000; //4 mins
private final int numOfRetries = 3;
private final long retryDuration = 30000;
private final long queueTime = 240000; //4 mins
private final long queueTaskTime = 60000; //1 min
private final long paymentTime = 120000; //2 mins
private final long messageTime = 150000; //2.5 mins
private final long employeeTime = 240000; //4 mins
void messagingDatabaseUnavailableCasePaymentSuccess() throws Exception {
//rest is successful
PaymentService ps = new PaymentService(new PaymentDatabase());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase());
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void messagingDatabaseUnavailableCasePaymentError() throws Exception {
//rest is successful
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
@ -84,58 +81,54 @@ public class AppMessagingFailCases {
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void messagingDatabaseUnavailableCasePaymentFailure() throws Exception {
//rest is successful
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb =
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb =
new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException());
Commander c =
var c =
new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration, queueTime, queueTaskTime,
paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void messagingSuccessCase() throws Exception {
//done here
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
@ -146,7 +139,7 @@ public class AppMessagingFailCases {
*/
public static void main(String[] args) throws Exception {
AppMessagingFailCases amfc = new AppMessagingFailCases();
var amfc = new AppMessagingFailCases();
//amfc.messagingDatabaseUnavailableCasePaymentSuccess();
//amfc.messagingDatabaseUnavailableCasePaymentError();
//amfc.messagingDatabaseUnavailableCasePaymentFailure();

View File

@ -40,62 +40,58 @@ import com.iluwatar.commander.shippingservice.ShippingService;
*/
public class AppPaymentFailCases {
final int numOfRetries = 3;
final long retryDuration = 30000;
final long queueTime = 240000; //4 mins
final long queueTaskTime = 60000; //1 min
final long paymentTime = 120000; //2 mins
final long messageTime = 150000; //2.5 mins
final long employeeTime = 240000; //4 mins
private final int numOfRetries = 3;
private final long retryDuration = 30000;
private final long queueTime = 240000; //4 mins
private final long queueTaskTime = 60000; //1 min
private final long paymentTime = 120000; //2 mins
private final long messageTime = 150000; //2.5 mins
private final long employeeTime = 240000; //4 mins
void paymentNotPossibleCase() throws Exception {
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new PaymentDetailsErrorException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException());
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException());
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase(new DatabaseUnavailableException());
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void paymentDatabaseUnavailableCase() throws Exception {
//rest is successful
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void paymentSuccessCase() throws Exception {
//goes to message after 2 retries maybe - rest is successful for now
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
var ss = new ShippingService(new ShippingDatabase());
var ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException());
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase(new DatabaseUnavailableException());
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
@ -106,7 +102,7 @@ public class AppPaymentFailCases {
*/
public static void main(String[] args) throws Exception {
AppPaymentFailCases apfc = new AppPaymentFailCases();
var apfc = new AppPaymentFailCases();
//apfc.paymentNotPossibleCase();
//apfc.paymentDatabaseUnavailableCase();
apfc.paymentSuccessCase();

View File

@ -40,98 +40,93 @@ import com.iluwatar.commander.shippingservice.ShippingService;
*/
public class AppQueueFailCases {
final int numOfRetries = 3;
final long retryDuration = 30000;
final long queueTime = 240000; //4 mins
final long queueTaskTime = 60000; //1 min
final long paymentTime = 120000; //2 mins
final long messageTime = 150000; //2.5 mins
final long employeeTime = 240000; //4 mins
private final int numOfRetries = 3;
private final long retryDuration = 30000;
private final long queueTime = 240000; //4 mins
private final long queueTaskTime = 60000; //1 min
private final long paymentTime = 120000; //2 mins
private final long messageTime = 150000; //2.5 mins
private final long employeeTime = 240000; //4 mins
void queuePaymentTaskDatabaseUnavailableCase() throws Exception {
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb =
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb =
new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException());
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void queueMessageTaskDatabaseUnavailableCase() throws Exception {
PaymentService ps = new PaymentService(new PaymentDatabase());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase());
var ss = new ShippingService(new ShippingDatabase());
var ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb =
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb =
new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException());
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void queueEmployeeDbTaskDatabaseUnavailableCase() throws Exception {
PaymentService ps = new PaymentService(new PaymentDatabase());
ShippingService ss =
new ShippingService(new ShippingDatabase(), new ItemUnavailableException());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh =
new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase());
var ss = new ShippingService(new ShippingDatabase(), new ItemUnavailableException());
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
QueueDatabase qdb =
var qdb =
new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException());
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void queueSuccessCase() throws Exception {
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
ShippingService ss = new ShippingService(new ShippingDatabase());
MessagingService ms =
var ss = new ShippingService(new ShippingDatabase());
var ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb =
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb =
new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException());
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
@ -142,7 +137,7 @@ public class AppQueueFailCases {
*/
public static void main(String[] args) throws Exception {
AppQueueFailCases aqfc = new AppQueueFailCases();
var aqfc = new AppQueueFailCases();
//aqfc.queuePaymentTaskDatabaseUnavailableCase();
//aqfc.queueMessageTaskDatabaseUnavailableCase();
//aqfc.queueEmployeeDbTaskDatabaseUnavailableCase();

View File

@ -42,75 +42,69 @@ import com.iluwatar.commander.shippingservice.ShippingService;
*/
public class AppShippingFailCases {
final int numOfRetries = 3;
final long retryDuration = 30000;
final long queueTime = 240000; //4 mins
final long queueTaskTime = 60000; //1 min
final long paymentTime = 120000; //2 mins
final long messageTime = 150000; //2.5 mins
final long employeeTime = 240000; //4 mins
private final int numOfRetries = 3;
private final long retryDuration = 30000;
private final long queueTime = 240000; //4 mins
private final long queueTaskTime = 60000; //1 min
private final long paymentTime = 120000; //2 mins
private final long messageTime = 150000; //2.5 mins
private final long employeeTime = 240000; //4 mins
void itemUnavailableCase() throws Exception {
PaymentService ps = new PaymentService(new PaymentDatabase());
ShippingService ss =
new ShippingService(new ShippingDatabase(), new ItemUnavailableException());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var ps = new PaymentService(new PaymentDatabase());
var ss = new ShippingService(new ShippingDatabase(), new ItemUnavailableException());
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void shippingNotPossibleCase() throws Exception {
PaymentService ps = new PaymentService(new PaymentDatabase());
ShippingService ss =
new ShippingService(new ShippingDatabase(), new ShippingNotPossibleException());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var ps = new PaymentService(new PaymentDatabase());
var ss = new ShippingService(new ShippingDatabase(), new ShippingNotPossibleException());
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void shippingDatabaseUnavailableCase() throws Exception {
//rest is successful
PaymentService ps = new PaymentService(new PaymentDatabase());
ShippingService ss =
new ShippingService(new ShippingDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase());
var ss = new ShippingService(new ShippingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
MessagingService ms = new MessagingService(new MessagingDatabase());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var ms = new MessagingService(new MessagingDatabase());
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
void shippingSuccessCase() throws Exception {
//goes to payment after 2 retries maybe - rest is successful for now
PaymentService ps =
new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException());
ShippingService ss =
new ShippingService(new ShippingDatabase(), new DatabaseUnavailableException(),
var ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException());
var ss = new ShippingService(new ShippingDatabase(), new DatabaseUnavailableException(),
new DatabaseUnavailableException());
MessagingService ms =
new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException());
EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase());
QueueDatabase qdb = new QueueDatabase();
Commander c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
var ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException());
var eh = new EmployeeHandle(new EmployeeDatabase());
var qdb = new QueueDatabase();
var c = new Commander(eh, ps, ss, ms, qdb, numOfRetries, retryDuration,
queueTime, queueTaskTime, paymentTime, messageTime, employeeTime);
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
c.placeOrder(order);
}
@ -121,7 +115,7 @@ public class AppShippingFailCases {
*/
public static void main(String[] args) throws Exception {
AppShippingFailCases asfc = new AppShippingFailCases();
var asfc = new AppShippingFailCases();
//asfc.itemUnavailableCase();
//asfc.shippingNotPossibleCase();
//asfc.shippingDatabaseUnavailableCase();

View File

@ -36,7 +36,6 @@ import com.iluwatar.commander.queue.QueueDatabase;
import com.iluwatar.commander.queue.QueueTask;
import com.iluwatar.commander.queue.QueueTask.TaskType;
import com.iluwatar.commander.shippingservice.ShippingService;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -86,7 +85,7 @@ public class Commander {
private final long messageTime;
private final long employeeTime;
private boolean finalSiteMsgShown;
static final Logger LOG = LoggerFactory.getLogger(Commander.class);
private static final Logger LOG = LoggerFactory.getLogger(Commander.class);
//we could also have another db where it stores all orders
Commander(EmployeeHandle empDb, PaymentService paymentService, ShippingService shippingService,
@ -113,7 +112,7 @@ public class Commander {
}
private void sendShippingRequest(Order order) throws Exception {
ArrayList<Exception> list = shippingService.exceptionsList;
var list = shippingService.exceptionsList;
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
@ -131,7 +130,6 @@ public class Commander {
LOG.info("Order has been placed and will be shipped to you. Please wait while we make your"
+ " payment... ");
sendPaymentRequest(order);
return;
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
if (ShippingNotPossibleException.class.isAssignableFrom(err.getClass())) {
@ -153,9 +151,8 @@ public class Commander {
LOG.error("Order " + order.id + ": Shipping service unavailable, order not placed..");
finalSiteMsgShown = true;
}
return;
};
Retry<Order> r = new Retry<Order>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
r.perform(list, order);
}
@ -169,10 +166,8 @@ public class Commander {
} //if succeeded or failed, would have been dequeued, no attempt to make payment
return;
}
ArrayList<Exception> list = paymentService.exceptionsList;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
var list = paymentService.exceptionsList;
var t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
@ -184,16 +179,14 @@ public class Commander {
throw l.remove(0);
}
if (order.paid.equals(PaymentStatus.Trying)) {
String transactionId = paymentService.receiveRequest(order.price);
var transactionId = paymentService.receiveRequest(order.price);
order.paid = PaymentStatus.Done;
LOG.info("Order " + order.id + ": Payment successful, transaction Id: "
+ transactionId);
LOG.info("Order " + order.id + ": Payment successful, transaction Id: " + transactionId);
if (!finalSiteMsgShown) {
LOG.info("Payment made successfully, thank you for shopping with us!!");
finalSiteMsgShown = true;
}
sendSuccessMessage(order);
return;
}
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
@ -208,7 +201,6 @@ public class Commander {
o.paid = PaymentStatus.NotDone;
sendPaymentFailureMessage(o);
} else {
try {
if (o.messageSent.equals(MessageSent.NoneSent)) {
if (!finalSiteMsgShown) {
LOG.info("There was an error in payment. We are on it, and will get back to you "
@ -220,28 +212,23 @@ public class Commander {
}
if (o.paid.equals(PaymentStatus.Trying) && System
.currentTimeMillis() - o.createdTime < paymentTime) {
QueueTask qt = new QueueTask(o, TaskType.Payment, -1);
var qt = new QueueTask(o, TaskType.Payment, -1);
updateQueue(qt);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
return;
};
Retry<Order> r = new Retry<Order>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, order);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t.start();
}
private void updateQueue(QueueTask qt) throws InterruptedException {
private void updateQueue(QueueTask qt) {
if (System.currentTimeMillis() - qt.order.createdTime >= this.queueTime) {
// since payment time is lesser than queuetime it would have already failed..
// additional check not needed
@ -256,98 +243,83 @@ public class Commander {
LOG.trace("Order " + qt.order.id + ": Not queueing task since task already done..");
return;
}
ArrayList<Exception> list = queue.exceptionsList;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Retry.Operation op = (list) -> {
if (!list.isEmpty()) {
var list = queue.exceptionsList;
Thread t = new Thread(() -> {
Retry.Operation op = (list1) -> {
if (!list1.isEmpty()) {
LOG.warn("Order " + qt.order.id + ": Error in connecting to queue db, trying again..");
throw list.remove(0);
throw list1.remove(0);
}
queue.add(qt);
queueItems++;
LOG.info("Order " + qt.order.id + ": " + qt.getType() + " task enqueued..");
tryDoingTasksInQueue();
return;
};
Retry.HandleErrorIssue<QueueTask> handleError = (qt, err) -> {
if (qt.taskType.equals(TaskType.Payment)) {
qt.order.paid = PaymentStatus.NotDone;
sendPaymentFailureMessage(qt.order);
LOG.error("Order " + qt.order.id + ": Unable to enqueue payment task,"
Retry.HandleErrorIssue<QueueTask> handleError = (qt1, err) -> {
if (qt1.taskType.equals(TaskType.Payment)) {
qt1.order.paid = PaymentStatus.NotDone;
sendPaymentFailureMessage(qt1.order);
LOG.error("Order " + qt1.order.id + ": Unable to enqueue payment task,"
+ " payment failed..");
}
LOG.error("Order " + qt.order.id + ": Unable to enqueue task of type " + qt.getType()
LOG.error("Order " + qt1.order.id + ": Unable to enqueue task of type " + qt1.getType()
+ ", trying to add to employee handle..");
employeeHandleIssue(qt.order);
return;
employeeHandleIssue(qt1.order);
};
Retry<QueueTask> r = new Retry<QueueTask>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, qt);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t.start();
}
private void tryDoingTasksInQueue() { //commander controls operations done to queue
ArrayList<Exception> list = queue.exceptionsList;
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Retry.Operation op = (list) -> {
if (!list.isEmpty()) {
var list = queue.exceptionsList;
var t2 = new Thread(() -> {
Retry.Operation op = (list1) -> {
if (!list1.isEmpty()) {
LOG.warn("Error in accessing queue db to do tasks, trying again..");
throw list.remove(0);
throw list1.remove(0);
}
doTasksInQueue();
return;
};
Retry.HandleErrorIssue<QueueTask> handleError = (o, err) -> {
return;
};
Retry<QueueTask> r = new Retry<QueueTask>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, null);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t2.start();
}
private void tryDequeue() {
ArrayList<Exception> list = queue.exceptionsList;
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
Retry.Operation op = (list) -> {
if (!list.isEmpty()) {
var list = queue.exceptionsList;
var t3 = new Thread(() -> {
Retry.Operation op = (list1) -> {
if (!list1.isEmpty()) {
LOG.warn("Error in accessing queue db to dequeue task, trying again..");
throw list.remove(0);
throw list1.remove(0);
}
queue.dequeue();
queueItems--;
return;
};
Retry.HandleErrorIssue<QueueTask> handleError = (o, err) -> {
return;
};
Retry<QueueTask> r = new Retry<QueueTask>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<QueueTask>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, null);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t3.start();
}
@ -357,10 +329,8 @@ public class Commander {
LOG.trace("Order " + order.id + ": Message time for order over, returning..");
return;
}
ArrayList<Exception> list = messagingService.exceptionsList;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
var list = messagingService.exceptionsList;
Thread t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
@ -374,37 +344,30 @@ public class Commander {
}
if (!order.messageSent.equals(MessageSent.PaymentFail)
&& !order.messageSent.equals(MessageSent.PaymentSuccessful)) {
String requestId = messagingService.receiveRequest(2);
var requestId = messagingService.receiveRequest(2);
order.messageSent = MessageSent.PaymentSuccessful;
LOG.info("Order " + order.id + ": Payment Success message sent,"
+ " request Id: " + requestId);
}
return;
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
try {
if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent
.equals(MessageSent.PaymentTrying))
&& System.currentTimeMillis() - o.createdTime < messageTime) {
QueueTask qt = new QueueTask(order, TaskType.Messaging, 2);
var qt = new QueueTask(order, TaskType.Messaging, 2);
updateQueue(qt);
LOG.info("Order " + order.id + ": Error in sending Payment Success message, trying to"
+ " queue task and add to employee handle..");
employeeHandleIssue(order);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return;
};
Retry<Order> r = new Retry<Order>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, order);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t.start();
}
@ -414,10 +377,8 @@ public class Commander {
LOG.trace("Order " + order.id + ": Message time for order over, returning..");
return;
}
ArrayList<Exception> list = messagingService.exceptionsList;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
var list = messagingService.exceptionsList;
var t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
@ -431,37 +392,30 @@ public class Commander {
}
if (!order.messageSent.equals(MessageSent.PaymentFail)
&& !order.messageSent.equals(MessageSent.PaymentSuccessful)) {
String requestId = messagingService.receiveRequest(0);
var requestId = messagingService.receiveRequest(0);
order.messageSent = MessageSent.PaymentFail;
LOG.info("Order " + order.id + ": Payment Failure message sent successfully,"
+ " request Id: " + requestId);
}
return;
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent
.equals(MessageSent.PaymentTrying))
&& System.currentTimeMillis() - o.createdTime < messageTime) {
try {
QueueTask qt = new QueueTask(order, TaskType.Messaging, 0);
var qt = new QueueTask(order, TaskType.Messaging, 0);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in sending Payment Failure message, "
+ "trying to queue task and add to employee handle..");
employeeHandleIssue(o);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return;
}
};
Retry<Order> r = new Retry<Order>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, order);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t.start();
}
@ -471,10 +425,8 @@ public class Commander {
LOG.trace("Message time for order over, returning..");
return;
}
ArrayList<Exception> list = messagingService.exceptionsList;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
var list = messagingService.exceptionsList;
var t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) {
@ -488,37 +440,30 @@ public class Commander {
}
if (order.paid.equals(PaymentStatus.Trying) && order.messageSent
.equals(MessageSent.NoneSent)) {
String requestId = messagingService.receiveRequest(1);
var requestId = messagingService.receiveRequest(1);
order.messageSent = MessageSent.PaymentTrying;
LOG.info("Order " + order.id + ": Payment Error message sent successfully,"
+ " request Id: " + requestId);
}
return;
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
try {
if (o.messageSent.equals(MessageSent.NoneSent) && order.paid
.equals(PaymentStatus.Trying)
&& System.currentTimeMillis() - o.createdTime < messageTime) {
QueueTask qt = new QueueTask(order, TaskType.Messaging, 1);
var qt = new QueueTask(order, TaskType.Messaging, 1);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in sending Payment Error message, "
+ "trying to queue task and add to employee handle..");
employeeHandleIssue(o);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return;
};
Retry<Order> r = new Retry<Order>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, order);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t.start();
}
@ -528,10 +473,8 @@ public class Commander {
LOG.trace("Order " + order.id + ": Employee handle time for order over, returning..");
return;
}
ArrayList<Exception> list = employeeDb.exceptionsList;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
var list = employeeDb.exceptionsList;
var t = new Thread(() -> {
Retry.Operation op = (l) -> {
if (!l.isEmpty()) {
LOG.warn("Order " + order.id + ": Error in connecting to employee handle,"
@ -543,38 +486,30 @@ public class Commander {
order.addedToEmployeeHandle = true;
LOG.info("Order " + order.id + ": Added order to employee database");
}
return;
};
Retry.HandleErrorIssue<Order> handleError = (o, err) -> {
try {
if (!o.addedToEmployeeHandle && System
.currentTimeMillis() - order.createdTime < employeeTime) {
QueueTask qt = new QueueTask(order, TaskType.EmployeeDb, -1);
var qt = new QueueTask(order, TaskType.EmployeeDb, -1);
updateQueue(qt);
LOG.warn("Order " + order.id + ": Error in adding to employee db,"
+ " trying to queue task..");
return;
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return;
};
Retry<Order> r = new Retry<Order>(op, handleError, numOfRetries, retryDuration,
var r = new Retry<>(op, handleError, numOfRetries, retryDuration,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
try {
r.perform(list, order);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t.start();
}
private void doTasksInQueue() throws Exception {
if (queueItems != 0) {
QueueTask qt = queue.peek(); //this should probably be cloned here
var qt = queue.peek(); //this should probably be cloned here
//this is why we have retry for doTasksInQueue
LOG.trace("Order " + qt.order.id + ": Started doing task of type " + qt.getType());
if (qt.firstAttemptTime == -1) {

View File

@ -36,14 +36,10 @@ public class Order { //can store all transactions ids also
NotDone, Trying, Done
}
;
enum MessageSent {
NoneSent, PaymentFail, PaymentTrying, PaymentSuccessful
}
;
final User user;
final String item;
public final String id;
@ -74,7 +70,7 @@ public class Order { //can store all transactions ids also
this.addedToEmployeeHandle = false;
}
String createUniqueId() {
private String createUniqueId() {
StringBuilder random = new StringBuilder();
while (random.length() < 12) { // length of the random string.
int index = (int) (RANDOM.nextFloat() * ALL_CHARS.length());

View File

@ -25,6 +25,7 @@ package com.iluwatar.commander;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
@ -42,7 +43,7 @@ public class Retry<T> {
*/
public interface Operation {
void operation(ArrayList<Exception> list) throws Exception;
void operation(List<Exception> list) throws Exception;
}
/**
@ -63,9 +64,9 @@ public class Retry<T> {
private final long maxDelay;
private final AtomicInteger attempts;
private final Predicate<Exception> test;
private final ArrayList<Exception> errors;
private final List<Exception> errors;
Retry(Operation op, HandleErrorIssue handleError, int maxAttempts,
Retry(Operation op, HandleErrorIssue<T> handleError, int maxAttempts,
long maxDelay, Predicate<Exception>... ignoreTests) {
this.op = op;
this.handleError = handleError;
@ -83,7 +84,7 @@ public class Retry<T> {
* @param obj is the parameter to be passed into handleIsuue method
*/
public void perform(ArrayList<Exception> list, T obj) throws Exception {
public void perform(List<Exception> list, T obj) {
do {
try {
op.operation(list);
@ -97,7 +98,7 @@ public class Retry<T> {
try {
long testDelay =
(long) Math.pow(2, this.attempts.intValue()) * 1000 + RANDOM.nextInt(1000);
long delay = testDelay < this.maxDelay ? testDelay : maxDelay;
long delay = Math.min(testDelay, this.maxDelay);
Thread.sleep(delay);
} catch (InterruptedException f) {
//ignore

View File

@ -36,7 +36,7 @@ public class EmployeeDatabase extends Database<Order> {
private Hashtable<String, Order> data;
public EmployeeDatabase() {
this.data = new Hashtable<String, Order>();
this.data = new Hashtable<>();
}
@Override

View File

@ -28,8 +28,8 @@ import com.iluwatar.commander.Service;
import com.iluwatar.commander.exceptions.DatabaseUnavailableException;
/**
* The EmployeeHandle class is the middle-man between {@link Commander} and {@link
* EmployeeDatabase}.
* The EmployeeHandle class is the middle-man between {@link com.iluwatar.commander.Commander} and
* {@link EmployeeDatabase}.
*/
public class EmployeeHandle extends Service {
@ -39,11 +39,11 @@ public class EmployeeHandle extends Service {
}
public String receiveRequest(Object... parameters) throws DatabaseUnavailableException {
return updateDb((Order) parameters[0]);
return updateDb(parameters[0]);
}
protected String updateDb(Object... parameters) throws DatabaseUnavailableException {
Order o = (Order) parameters[0];
var o = (Order) parameters[0];
if (database.get(o.id) == null) {
database.add(o);
return o.id; //true rcvd - change addedToEmployeeHandle to true else dont do anything

View File

@ -36,16 +36,16 @@ public class MessagingDatabase extends Database<MessageRequest> {
private Hashtable<String, MessageRequest> data;
public MessagingDatabase() {
this.data = new Hashtable<String, MessageRequest>();
this.data = new Hashtable<>();
}
@Override
public MessageRequest add(MessageRequest r) throws DatabaseUnavailableException {
public MessageRequest add(MessageRequest r) {
return data.put(r.reqId, r);
}
@Override
public MessageRequest get(String requestId) throws DatabaseUnavailableException {
public MessageRequest get(String requestId) {
return data.get(requestId);
}

View File

@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
/**
* The MessagingService is used to send messages to user regarding their order and payment status.
* In case an error is encountered in payment and this service is found to be unavailable, the order
* is added to the {@link EmployeeDatabase}.
* is added to the {@link com.iluwatar.commander.employeehandle.EmployeeDatabase}.
*/
public class MessagingService extends Service {
@ -41,8 +41,6 @@ public class MessagingService extends Service {
PaymentFail, PaymentTrying, PaymentSuccessful
}
;
class MessageRequest {
String reqId;
MessageToSend msg;
@ -58,12 +56,12 @@ public class MessagingService extends Service {
}
/**
* Public method which will receive request from {@link Commander}.
* Public method which will receive request from {@link com.iluwatar.commander.Commander}.
*/
public String receiveRequest(Object... parameters) throws DatabaseUnavailableException {
int messageToSend = (int) parameters[0];
String id = generateId();
MessageToSend msg = null;
var messageToSend = (int) parameters[0];
var id = generateId();
MessageToSend msg;
if (messageToSend == 0) {
msg = MessageToSend.PaymentFail;
} else if (messageToSend == 1) {
@ -71,12 +69,12 @@ public class MessagingService extends Service {
} else { //messageToSend == 2
msg = MessageToSend.PaymentSuccessful;
}
MessageRequest req = new MessageRequest(id, msg);
var req = new MessageRequest(id, msg);
return updateDb(req);
}
protected String updateDb(Object... parameters) throws DatabaseUnavailableException {
MessageRequest req = (MessageRequest) parameters[0];
var req = (MessageRequest) parameters[0];
if (this.database.get(req.reqId) == null) { //idempotence, in case db fails here
database.add(req); //if successful:
LOGGER.info(sendMessage(req.msg));

View File

@ -37,17 +37,17 @@ public class PaymentDatabase extends Database<PaymentRequest> {
private Hashtable<String, PaymentRequest> data;
public PaymentDatabase() {
this.data = new Hashtable<String, PaymentRequest>();
this.data = new Hashtable<>();
//0-fail, 1-error, 2-success
}
@Override
public PaymentRequest add(PaymentRequest r) throws DatabaseUnavailableException {
public PaymentRequest add(PaymentRequest r) {
return data.put(r.transactionId, r);
}
@Override
public PaymentRequest get(String requestId) throws DatabaseUnavailableException {
public PaymentRequest get(String requestId) {
return data.get(requestId);
}

View File

@ -27,8 +27,8 @@ import com.iluwatar.commander.Service;
import com.iluwatar.commander.exceptions.DatabaseUnavailableException;
/**
* The PaymentService class receives request from the {@link Commander} and adds to the {@link
* PaymentDatabase}.
* The PaymentService class receives request from the {@link com.iluwatar.commander.Commander} and
* adds to the {@link PaymentDatabase}.
*/
public class PaymentService extends Service {
@ -50,18 +50,18 @@ public class PaymentService extends Service {
}
/**
* Public method which will receive request from {@link Commander}.
* Public method which will receive request from {@link com.iluwatar.commander.Commander}.
*/
public String receiveRequest(Object... parameters) throws DatabaseUnavailableException {
//it could also be sending a userid, payment details here or something, not added here
String id = generateId();
PaymentRequest req = new PaymentRequest(id, (float) parameters[0]);
var id = generateId();
var req = new PaymentRequest(id, (float) parameters[0]);
return updateDb(req);
}
protected String updateDb(Object... parameters) throws DatabaseUnavailableException {
PaymentRequest req = (PaymentRequest) parameters[0];
var req = (PaymentRequest) parameters[0];
if (database.get(req.transactionId) == null || !req.paid) {
database.add(req);
req.paid = true;

View File

@ -33,15 +33,15 @@ import com.iluwatar.commander.exceptions.IsEmptyException;
public class Queue<T> {
Node<T> front;
Node<T> rear;
public int size = 0;
private Node<T> front;
private Node<T> rear;
private int size;
class Node<T> {
T value;
Node<T> next;
static class Node<V> {
V value;
Node<V> next;
Node(T obj, Node<T> b) {
Node(V obj, Node<V> b) {
value = obj;
next = b;
}
@ -57,19 +57,15 @@ public class Queue<T> {
}
boolean isEmpty() {
if (size == 0) {
return true;
} else {
return false;
}
return size == 0;
}
void enqueue(T obj) {
if (front == null) {
front = new Node(obj, null);
front = new Node<>(obj, null);
rear = front;
} else {
Node temp = new Node(obj, null);
var temp = new Node<>(obj, null);
rear.next = temp;
rear = temp;
}
@ -80,10 +76,10 @@ public class Queue<T> {
if (isEmpty()) {
throw new IsEmptyException();
} else {
Node temp = front;
var temp = front;
front = front.next;
size = size - 1;
return (T) temp.value;
return temp.value;
}
}
@ -91,7 +87,7 @@ public class Queue<T> {
if (isEmpty()) {
throw new IsEmptyException();
} else {
return (T) front.value;
return front.value;
}
}
}

View File

@ -36,7 +36,7 @@ import java.util.List;
public class QueueDatabase extends Database<QueueTask> {
private Queue<QueueTask> data;
public ArrayList<Exception> exceptionsList;
public List<Exception> exceptionsList;
public QueueDatabase(Exception... exc) {
this.data = new Queue<>();
@ -44,7 +44,7 @@ public class QueueDatabase extends Database<QueueTask> {
}
@Override
public QueueTask add(QueueTask t) throws DatabaseUnavailableException {
public QueueTask add(QueueTask t) {
data.enqueue(t);
return t;
//even if same thing queued twice, it is taken care of in other dbs
@ -55,12 +55,10 @@ public class QueueDatabase extends Database<QueueTask> {
*
* @return object at front of queue
* @throws IsEmptyException if queue is empty
* @throws DatabaseUnavailableException if queue db is unavailable
*/
public QueueTask peek() throws IsEmptyException, DatabaseUnavailableException {
QueueTask qt = this.data.peek();
return qt;
public QueueTask peek() throws IsEmptyException {
return this.data.peek();
}
/**
@ -68,16 +66,14 @@ public class QueueDatabase extends Database<QueueTask> {
*
* @return object at front of queue
* @throws IsEmptyException if queue is empty
* @throws DatabaseUnavailableException if queue db is unavailable
*/
public QueueTask dequeue() throws IsEmptyException, DatabaseUnavailableException {
QueueTask qt = this.data.dequeue();
return qt;
public QueueTask dequeue() throws IsEmptyException {
return this.data.dequeue();
}
@Override
public QueueTask get(String taskId) throws DatabaseUnavailableException {
public QueueTask get(String taskId) {
return null;
}

View File

@ -39,8 +39,6 @@ public class QueueTask {
Messaging, Payment, EmployeeDb
}
;
public Order order;
public TaskType taskType;
public int messageType; //0-fail, 1-error, 2-success
@ -69,7 +67,6 @@ public class QueueTask {
*
* @return String representing type of task
*/
public String getType() {
if (!this.taskType.equals(TaskType.Messaging)) {
return this.taskType.toString();

View File

@ -37,15 +37,15 @@ public class ShippingDatabase extends Database<ShippingRequest> {
private Hashtable<String, ShippingRequest> data;
public ShippingDatabase() {
this.data = new Hashtable<String, ShippingRequest>();
this.data = new Hashtable<>();
}
@Override
public ShippingRequest add(ShippingRequest r) throws DatabaseUnavailableException {
public ShippingRequest add(ShippingRequest r) {
return data.put(r.transactionId, r);
}
public ShippingRequest get(String trasnactionId) throws DatabaseUnavailableException {
public ShippingRequest get(String trasnactionId) {
return data.get(trasnactionId);
}

View File

@ -27,13 +27,13 @@ import com.iluwatar.commander.Service;
import com.iluwatar.commander.exceptions.DatabaseUnavailableException;
/**
* ShippingService class receives request from {@link Commander} class and adds it to the {@link
* ShippingDatabase}.
* ShippingService class receives request from {@link com.iluwatar.commander.Commander} class and
* adds it to the {@link ShippingDatabase}.
*/
public class ShippingService extends Service {
class ShippingRequest {
static class ShippingRequest {
String transactionId;
String item;
String address;
@ -50,18 +50,19 @@ public class ShippingService extends Service {
}
/**
* Public method which will receive request from {@link Commander}.
* Public method which will receive request from {@link com.iluwatar.commander.Commander}.
*/
public String receiveRequest(Object... parameters) throws DatabaseUnavailableException {
String id = generateId();
ShippingRequest req =
new ShippingRequest(id, (String) parameters[0] /*item*/, (String) parameters[1]/*address*/);
var id = generateId();
var item = (String) parameters[0];
var address = (String) parameters[1];
var req = new ShippingRequest(id, item, address);
return updateDb(req);
}
protected String updateDb(Object... parameters) throws DatabaseUnavailableException {
ShippingRequest req = (ShippingRequest) parameters[0];
var req = (ShippingRequest) parameters[0];
if (this.database.get(req.transactionId) == null) {
database.add(req);
return req.transactionId;

View File

@ -23,14 +23,13 @@
package com.iluwatar.commander;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.commander.exceptions.DatabaseUnavailableException;
import com.iluwatar.commander.exceptions.ItemUnavailableException;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class RetryTest {
@ -40,26 +39,22 @@ class RetryTest {
if (!l.isEmpty()) {
throw l.remove(0);
}
return;
};
Retry.HandleErrorIssue<Order> handleError = (o, e) -> {
return;
};
Retry<Order> r1 = new Retry<>(op, handleError, 3, 30000,
var r1 = new Retry<>(op, handleError, 3, 30000,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
Retry<Order> r2 = new Retry<>(op, handleError, 3, 30000,
var r2 = new Retry<>(op, handleError, 3, 30000,
e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass()));
User user = new User("Jim", "ABCD");
Order order = new Order(user, "book", 10f);
ArrayList<Exception> arr1 = new ArrayList<>(List.of(
new ItemUnavailableException(), new DatabaseUnavailableException()));
var user = new User("Jim", "ABCD");
var order = new Order(user, "book", 10f);
var arr1 = new ArrayList<>(List.of(new ItemUnavailableException(), new DatabaseUnavailableException()));
try {
r1.perform(arr1, order);
} catch (Exception e1) {
e1.printStackTrace();
}
ArrayList<Exception> arr2 = new ArrayList<>(List.of(
new DatabaseUnavailableException(), new ItemUnavailableException()));
var arr2 = new ArrayList<>(List.of(new DatabaseUnavailableException(), new ItemUnavailableException()));
try {
r2.perform(arr2, order);
} catch (Exception e1) {

View File

@ -49,12 +49,12 @@ public class App {
public static void main(String[] args) {
LOGGER.info("Message from the orcs: ");
LetterComposite orcMessage = new Messenger().messageFromOrcs();
var orcMessage = new Messenger().messageFromOrcs();
orcMessage.print();
LOGGER.info("\nMessage from the elves: ");
LetterComposite elfMessage = new Messenger().messageFromElves();
var elfMessage = new Messenger().messageFromElves();
elfMessage.print();
}
}

View File

@ -52,9 +52,7 @@ public abstract class LetterComposite {
*/
public void print() {
printThisBefore();
for (LetterComposite letter : children) {
letter.print();
}
children.forEach(LetterComposite::print);
printThisAfter();
}
}

View File

@ -32,20 +32,17 @@ public class Messenger {
LetterComposite messageFromOrcs() {
List<Word> words = List.of(
new Word(List.of(new Letter('W'), new Letter('h'), new Letter('e'), new Letter(
'r'), new Letter('e'))),
new Word(List.of(new Letter('t'), new Letter('h'), new Letter('e'), new Letter(
'r'), new Letter('e'))),
new Word(List.of(new Letter('i'), new Letter('s'))),
new Word(List.of(new Letter('a'))),
new Word(List.of(new Letter('w'), new Letter('h'), new Letter('i'), new Letter(
'p'))),
new Word(List.of(new Letter('t'), new Letter('h'), new Letter('e'), new Letter(
'r'), new Letter('e'))),
new Word(List.of(new Letter('i'), new Letter('s'))),
new Word(List.of(new Letter('a'))),
new Word(List.of(new Letter('w'), new Letter('a'), new Letter('y'))));
var words = List.of(
new Word('W', 'h', 'e', 'r', 'e'),
new Word('t', 'h', 'e', 'r', 'e'),
new Word('i', 's'),
new Word('a'),
new Word('w', 'h', 'i', 'p'),
new Word('t', 'h', 'e', 'r', 'e'),
new Word('i', 's'),
new Word('a'),
new Word('w', 'a', 'y')
);
return new Sentence(words);
@ -53,15 +50,14 @@ public class Messenger {
LetterComposite messageFromElves() {
List<Word> words = List.of(
new Word(List.of(new Letter('M'), new Letter('u'), new Letter('c'), new Letter('h'))),
new Word(List.of(new Letter('w'), new Letter('i'), new Letter('n'), new Letter('d'))),
new Word(List.of(new Letter('p'), new Letter('o'), new Letter('u'), new Letter('r'),
new Letter('s'))),
new Word(List.of(new Letter('f'), new Letter('r'), new Letter('o'), new Letter('m'))),
new Word(List.of(new Letter('y'), new Letter('o'), new Letter('u'), new Letter('r'))),
new Word(List.of(new Letter('m'), new Letter('o'), new Letter('u'), new Letter('t'),
new Letter('h'))));
var words = List.of(
new Word('M', 'u', 'c', 'h'),
new Word('w', 'i', 'n', 'd'),
new Word('p', 'o', 'u', 'r', 's'),
new Word('f', 'r', 'o', 'm'),
new Word('y', 'o', 'u', 'r'),
new Word('m', 'o', 'u', 't', 'h')
);
return new Sentence(words);

View File

@ -34,9 +34,7 @@ public class Sentence extends LetterComposite {
* Constructor.
*/
public Sentence(List<Word> words) {
for (Word w : words) {
this.add(w);
}
words.forEach(this::add);
}
@Override

View File

@ -34,8 +34,12 @@ public class Word extends LetterComposite {
* Constructor.
*/
public Word(List<Letter> letters) {
for (Letter l : letters) {
this.add(l);
letters.forEach(this::add);
}
public Word(char... letters) {
for (char letter : letters) {
this.add(new Letter(letter));
}
}

View File

@ -26,15 +26,12 @@ package com.iluwatar.composite;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -72,7 +72,7 @@ public class MessengerTest {
*/
@Test
public void testMessageFromOrcs() {
final Messenger messenger = new Messenger();
final var messenger = new Messenger();
testMessage(
messenger.messageFromOrcs(),
"Where there is a whip there is a way."
@ -84,7 +84,7 @@ public class MessengerTest {
*/
@Test
public void testMessageFromElves() {
final Messenger messenger = new Messenger();
final var messenger = new Messenger();
testMessage(
messenger.messageFromElves(),
"Much wind pours from your mouth."
@ -99,7 +99,7 @@ public class MessengerTest {
*/
private void testMessage(final LetterComposite composedMessage, final String message) {
// Test is the composed message has the correct number of words
final String[] words = message.split(" ");
final var words = message.split(" ");
assertNotNull(composedMessage);
assertEquals(words.length, composedMessage.count());