📍Use lombok, reformat, and optimize the code (#1560)
* Use lombok, reformat, and optimize the code * Fix merge conflicts and some sonar issues Co-authored-by: va1m <va1m@email.com>
This commit is contained in:
parent
0e26a6adb5
commit
5cf2fe009b
@ -27,8 +27,7 @@ import com.iluwatar.abstractdocument.domain.Car;
|
|||||||
import com.iluwatar.abstractdocument.domain.enums.Property;
|
import com.iluwatar.abstractdocument.domain.enums.Property;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Abstract Document pattern enables handling additional, non-static properties. This pattern
|
* The Abstract Document pattern enables handling additional, non-static properties. This pattern
|
||||||
@ -38,10 +37,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* <p>In Abstract Document pattern,({@link AbstractDocument}) fully implements {@link Document})
|
* <p>In Abstract Document pattern,({@link AbstractDocument}) fully implements {@link Document})
|
||||||
* interface. Traits are then defined to enable access to properties in usual, static way.
|
* interface. Traits are then defined to enable access to properties in usual, static way.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
|
@ -23,19 +23,18 @@
|
|||||||
|
|
||||||
package com.iluwatar.abstractdocument;
|
package com.iluwatar.abstractdocument;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AbstractDocument test class
|
* AbstractDocument test class
|
||||||
*/
|
*/
|
||||||
public class AbstractDocumentTest {
|
class AbstractDocumentTest {
|
||||||
|
|
||||||
private static final String KEY = "key";
|
private static final String KEY = "key";
|
||||||
private static final String VALUE = "value";
|
private static final String VALUE = "value";
|
||||||
@ -50,13 +49,13 @@ public class AbstractDocumentTest {
|
|||||||
private final DocumentImplementation document = new DocumentImplementation(new HashMap<>());
|
private final DocumentImplementation document = new DocumentImplementation(new HashMap<>());
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldPutAndGetValue() {
|
void shouldPutAndGetValue() {
|
||||||
document.put(KEY, VALUE);
|
document.put(KEY, VALUE);
|
||||||
assertEquals(VALUE, document.get(KEY));
|
assertEquals(VALUE, document.get(KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldRetrieveChildren() {
|
void shouldRetrieveChildren() {
|
||||||
var children = List.of(Map.of(), Map.of());
|
var children = List.of(Map.of(), Map.of());
|
||||||
|
|
||||||
document.put(KEY, children);
|
document.put(KEY, children);
|
||||||
@ -67,14 +66,14 @@ public class AbstractDocumentTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldRetrieveEmptyStreamForNonExistingChildren() {
|
void shouldRetrieveEmptyStreamForNonExistingChildren() {
|
||||||
var children = document.children(KEY, DocumentImplementation::new);
|
var children = document.children(KEY, DocumentImplementation::new);
|
||||||
assertNotNull(children);
|
assertNotNull(children);
|
||||||
assertEquals(0, children.count());
|
assertEquals(0, children.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldIncludePropsInToString() {
|
void shouldIncludePropsInToString() {
|
||||||
var props = Map.of(KEY, (Object) VALUE);
|
var props = Map.of(KEY, (Object) VALUE);
|
||||||
var document = new DocumentImplementation(props);
|
var document = new DocumentImplementation(props);
|
||||||
assertTrue(document.toString().contains(KEY));
|
assertTrue(document.toString().contains(KEY));
|
||||||
|
@ -23,19 +23,20 @@
|
|||||||
|
|
||||||
package com.iluwatar.abstractdocument;
|
package com.iluwatar.abstractdocument;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import com.iluwatar.abstractdocument.domain.Car;
|
import com.iluwatar.abstractdocument.domain.Car;
|
||||||
import com.iluwatar.abstractdocument.domain.Part;
|
import com.iluwatar.abstractdocument.domain.Part;
|
||||||
import com.iluwatar.abstractdocument.domain.enums.Property;
|
import com.iluwatar.abstractdocument.domain.enums.Property;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for Part and Car
|
* Test for Part and Car
|
||||||
*/
|
*/
|
||||||
public class DomainTest {
|
class DomainTest {
|
||||||
|
|
||||||
private static final String TEST_PART_TYPE = "test-part-type";
|
private static final String TEST_PART_TYPE = "test-part-type";
|
||||||
private static final String TEST_PART_MODEL = "test-part-model";
|
private static final String TEST_PART_MODEL = "test-part-model";
|
||||||
@ -45,7 +46,7 @@ public class DomainTest {
|
|||||||
private static final long TEST_CAR_PRICE = 1L;
|
private static final long TEST_CAR_PRICE = 1L;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldConstructPart() {
|
void shouldConstructPart() {
|
||||||
var partProperties = Map.of(
|
var partProperties = Map.of(
|
||||||
Property.TYPE.toString(), TEST_PART_TYPE,
|
Property.TYPE.toString(), TEST_PART_TYPE,
|
||||||
Property.MODEL.toString(), TEST_PART_MODEL,
|
Property.MODEL.toString(), TEST_PART_MODEL,
|
||||||
@ -58,7 +59,7 @@ public class DomainTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldConstructCar() {
|
void shouldConstructCar() {
|
||||||
var carProperties = Map.of(
|
var carProperties = Map.of(
|
||||||
Property.MODEL.toString(), TEST_CAR_MODEL,
|
Property.MODEL.toString(), TEST_CAR_MODEL,
|
||||||
Property.PRICE.toString(), TEST_CAR_PRICE,
|
Property.PRICE.toString(), TEST_CAR_PRICE,
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.abstractfactory;
|
package com.iluwatar.abstractfactory;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Abstract Factory pattern provides a way to encapsulate a group of individual factories that
|
* The Abstract Factory pattern provides a way to encapsulate a group of individual factories that
|
||||||
@ -40,10 +39,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* and its implementations ( {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses
|
* and its implementations ( {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses
|
||||||
* both concrete implementations to create a king, a castle and an army.
|
* both concrete implementations to create a king, a castle and an army.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App implements Runnable {
|
public class App implements Runnable {
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
private final Kingdom kingdom = new Kingdom();
|
private final Kingdom kingdom = new Kingdom();
|
||||||
|
|
||||||
public Kingdom getKingdom() {
|
public Kingdom getKingdom() {
|
||||||
@ -62,17 +60,17 @@ public class App implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
log.info("Elf Kingdom");
|
LOGGER.info("Elf Kingdom");
|
||||||
createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
||||||
log.info(kingdom.getArmy().getDescription());
|
LOGGER.info(kingdom.getArmy().getDescription());
|
||||||
log.info(kingdom.getCastle().getDescription());
|
LOGGER.info(kingdom.getCastle().getDescription());
|
||||||
log.info(kingdom.getKing().getDescription());
|
LOGGER.info(kingdom.getKing().getDescription());
|
||||||
|
|
||||||
log.info("Orc Kingdom");
|
LOGGER.info("Orc Kingdom");
|
||||||
createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
|
createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
|
||||||
log.info(kingdom.getArmy().getDescription());
|
LOGGER.info(kingdom.getArmy().getDescription());
|
||||||
log.info(kingdom.getCastle().getDescription());
|
LOGGER.info(kingdom.getCastle().getDescription());
|
||||||
log.info(kingdom.getKing().getDescription());
|
LOGGER.info(kingdom.getKing().getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,36 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.abstractfactory;
|
package com.iluwatar.abstractfactory;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
public class Kingdom {
|
public class Kingdom {
|
||||||
|
|
||||||
private King king;
|
private King king;
|
||||||
private Castle castle;
|
private Castle castle;
|
||||||
private Army army;
|
private Army army;
|
||||||
|
|
||||||
public King getKing() {
|
|
||||||
return king;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Castle getCastle() {
|
|
||||||
return castle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Army getArmy() {
|
|
||||||
return army;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKing(King king) {
|
|
||||||
this.king = king;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCastle(Castle castle) {
|
|
||||||
this.castle = castle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArmy(Army army) {
|
|
||||||
this.army = army;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The factory of kingdom factories.
|
* The factory of kingdom factories.
|
||||||
*/
|
*/
|
||||||
|
@ -31,12 +31,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||||||
/**
|
/**
|
||||||
* Test for abstract factory.
|
* Test for abstract factory.
|
||||||
*/
|
*/
|
||||||
public class AbstractFactoryTest {
|
class AbstractFactoryTest {
|
||||||
|
|
||||||
private final App app = new App();
|
private final App app = new App();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void king() {
|
void king() {
|
||||||
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
||||||
final var kingdom = app.getKingdom();
|
final var kingdom = app.getKingdom();
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ public class AbstractFactoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void castle() {
|
void castle() {
|
||||||
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
||||||
final var kingdom = app.getKingdom();
|
final var kingdom = app.getKingdom();
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ public class AbstractFactoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void army() {
|
void army() {
|
||||||
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
||||||
final var kingdom = app.getKingdom();
|
final var kingdom = app.getKingdom();
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ public class AbstractFactoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createElfKingdom() {
|
void createElfKingdom() {
|
||||||
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
|
||||||
final var kingdom = app.getKingdom();
|
final var kingdom = app.getKingdom();
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ public class AbstractFactoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOrcKingdom() {
|
void createOrcKingdom() {
|
||||||
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
|
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
|
||||||
final var kingdom = app.getKingdom();
|
final var kingdom = app.getKingdom();
|
||||||
|
|
||||||
|
@ -23,17 +23,15 @@
|
|||||||
|
|
||||||
package com.iluwatar.acyclicvisitor;
|
package com.iluwatar.acyclicvisitor;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConfigureForDosVisitor class implements both zoom's and hayes' visit method for Dos
|
* ConfigureForDosVisitor class implements both zoom's and hayes' visit method for Dos
|
||||||
* manufacturer.
|
* manufacturer.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class ConfigureForDosVisitor implements AllModemVisitor {
|
public class ConfigureForDosVisitor implements AllModemVisitor {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForDosVisitor.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Hayes hayes) {
|
public void visit(Hayes hayes) {
|
||||||
LOGGER.info(hayes + " used with Dos configurator.");
|
LOGGER.info(hayes + " used with Dos configurator.");
|
||||||
|
@ -23,17 +23,15 @@
|
|||||||
|
|
||||||
package com.iluwatar.acyclicvisitor;
|
package com.iluwatar.acyclicvisitor;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConfigureForUnixVisitor class implements zoom's visit method for Unix manufacturer, unlike
|
* ConfigureForUnixVisitor class implements zoom's visit method for Unix manufacturer, unlike
|
||||||
* traditional visitor pattern, this class may selectively implement visit for other modems.
|
* traditional visitor pattern, this class may selectively implement visit for other modems.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class ConfigureForUnixVisitor implements ZoomVisitor {
|
public class ConfigureForUnixVisitor implements ZoomVisitor {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForUnixVisitor.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Zoom zoom) {
|
public void visit(Zoom zoom) {
|
||||||
LOGGER.info(zoom + " used with Unix configurator.");
|
LOGGER.info(zoom + " used with Unix configurator.");
|
||||||
|
@ -23,16 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.acyclicvisitor;
|
package com.iluwatar.acyclicvisitor;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hayes class implements its accept method.
|
* Hayes class implements its accept method.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class Hayes extends Modem {
|
public class Hayes extends Modem {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForDosVisitor.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts all visitors but honors only HayesVisitor.
|
* Accepts all visitors but honors only HayesVisitor.
|
||||||
*/
|
*/
|
||||||
|
@ -23,16 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.acyclicvisitor;
|
package com.iluwatar.acyclicvisitor;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zoom class implements its accept method.
|
* Zoom class implements its accept method.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class Zoom extends Modem {
|
public class Zoom extends Modem {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForDosVisitor.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts all visitors but honors only ZoomVisitor.
|
* Accepts all visitors but honors only ZoomVisitor.
|
||||||
*/
|
*/
|
||||||
|
@ -35,12 +35,12 @@ import uk.org.lidalia.slf4jtest.TestLoggerFactory;
|
|||||||
/**
|
/**
|
||||||
* ConfigureForDosVisitor test class
|
* ConfigureForDosVisitor test class
|
||||||
*/
|
*/
|
||||||
public class ConfigureForDosVisitorTest {
|
class ConfigureForDosVisitorTest {
|
||||||
|
|
||||||
private final TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class);
|
private final TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVisitForZoom() {
|
void testVisitForZoom() {
|
||||||
var conDos = new ConfigureForDosVisitor();
|
var conDos = new ConfigureForDosVisitor();
|
||||||
var zoom = new Zoom();
|
var zoom = new Zoom();
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ public class ConfigureForDosVisitorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVisitForHayes() {
|
void testVisitForHayes() {
|
||||||
var conDos = new ConfigureForDosVisitor();
|
var conDos = new ConfigureForDosVisitor();
|
||||||
var hayes = new Hayes();
|
var hayes = new Hayes();
|
||||||
|
|
||||||
|
@ -23,20 +23,19 @@
|
|||||||
|
|
||||||
package com.iluwatar.acyclicvisitor;
|
package com.iluwatar.acyclicvisitor;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import uk.org.lidalia.slf4jtest.TestLogger;
|
||||||
|
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.groups.Tuple.tuple;
|
import static org.assertj.core.groups.Tuple.tuple;
|
||||||
import static uk.org.lidalia.slf4jext.Level.INFO;
|
import static uk.org.lidalia.slf4jext.Level.INFO;
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import uk.org.lidalia.slf4jtest.TestLogger;
|
|
||||||
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConfigureForUnixVisitor test class
|
* ConfigureForUnixVisitor test class
|
||||||
*/
|
*/
|
||||||
public class ConfigureForUnixVisitorTest {
|
class ConfigureForUnixVisitorTest {
|
||||||
|
|
||||||
private static final TestLogger LOGGER = TestLoggerFactory.getTestLogger(ConfigureForUnixVisitor.class);
|
private static final TestLogger LOGGER = TestLoggerFactory.getTestLogger(ConfigureForUnixVisitor.class);
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ public class ConfigureForUnixVisitorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVisitForZoom() {
|
void testVisitForZoom() {
|
||||||
var conUnix = new ConfigureForUnixVisitor();
|
var conUnix = new ConfigureForUnixVisitor();
|
||||||
var zoom = new Zoom();
|
var zoom = new Zoom();
|
||||||
|
|
||||||
|
@ -23,29 +23,27 @@
|
|||||||
|
|
||||||
package com.iluwatar.acyclicvisitor;
|
package com.iluwatar.acyclicvisitor;
|
||||||
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hayes test class
|
* Hayes test class
|
||||||
*/
|
*/
|
||||||
public class HayesTest {
|
class HayesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAcceptForDos() {
|
void testAcceptForDos() {
|
||||||
var hayes = new Hayes();
|
var hayes = new Hayes();
|
||||||
var mockVisitor = mock(ConfigureForDosVisitor.class);
|
var mockVisitor = mock(ConfigureForDosVisitor.class);
|
||||||
|
|
||||||
hayes.accept(mockVisitor);
|
hayes.accept(mockVisitor);
|
||||||
verify((HayesVisitor)mockVisitor).visit(eq(hayes));
|
verify((HayesVisitor) mockVisitor).visit(eq(hayes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAcceptForUnix() {
|
void testAcceptForUnix() {
|
||||||
var hayes = new Hayes();
|
var hayes = new Hayes();
|
||||||
var mockVisitor = mock(ConfigureForUnixVisitor.class);
|
var mockVisitor = mock(ConfigureForUnixVisitor.class);
|
||||||
|
|
||||||
|
@ -24,32 +24,32 @@
|
|||||||
package com.iluwatar.acyclicvisitor;
|
package com.iluwatar.acyclicvisitor;
|
||||||
|
|
||||||
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zoom test class
|
* Zoom test class
|
||||||
*/
|
*/
|
||||||
public class ZoomTest {
|
class ZoomTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAcceptForDos() {
|
void testAcceptForDos() {
|
||||||
var zoom = new Zoom();
|
var zoom = new Zoom();
|
||||||
var mockVisitor = mock(ConfigureForDosVisitor.class);
|
var mockVisitor = mock(ConfigureForDosVisitor.class);
|
||||||
|
|
||||||
zoom.accept(mockVisitor);
|
zoom.accept(mockVisitor);
|
||||||
verify((ZoomVisitor)mockVisitor).visit(eq(zoom));
|
verify((ZoomVisitor) mockVisitor).visit(eq(zoom));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAcceptForUnix() {
|
void testAcceptForUnix() {
|
||||||
var zoom = new Zoom();
|
var zoom = new Zoom();
|
||||||
var mockVisitor = mock(ConfigureForUnixVisitor.class);
|
var mockVisitor = mock(ConfigureForUnixVisitor.class);
|
||||||
|
|
||||||
zoom.accept(mockVisitor);
|
zoom.accept(mockVisitor);
|
||||||
verify((ZoomVisitor)mockVisitor).visit(eq(zoom));
|
verify((ZoomVisitor) mockVisitor).visit(eq(zoom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ public interface RowingBoat {
|
|||||||
void row();
|
void row();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class FishingBoat {
|
public class FishingBoat {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
|
|
||||||
public void sail() {
|
public void sail() {
|
||||||
LOGGER.info("The fishing boat is sailing");
|
LOGGER.info("The fishing boat is sailing");
|
||||||
}
|
}
|
||||||
@ -70,10 +70,9 @@ public class Captain {
|
|||||||
Now let's say the pirates are coming and our captain needs to escape but there is only fishing boat available. We need to create an adapter that allows the captain to operate the fishing boat with his rowing boat skills.
|
Now let's say the pirates are coming and our captain needs to escape but there is only fishing boat available. We need to create an adapter that allows the captain to operate the fishing boat with his rowing boat skills.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public class FishingBoatAdapter implements RowingBoat {
|
public class FishingBoatAdapter implements RowingBoat {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);
|
|
||||||
|
|
||||||
private final FishingBoat boat;
|
private final FishingBoat boat;
|
||||||
|
|
||||||
public FishingBoatAdapter() {
|
public FishingBoatAdapter() {
|
||||||
|
@ -23,24 +23,20 @@
|
|||||||
|
|
||||||
package com.iluwatar.adapter;
|
package com.iluwatar.adapter;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Captain uses {@link RowingBoat} to sail. <br> This is the client in the pattern.
|
* The Captain uses {@link RowingBoat} to sail. <br> This is the client in the pattern.
|
||||||
*/
|
*/
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
public final class Captain {
|
public final class Captain {
|
||||||
|
|
||||||
private RowingBoat rowingBoat;
|
private RowingBoat rowingBoat;
|
||||||
|
|
||||||
public Captain() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Captain(final RowingBoat boat) {
|
|
||||||
this.rowingBoat = boat;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRowingBoat(final RowingBoat boat) {
|
|
||||||
this.rowingBoat = boat;
|
|
||||||
}
|
|
||||||
|
|
||||||
void row() {
|
void row() {
|
||||||
rowingBoat.row();
|
rowingBoat.row();
|
||||||
}
|
}
|
||||||
|
@ -23,18 +23,15 @@
|
|||||||
|
|
||||||
package com.iluwatar.adapter;
|
package com.iluwatar.adapter;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Device class (adaptee in the pattern). We want to reuse this class. Fishing boat moves by
|
* Device class (adaptee in the pattern). We want to reuse this class. Fishing boat moves by
|
||||||
* sailing.
|
* sailing.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
final class FishingBoat {
|
final class FishingBoat {
|
||||||
|
|
||||||
private static final Logger LOGGER = getLogger(FishingBoat.class);
|
|
||||||
|
|
||||||
void sail() {
|
void sail() {
|
||||||
LOGGER.info("The fishing boat is sailing");
|
LOGGER.info("The fishing boat is sailing");
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,7 @@ package com.iluwatar.adapter;
|
|||||||
*/
|
*/
|
||||||
public class FishingBoatAdapter implements RowingBoat {
|
public class FishingBoatAdapter implements RowingBoat {
|
||||||
|
|
||||||
private final FishingBoat boat;
|
private final FishingBoat boat = new FishingBoat();
|
||||||
|
|
||||||
public FishingBoatAdapter() {
|
|
||||||
boat = new FishingBoat();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void row() {
|
public final void row() {
|
||||||
boat.sail();
|
boat.sail();
|
||||||
|
@ -23,18 +23,19 @@
|
|||||||
|
|
||||||
package com.iluwatar.adapter;
|
package com.iluwatar.adapter;
|
||||||
|
|
||||||
import static org.mockito.Mockito.spy;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import static org.mockito.Mockito.verify;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class
|
* Test class
|
||||||
*/
|
*/
|
||||||
public class AdapterPatternTest {
|
class AdapterPatternTest {
|
||||||
|
|
||||||
private Map<String, Object> beans;
|
private Map<String, Object> beans;
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ public class AdapterPatternTest {
|
|||||||
* by the client ({@link Captain} ).
|
* by the client ({@link Captain} ).
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAdapter() {
|
void testAdapter() {
|
||||||
var captain = (Captain) beans.get(ROWING_BEAN);
|
var captain = (Captain) beans.get(ROWING_BEAN);
|
||||||
|
|
||||||
// when captain moves
|
// when captain moves
|
||||||
|
@ -26,8 +26,7 @@ package com.iluwatar.aggregator.microservices;
|
|||||||
import static java.util.Objects.requireNonNullElse;
|
import static java.util.Objects.requireNonNullElse;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,20 +36,18 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
public class Aggregator {
|
public class Aggregator {
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProductInformationClient informationClient;
|
private ProductInformationClient informationClient;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProductInventoryClient inventoryClient;
|
private ProductInventoryClient inventoryClient;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves product data.
|
* Retrieves product data.
|
||||||
*
|
*
|
||||||
* @return a Product.
|
* @return a Product.
|
||||||
*/
|
*/
|
||||||
@RequestMapping(path = "/product", method = RequestMethod.GET)
|
@GetMapping("/product")
|
||||||
public Product getProduct() {
|
public Product getProduct() {
|
||||||
|
|
||||||
var product = new Product();
|
var product = new Product();
|
||||||
|
@ -23,9 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.aggregator.microservices;
|
package com.iluwatar.aggregator.microservices;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates all the data for a Product that clients will request.
|
* Encapsulates all the data for a Product that clients will request.
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
public class Product {
|
public class Product {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,20 +44,4 @@ public class Product {
|
|||||||
*/
|
*/
|
||||||
private int productInventories;
|
private int productInventories;
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProductInventories() {
|
|
||||||
return productInventories;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProductInventories(int productInventories) {
|
|
||||||
this.productInventories = productInventories;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,18 +28,16 @@ import java.net.URI;
|
|||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An adapter to communicate with information micro-service.
|
* An adapter to communicate with information micro-service.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class ProductInformationClientImpl implements ProductInformationClient {
|
public class ProductInformationClientImpl implements ProductInformationClient {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ProductInformationClientImpl.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getProductTitle() {
|
public String getProductTitle() {
|
||||||
var request = HttpRequest.newBuilder()
|
var request = HttpRequest.newBuilder()
|
||||||
@ -54,6 +52,7 @@ public class ProductInformationClientImpl implements ProductInformationClient {
|
|||||||
LOGGER.error("IOException Occurred", ioe);
|
LOGGER.error("IOException Occurred", ioe);
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
LOGGER.error("InterruptedException Occurred", ie);
|
LOGGER.error("InterruptedException Occurred", ie);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -28,18 +28,16 @@ import java.net.URI;
|
|||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An adapter to communicate with inventory micro-service.
|
* An adapter to communicate with inventory micro-service.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class ProductInventoryClientImpl implements ProductInventoryClient {
|
public class ProductInventoryClientImpl implements ProductInventoryClient {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ProductInventoryClientImpl.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer getProductInventories() {
|
public Integer getProductInventories() {
|
||||||
var response = "";
|
var response = "";
|
||||||
@ -56,6 +54,7 @@ public class ProductInventoryClientImpl implements ProductInventoryClient {
|
|||||||
LOGGER.error("IOException Occurred", ioe);
|
LOGGER.error("IOException Occurred", ioe);
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
LOGGER.error("InterruptedException Occurred", ie);
|
LOGGER.error("InterruptedException Occurred", ie);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
if ("".equalsIgnoreCase(response)) {
|
if ("".equalsIgnoreCase(response)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -23,19 +23,19 @@
|
|||||||
|
|
||||||
package com.iluwatar.aggregator.microservices;
|
package com.iluwatar.aggregator.microservices;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Aggregation of domain objects
|
* Test Aggregation of domain objects
|
||||||
*/
|
*/
|
||||||
public class AggregatorTest {
|
class AggregatorTest {
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private Aggregator aggregator;
|
private Aggregator aggregator;
|
||||||
@ -55,7 +55,7 @@ public class AggregatorTest {
|
|||||||
* Tests getting the data for a desktop client
|
* Tests getting the data for a desktop client
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetProduct() {
|
void testGetProduct() {
|
||||||
var title = "The Product Title.";
|
var title = "The Product Title.";
|
||||||
var inventories = 5;
|
var inventories = 5;
|
||||||
|
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.information.microservice;
|
package com.iluwatar.information.microservice;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +37,7 @@ public class InformationController {
|
|||||||
*
|
*
|
||||||
* @return product inventory.
|
* @return product inventory.
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/information", method = RequestMethod.GET)
|
@GetMapping("/information")
|
||||||
public String getProductTitle() {
|
public String getProductTitle() {
|
||||||
return "The Product Title.";
|
return "The Product Title.";
|
||||||
}
|
}
|
||||||
|
@ -23,17 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.information.microservice;
|
package com.iluwatar.information.microservice;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for Information Rest Controller
|
* Test for Information Rest Controller
|
||||||
*/
|
*/
|
||||||
public class InformationControllerTest {
|
class InformationControllerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldGetProductTitle() {
|
void shouldGetProductTitle() {
|
||||||
var infoController = new InformationController();
|
var infoController = new InformationController();
|
||||||
var title = infoController.getProductTitle();
|
var title = infoController.getProductTitle();
|
||||||
assertEquals("The Product Title.", title);
|
assertEquals("The Product Title.", title);
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.inventory.microservice;
|
package com.iluwatar.inventory.microservice;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +37,7 @@ public class InventoryController {
|
|||||||
*
|
*
|
||||||
* @return product inventory.
|
* @return product inventory.
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/inventories", method = RequestMethod.GET)
|
@GetMapping("/inventories")
|
||||||
public int getProductInventories() {
|
public int getProductInventories() {
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
@ -23,16 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.inventory.microservice;
|
package com.iluwatar.inventory.microservice;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Inventory Rest Controller
|
* Test Inventory Rest Controller
|
||||||
*/
|
*/
|
||||||
public class InventoryControllerTest {
|
class InventoryControllerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetProductInventories() {
|
void testGetProductInventories() {
|
||||||
var inventoryController = new InventoryController();
|
var inventoryController = new InventoryController();
|
||||||
var numberOfInventories = inventoryController.getProductInventories();
|
var numberOfInventories = inventoryController.getProductInventories();
|
||||||
assertEquals(5, numberOfInventories);
|
assertEquals(5, numberOfInventories);
|
||||||
|
@ -48,9 +48,8 @@ interface RemoteServiceInterface {
|
|||||||
A remote services represented as a singleton.
|
A remote services represented as a singleton.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public class RemoteService implements RemoteServiceInterface {
|
public class RemoteService implements RemoteServiceInterface {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
|
|
||||||
private static RemoteService service = null;
|
private static RemoteService service = null;
|
||||||
|
|
||||||
static synchronized RemoteService getRemoteService() {
|
static synchronized RemoteService getRemoteService() {
|
||||||
@ -80,9 +79,8 @@ public class RemoteService implements RemoteServiceInterface {
|
|||||||
A service ambassador adding additional features such as logging, latency checks
|
A service ambassador adding additional features such as logging, latency checks
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public class ServiceAmbassador implements RemoteServiceInterface {
|
public class ServiceAmbassador implements RemoteServiceInterface {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceAmbassador.class);
|
|
||||||
private static final int RETRIES = 3;
|
private static final int RETRIES = 3;
|
||||||
private static final int DELAY_MS = 3000;
|
private static final int DELAY_MS = 3000;
|
||||||
|
|
||||||
@ -132,9 +130,8 @@ public class ServiceAmbassador implements RemoteServiceInterface {
|
|||||||
A client has a local service ambassador used to interact with the remote service:
|
A client has a local service ambassador used to interact with the remote service:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public class Client {
|
public class Client {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Client.class);
|
|
||||||
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
|
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
|
||||||
|
|
||||||
long useService(int value) {
|
long useService(int value) {
|
||||||
|
@ -23,20 +23,19 @@
|
|||||||
|
|
||||||
package com.iluwatar.ambassador;
|
package com.iluwatar.ambassador;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple Client.
|
* A simple Client.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class Client {
|
public class Client {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Client.class);
|
|
||||||
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
|
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
|
||||||
|
|
||||||
long useService(int value) {
|
long useService(int value) {
|
||||||
var result = serviceAmbassador.doRemoteFunction(value);
|
var result = serviceAmbassador.doRemoteFunction(value);
|
||||||
LOGGER.info("Service result: " + result);
|
LOGGER.info("Service result: {}", result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,14 @@ package com.iluwatar.ambassador;
|
|||||||
import static java.lang.Thread.sleep;
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
import com.iluwatar.ambassador.util.RandomProvider;
|
import com.iluwatar.ambassador.util.RandomProvider;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A remote legacy application represented by a Singleton implementation.
|
* A remote legacy application represented by a Singleton implementation.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class RemoteService implements RemoteServiceInterface {
|
public class RemoteService implements RemoteServiceInterface {
|
||||||
private static final int THRESHOLD = 200;
|
private static final int THRESHOLD = 200;
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
|
|
||||||
private static RemoteService service = null;
|
private static RemoteService service = null;
|
||||||
private final RandomProvider randomProvider;
|
private final RandomProvider randomProvider;
|
||||||
|
|
||||||
@ -73,6 +72,7 @@ public class RemoteService implements RemoteServiceInterface {
|
|||||||
sleep(waitTime);
|
sleep(waitTime);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOGGER.error("Thread sleep state interrupted", e);
|
LOGGER.error("Thread sleep state interrupted", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
return waitTime <= THRESHOLD ? value * 10
|
return waitTime <= THRESHOLD ? value * 10
|
||||||
: RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue();
|
: RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue();
|
||||||
|
@ -33,8 +33,7 @@ package com.iluwatar.ambassador;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public enum RemoteServiceStatus {
|
public enum RemoteServiceStatus {
|
||||||
FAILURE(-1)
|
FAILURE(-1);
|
||||||
;
|
|
||||||
|
|
||||||
private final long remoteServiceStatusValue;
|
private final long remoteServiceStatusValue;
|
||||||
|
|
||||||
|
@ -26,17 +26,16 @@ package com.iluwatar.ambassador;
|
|||||||
import static com.iluwatar.ambassador.RemoteServiceStatus.FAILURE;
|
import static com.iluwatar.ambassador.RemoteServiceStatus.FAILURE;
|
||||||
import static java.lang.Thread.sleep;
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceAmbassador provides an interface for a ({@link Client}) to access ({@link RemoteService}).
|
* ServiceAmbassador provides an interface for a ({@link Client}) to access ({@link RemoteService}).
|
||||||
* The interface adds logging, latency testing and usage of the service in a safe way that will not
|
* The interface adds logging, latency testing and usage of the service in a safe way that will not
|
||||||
* add stress to the remote service when connectivity issues occur.
|
* add stress to the remote service when connectivity issues occur.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class ServiceAmbassador implements RemoteServiceInterface {
|
public class ServiceAmbassador implements RemoteServiceInterface {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceAmbassador.class);
|
|
||||||
private static final int RETRIES = 3;
|
private static final int RETRIES = 3;
|
||||||
private static final int DELAY_MS = 3000;
|
private static final int DELAY_MS = 3000;
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ public class ServiceAmbassador implements RemoteServiceInterface {
|
|||||||
var result = RemoteService.getRemoteService().doRemoteFunction(value);
|
var result = RemoteService.getRemoteService().doRemoteFunction(value);
|
||||||
var timeTaken = System.currentTimeMillis() - startTime;
|
var timeTaken = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
LOGGER.info("Time taken (ms): " + timeTaken);
|
LOGGER.info("Time taken (ms): {}", timeTaken);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,12 +66,13 @@ public class ServiceAmbassador implements RemoteServiceInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((result = checkLatency(value)) == FAILURE.getRemoteServiceStatusValue()) {
|
if ((result = checkLatency(value)) == FAILURE.getRemoteServiceStatusValue()) {
|
||||||
LOGGER.info("Failed to reach remote: (" + (i + 1) + ")");
|
LOGGER.info("Failed to reach remote: ({})", i + 1);
|
||||||
retries++;
|
retries++;
|
||||||
try {
|
try {
|
||||||
sleep(DELAY_MS);
|
sleep(DELAY_MS);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOGGER.error("Thread sleep state interrupted", e);
|
LOGGER.error("Thread sleep state interrupted", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
package com.iluwatar.api.gateway;
|
package com.iluwatar.api.gateway;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +44,7 @@ public class ApiGateway {
|
|||||||
*
|
*
|
||||||
* @return Product information for clients on a desktop
|
* @return Product information for clients on a desktop
|
||||||
*/
|
*/
|
||||||
@RequestMapping(path = "/desktop", method = RequestMethod.GET)
|
@GetMapping("/desktop")
|
||||||
public DesktopProduct getProductDesktop() {
|
public DesktopProduct getProductDesktop() {
|
||||||
var desktopProduct = new DesktopProduct();
|
var desktopProduct = new DesktopProduct();
|
||||||
desktopProduct.setImagePath(imageClient.getImagePath());
|
desktopProduct.setImagePath(imageClient.getImagePath());
|
||||||
@ -58,7 +57,7 @@ public class ApiGateway {
|
|||||||
*
|
*
|
||||||
* @return Product information for clients on a mobile device
|
* @return Product information for clients on a mobile device
|
||||||
*/
|
*/
|
||||||
@RequestMapping(path = "/mobile", method = RequestMethod.GET)
|
@GetMapping("/mobile")
|
||||||
public MobileProduct getProductMobile() {
|
public MobileProduct getProductMobile() {
|
||||||
var mobileProduct = new MobileProduct();
|
var mobileProduct = new MobileProduct();
|
||||||
mobileProduct.setPrice(priceClient.getPrice());
|
mobileProduct.setPrice(priceClient.getPrice());
|
||||||
|
@ -23,10 +23,16 @@
|
|||||||
|
|
||||||
package com.iluwatar.api.gateway;
|
package com.iluwatar.api.gateway;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates all of the information that a desktop client needs to display a product.
|
* Encapsulates all of the information that a desktop client needs to display a product.
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
public class DesktopProduct {
|
public class DesktopProduct {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The price of the product.
|
* The price of the product.
|
||||||
*/
|
*/
|
||||||
@ -37,19 +43,4 @@ public class DesktopProduct {
|
|||||||
*/
|
*/
|
||||||
private String imagePath;
|
private String imagePath;
|
||||||
|
|
||||||
public String getPrice() {
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrice(String price) {
|
|
||||||
this.price = price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getImagePath() {
|
|
||||||
return imagePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImagePath(String imagePath) {
|
|
||||||
this.imagePath = imagePath;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,24 +23,21 @@
|
|||||||
|
|
||||||
package com.iluwatar.api.gateway;
|
package com.iluwatar.api.gateway;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import java.net.http.HttpResponse.BodyHandlers;
|
import java.net.http.HttpResponse.BodyHandlers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An adapter to communicate with the Image microservice.
|
* An adapter to communicate with the Image microservice.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class ImageClientImpl implements ImageClient {
|
public class ImageClientImpl implements ImageClient {
|
||||||
private static final Logger LOGGER = getLogger(ImageClientImpl.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a simple HTTP Get request to the Image microservice.
|
* Makes a simple HTTP Get request to the Image microservice.
|
||||||
@ -60,8 +57,11 @@ public class ImageClientImpl implements ImageClient {
|
|||||||
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
|
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
|
||||||
logResponse(httpResponse);
|
logResponse(httpResponse);
|
||||||
return httpResponse.body();
|
return httpResponse.body();
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException ioe) {
|
||||||
LOGGER.error("Failure occurred while getting image path", e);
|
LOGGER.error("Failure occurred while getting image path", ioe);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
LOGGER.error("Failure occurred while getting image path", ie);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -23,20 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.api.gateway;
|
package com.iluwatar.api.gateway;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates all of the information that mobile client needs to display a product.
|
* Encapsulates all of the information that mobile client needs to display a product.
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
public class MobileProduct {
|
public class MobileProduct {
|
||||||
/**
|
/**
|
||||||
* The price of the product.
|
* The price of the product.
|
||||||
*/
|
*/
|
||||||
private String price;
|
private String price;
|
||||||
|
|
||||||
public String getPrice() {
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrice(String price) {
|
|
||||||
this.price = price;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,25 +23,22 @@
|
|||||||
|
|
||||||
package com.iluwatar.api.gateway;
|
package com.iluwatar.api.gateway;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import java.net.http.HttpResponse.BodyHandlers;
|
import java.net.http.HttpResponse.BodyHandlers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An adapter to communicate with the Price microservice.
|
* An adapter to communicate with the Price microservice.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class PriceClientImpl implements PriceClient {
|
public class PriceClientImpl implements PriceClient {
|
||||||
private static final Logger LOGGER = getLogger(PriceClientImpl.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a simple HTTP Get request to the Price microservice.
|
* Makes a simple HTTP Get request to the Price microservice.
|
||||||
@ -61,8 +58,11 @@ public class PriceClientImpl implements PriceClient {
|
|||||||
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
|
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
|
||||||
logResponse(httpResponse);
|
logResponse(httpResponse);
|
||||||
return httpResponse.body();
|
return httpResponse.body();
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error("Failure occurred while getting price info", e);
|
LOGGER.error("Failure occurred while getting price info", e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.error("Failure occurred while getting price info", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -35,7 +35,7 @@ import org.mockito.MockitoAnnotations;
|
|||||||
/**
|
/**
|
||||||
* Test API Gateway Pattern
|
* Test API Gateway Pattern
|
||||||
*/
|
*/
|
||||||
public class ApiGatewayTest {
|
class ApiGatewayTest {
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private ApiGateway apiGateway;
|
private ApiGateway apiGateway;
|
||||||
@ -55,7 +55,7 @@ public class ApiGatewayTest {
|
|||||||
* Tests getting the data for a desktop client
|
* Tests getting the data for a desktop client
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetProductDesktop() {
|
void testGetProductDesktop() {
|
||||||
var imagePath = "/product-image.png";
|
var imagePath = "/product-image.png";
|
||||||
var price = "20";
|
var price = "20";
|
||||||
when(imageClient.getImagePath()).thenReturn(imagePath);
|
when(imageClient.getImagePath()).thenReturn(imagePath);
|
||||||
@ -71,7 +71,7 @@ public class ApiGatewayTest {
|
|||||||
* Tests getting the data for a mobile client
|
* Tests getting the data for a mobile client
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetProductMobile() {
|
void testGetProductMobile() {
|
||||||
var price = "20";
|
var price = "20";
|
||||||
when(priceClient.getPrice()).thenReturn(price);
|
when(priceClient.getPrice()).thenReturn(price);
|
||||||
|
|
||||||
|
@ -23,27 +23,24 @@
|
|||||||
|
|
||||||
package com.iluwatar.image.microservice;
|
package com.iluwatar.image.microservice;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exposes the Image microservice's endpoints.
|
* Exposes the Image microservice's endpoints.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
public class ImageController {
|
public class ImageController {
|
||||||
private static final Logger LOGGER = getLogger(ImageController.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An endpoint for a user to retrieve an image path.
|
* An endpoint for a user to retrieve an image path.
|
||||||
*
|
*
|
||||||
* @return An image path
|
* @return An image path
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/image-path", method = RequestMethod.GET)
|
@GetMapping("/image-path")
|
||||||
public String getImagePath() {
|
public String getImagePath() {
|
||||||
LOGGER.info("Successfully found image path");
|
LOGGER.info("Successfully found image path");
|
||||||
return "/product-image.png";
|
return "/product-image.png";
|
||||||
|
@ -23,16 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.image.microservice;
|
package com.iluwatar.image.microservice;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for Image Rest Controller
|
* Test for Image Rest Controller
|
||||||
*/
|
*/
|
||||||
public class ImageControllerTest {
|
class ImageControllerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetImagePath() {
|
void testGetImagePath() {
|
||||||
var imageController = new ImageController();
|
var imageController = new ImageController();
|
||||||
var imagePath = imageController.getImagePath();
|
var imagePath = imageController.getImagePath();
|
||||||
assertEquals("/product-image.png", imagePath);
|
assertEquals("/product-image.png", imagePath);
|
||||||
|
@ -23,27 +23,24 @@
|
|||||||
|
|
||||||
package com.iluwatar.price.microservice;
|
package com.iluwatar.price.microservice;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exposes the Price microservice's endpoints.
|
* Exposes the Price microservice's endpoints.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
public class PriceController {
|
public class PriceController {
|
||||||
private static final Logger LOGGER = getLogger(PriceController.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An endpoint for a user to retrieve a product's price.
|
* An endpoint for a user to retrieve a product's price.
|
||||||
*
|
*
|
||||||
* @return A product's price
|
* @return A product's price
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/price", method = RequestMethod.GET)
|
@GetMapping("/price")
|
||||||
public String getPrice() {
|
public String getPrice() {
|
||||||
LOGGER.info("Successfully found price info");
|
LOGGER.info("Successfully found price info");
|
||||||
return "20";
|
return "20";
|
||||||
|
@ -23,16 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.price.microservice;
|
package com.iluwatar.price.microservice;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for Price Rest Controller
|
* Test for Price Rest Controller
|
||||||
*/
|
*/
|
||||||
public class PriceControllerTest {
|
class PriceControllerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testgetPrice() {
|
void testgetPrice() {
|
||||||
var priceController = new PriceController();
|
var priceController = new PriceController();
|
||||||
var price = priceController.getPrice();
|
var price = priceController.getPrice();
|
||||||
assertEquals("20", price);
|
assertEquals("20", price);
|
||||||
|
@ -81,10 +81,10 @@ Then we write our unit tests according to Arrange/Act/Assert pattern. Notice the
|
|||||||
separated steps for each unit test.
|
separated steps for each unit test.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class CashAAATest {
|
class CashAAATest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPlus() {
|
void testPlus() {
|
||||||
//Arrange
|
//Arrange
|
||||||
var cash = new Cash(3);
|
var cash = new Cash(3);
|
||||||
//Act
|
//Act
|
||||||
@ -94,7 +94,7 @@ public class CashAAATest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMinus() {
|
void testMinus() {
|
||||||
//Arrange
|
//Arrange
|
||||||
var cash = new Cash(8);
|
var cash = new Cash(8);
|
||||||
//Act
|
//Act
|
||||||
@ -105,7 +105,7 @@ public class CashAAATest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInsufficientMinus() {
|
void testInsufficientMinus() {
|
||||||
//Arrange
|
//Arrange
|
||||||
var cash = new Cash(1);
|
var cash = new Cash(1);
|
||||||
//Act
|
//Act
|
||||||
@ -116,7 +116,7 @@ public class CashAAATest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdate() {
|
void testUpdate() {
|
||||||
//Arrange
|
//Arrange
|
||||||
var cash = new Cash(5);
|
var cash = new Cash(5);
|
||||||
//Act
|
//Act
|
||||||
|
@ -23,18 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.arrangeactassert;
|
package com.iluwatar.arrangeactassert;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arrange/Act/Assert (AAA) is a unit test pattern. In this simple example, we have a ({@link Cash})
|
* Arrange/Act/Assert (AAA) is a unit test pattern. In this simple example, we have a ({@link Cash})
|
||||||
* object for plus, minus and counting amount.
|
* object for plus, minus and counting amount.
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
public class Cash {
|
public class Cash {
|
||||||
|
|
||||||
private int amount;
|
private int amount;
|
||||||
|
|
||||||
Cash(int amount) {
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//plus
|
//plus
|
||||||
void plus(int addend) {
|
void plus(int addend) {
|
||||||
amount += addend;
|
amount += addend;
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
package com.iluwatar.async.method.invocation;
|
package com.iluwatar.async.method.invocation;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This application demonstrates the async method invocation pattern. Key parts of the pattern are
|
* This application demonstrates the async method invocation pattern. Key parts of the pattern are
|
||||||
@ -55,10 +54,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @see java.util.concurrent.CompletableFuture
|
* @see java.util.concurrent.CompletableFuture
|
||||||
* @see java.util.concurrent.ExecutorService
|
* @see java.util.concurrent.ExecutorService
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*/
|
*/
|
||||||
|
@ -23,11 +23,9 @@
|
|||||||
|
|
||||||
package com.iluwatar.balking;
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In Balking Design Pattern if an object’s method is invoked when it is in an inappropriate state,
|
* In Balking Design Pattern if an object’s method is invoked when it is in an inappropriate state,
|
||||||
@ -40,11 +38,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* been already washing and any other thread execute wash() it can't do that once again and returns
|
* been already washing and any other thread execute wash() it can't do that once again and returns
|
||||||
* doing nothing.
|
* doing nothing.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry Point.
|
* Entry Point.
|
||||||
*
|
*
|
||||||
@ -61,6 +57,7 @@ public class App {
|
|||||||
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
LOGGER.error("ERROR: Waiting on executor service shutdown!");
|
LOGGER.error("ERROR: Waiting on executor service shutdown!");
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,15 +24,14 @@
|
|||||||
package com.iluwatar.balking;
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Washing machine class.
|
* Washing machine class.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class WashingMachine {
|
public class WashingMachine {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class);
|
|
||||||
private final DelayProvider delayProvider;
|
private final DelayProvider delayProvider;
|
||||||
private WashingMachineState washingMachineState;
|
private WashingMachineState washingMachineState;
|
||||||
|
|
||||||
@ -44,7 +43,8 @@ public class WashingMachine {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(timeUnit.toMillis(interval));
|
Thread.sleep(timeUnit.toMillis(interval));
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
ie.printStackTrace();
|
LOGGER.error("", ie);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
task.run();
|
task.run();
|
||||||
});
|
});
|
||||||
@ -71,7 +71,7 @@ public class WashingMachine {
|
|||||||
var machineState = getWashingMachineState();
|
var machineState = getWashingMachineState();
|
||||||
LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), machineState);
|
LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), machineState);
|
||||||
if (this.washingMachineState == WashingMachineState.WASHING) {
|
if (this.washingMachineState == WashingMachineState.WASHING) {
|
||||||
LOGGER.error("ERROR: Cannot wash if the machine has been already washing!");
|
LOGGER.error("Cannot wash if the machine has been already washing!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.washingMachineState = WashingMachineState.WASHING;
|
this.washingMachineState = WashingMachineState.WASHING;
|
||||||
|
@ -28,5 +28,6 @@ package com.iluwatar.balking;
|
|||||||
* as well as during washing.
|
* as well as during washing.
|
||||||
*/
|
*/
|
||||||
public enum WashingMachineState {
|
public enum WashingMachineState {
|
||||||
ENABLED, WASHING
|
ENABLED,
|
||||||
|
WASHING
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.bridge;
|
package com.iluwatar.bridge;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composition over inheritance. The Bridge pattern can also be thought of as two layers of
|
* Composition over inheritance. The Bridge pattern can also be thought of as two layers of
|
||||||
@ -39,10 +38,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* enchantments. We can easily combine any weapon with any enchantment using composition instead of
|
* enchantments. We can easily combine any weapon with any enchantment using composition instead of
|
||||||
* creating deep class hierarchy.
|
* creating deep class hierarchy.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
|
@ -23,16 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.bridge;
|
package com.iluwatar.bridge;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FlyingEnchantment.
|
* FlyingEnchantment.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class FlyingEnchantment implements Enchantment {
|
public class FlyingEnchantment implements Enchantment {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(FlyingEnchantment.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivate() {
|
public void onActivate() {
|
||||||
LOGGER.info("The item begins to glow faintly.");
|
LOGGER.info("The item begins to glow faintly.");
|
||||||
|
@ -23,22 +23,18 @@
|
|||||||
|
|
||||||
package com.iluwatar.bridge;
|
package com.iluwatar.bridge;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.AllArgsConstructor;
|
||||||
import org.slf4j.LoggerFactory;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hammer.
|
* Hammer.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
public class Hammer implements Weapon {
|
public class Hammer implements Weapon {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Hammer.class);
|
|
||||||
|
|
||||||
private final Enchantment enchantment;
|
private final Enchantment enchantment;
|
||||||
|
|
||||||
public Hammer(Enchantment enchantment) {
|
|
||||||
this.enchantment = enchantment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wield() {
|
public void wield() {
|
||||||
LOGGER.info("The hammer is wielded.");
|
LOGGER.info("The hammer is wielded.");
|
||||||
|
@ -23,16 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.bridge;
|
package com.iluwatar.bridge;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SoulEatingEnchantment.
|
* SoulEatingEnchantment.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class SoulEatingEnchantment implements Enchantment {
|
public class SoulEatingEnchantment implements Enchantment {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(SoulEatingEnchantment.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivate() {
|
public void onActivate() {
|
||||||
LOGGER.info("The item spreads bloodlust.");
|
LOGGER.info("The item spreads bloodlust.");
|
||||||
|
@ -23,22 +23,18 @@
|
|||||||
|
|
||||||
package com.iluwatar.bridge;
|
package com.iluwatar.bridge;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.AllArgsConstructor;
|
||||||
import org.slf4j.LoggerFactory;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sword.
|
* Sword.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
public class Sword implements Weapon {
|
public class Sword implements Weapon {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Sword.class);
|
|
||||||
|
|
||||||
private final Enchantment enchantment;
|
private final Enchantment enchantment;
|
||||||
|
|
||||||
public Sword(Enchantment enchantment) {
|
|
||||||
this.enchantment = enchantment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wield() {
|
public void wield() {
|
||||||
LOGGER.info("The sword is wielded.");
|
LOGGER.info("The sword is wielded.");
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
package com.iluwatar.builder;
|
package com.iluwatar.builder;
|
||||||
|
|
||||||
import com.iluwatar.builder.Hero.Builder;
|
import com.iluwatar.builder.Hero.Builder;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The intention of the Builder pattern is to find a solution to the telescoping constructor
|
* The intention of the Builder pattern is to find a solution to the telescoping constructor
|
||||||
@ -48,10 +47,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* configuration for the {@link Hero} object can be done using the fluent {@link Builder} interface.
|
* configuration for the {@link Hero} object can be done using the fluent {@link Builder} interface.
|
||||||
* When configuration is ready the build method is called to receive the final {@link Hero} object.
|
* When configuration is ready the build method is called to receive the final {@link Hero} object.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
@ -76,6 +74,5 @@ public class App {
|
|||||||
.withWeapon(Weapon.BOW)
|
.withWeapon(Weapon.BOW)
|
||||||
.build();
|
.build();
|
||||||
LOGGER.info(thief.toString());
|
LOGGER.info(thief.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,19 +23,21 @@
|
|||||||
|
|
||||||
package com.iluwatar.builder;
|
package com.iluwatar.builder;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Armor enumeration.
|
* Armor enumeration.
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
public enum Armor {
|
public enum Armor {
|
||||||
|
|
||||||
CLOTHES("clothes"), LEATHER("leather"), CHAIN_MAIL("chain mail"), PLATE_MAIL("plate mail");
|
CLOTHES("clothes"),
|
||||||
|
LEATHER("leather"),
|
||||||
|
CHAIN_MAIL("chain mail"),
|
||||||
|
PLATE_MAIL("plate mail");
|
||||||
|
|
||||||
private final String title;
|
private final String title;
|
||||||
|
|
||||||
Armor(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return title;
|
return title;
|
||||||
|
@ -28,7 +28,11 @@ package com.iluwatar.builder;
|
|||||||
*/
|
*/
|
||||||
public enum HairColor {
|
public enum HairColor {
|
||||||
|
|
||||||
WHITE, BLOND, RED, BROWN, BLACK;
|
WHITE,
|
||||||
|
BLOND,
|
||||||
|
RED,
|
||||||
|
BROWN,
|
||||||
|
BLACK;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -23,20 +23,22 @@
|
|||||||
|
|
||||||
package com.iluwatar.builder;
|
package com.iluwatar.builder;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HairType enumeration.
|
* HairType enumeration.
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
public enum HairType {
|
public enum HairType {
|
||||||
|
|
||||||
BALD("bald"), SHORT("short"), CURLY("curly"), LONG_STRAIGHT("long straight"), LONG_CURLY(
|
BALD("bald"),
|
||||||
"long curly");
|
SHORT("short"),
|
||||||
|
CURLY("curly"),
|
||||||
|
LONG_STRAIGHT("long straight"),
|
||||||
|
LONG_CURLY("long curly");
|
||||||
|
|
||||||
private final String title;
|
private final String title;
|
||||||
|
|
||||||
HairType(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return title;
|
return title;
|
||||||
|
@ -41,7 +41,6 @@ class AppTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldExecuteApplicationWithoutException() {
|
void shouldExecuteApplicationWithoutException() {
|
||||||
|
|
||||||
assertDoesNotThrow(() -> App.main(new String[]{}));
|
assertDoesNotThrow(() -> App.main(new String[]{}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ package com.iluwatar.business.delegate;
|
|||||||
public class BusinessDelegate {
|
public class BusinessDelegate {
|
||||||
|
|
||||||
private BusinessLookup lookupService;
|
private BusinessLookup lookupService;
|
||||||
private BusinessService businessService;
|
|
||||||
private ServiceType serviceType;
|
private ServiceType serviceType;
|
||||||
|
|
||||||
public void setLookupService(BusinessLookup businessLookup) {
|
public void setLookupService(BusinessLookup businessLookup) {
|
||||||
@ -41,7 +40,7 @@ public class BusinessDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void doTask() {
|
public void doTask() {
|
||||||
businessService = lookupService.getBusinessService(serviceType);
|
BusinessService businessService = lookupService.getBusinessService(serviceType);
|
||||||
businessService.doProcessing();
|
businessService.doProcessing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,12 @@
|
|||||||
|
|
||||||
package com.iluwatar.business.delegate;
|
package com.iluwatar.business.delegate;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for performing service lookups.
|
* Class for performing service lookups.
|
||||||
*/
|
*/
|
||||||
|
@Setter
|
||||||
public class BusinessLookup {
|
public class BusinessLookup {
|
||||||
|
|
||||||
private EjbService ejbService;
|
private EjbService ejbService;
|
||||||
@ -45,12 +48,4 @@ public class BusinessLookup {
|
|||||||
return jmsService;
|
return jmsService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJmsService(JmsService jmsService) {
|
|
||||||
this.jmsService = jmsService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEjbService(EjbService ejbService) {
|
|
||||||
this.ejbService = ejbService;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,16 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.business.delegate;
|
package com.iluwatar.business.delegate;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service EJB implementation.
|
* Service EJB implementation.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class EjbService implements BusinessService {
|
public class EjbService implements BusinessService {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(EjbService.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doProcessing() {
|
public void doProcessing() {
|
||||||
LOGGER.info("EjbService is now processing");
|
LOGGER.info("EjbService is now processing");
|
||||||
|
@ -23,16 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.business.delegate;
|
package com.iluwatar.business.delegate;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service JMS implementation.
|
* Service JMS implementation.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class JmsService implements BusinessService {
|
public class JmsService implements BusinessService {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(JmsService.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doProcessing() {
|
public void doProcessing() {
|
||||||
LOGGER.info("JmsService is now processing");
|
LOGGER.info("JmsService is now processing");
|
||||||
|
@ -28,5 +28,6 @@ package com.iluwatar.business.delegate;
|
|||||||
*/
|
*/
|
||||||
public enum ServiceType {
|
public enum ServiceType {
|
||||||
|
|
||||||
EJB, JMS
|
EJB,
|
||||||
|
JMS
|
||||||
}
|
}
|
||||||
|
@ -40,14 +40,12 @@ import static org.mockito.Mockito.verify;
|
|||||||
* retrieved through service lookups. The Business Delegate itself may contain business logic too
|
* retrieved through service lookups. The Business Delegate itself may contain business logic too
|
||||||
* potentially tying together multiple service calls, exception handling, retrying etc.
|
* potentially tying together multiple service calls, exception handling, retrying etc.
|
||||||
*/
|
*/
|
||||||
public class BusinessDelegateTest {
|
class BusinessDelegateTest {
|
||||||
|
|
||||||
private EjbService ejbService;
|
private EjbService ejbService;
|
||||||
|
|
||||||
private JmsService jmsService;
|
private JmsService jmsService;
|
||||||
|
|
||||||
private BusinessLookup businessLookup;
|
|
||||||
|
|
||||||
private BusinessDelegate businessDelegate;
|
private BusinessDelegate businessDelegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +57,7 @@ public class BusinessDelegateTest {
|
|||||||
ejbService = spy(new EjbService());
|
ejbService = spy(new EjbService());
|
||||||
jmsService = spy(new JmsService());
|
jmsService = spy(new JmsService());
|
||||||
|
|
||||||
businessLookup = spy(new BusinessLookup());
|
BusinessLookup businessLookup = spy(new BusinessLookup());
|
||||||
businessLookup.setEjbService(ejbService);
|
businessLookup.setEjbService(ejbService);
|
||||||
businessLookup.setJmsService(jmsService);
|
businessLookup.setJmsService(jmsService);
|
||||||
|
|
||||||
@ -73,7 +71,7 @@ public class BusinessDelegateTest {
|
|||||||
* service and makes the service call.
|
* service and makes the service call.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBusinessDelegate() {
|
void testBusinessDelegate() {
|
||||||
|
|
||||||
// setup a client object
|
// setup a client object
|
||||||
var client = new Client(businessDelegate);
|
var client = new Client(businessDelegate);
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
package com.iluwatar.bytecode;
|
package com.iluwatar.bytecode;
|
||||||
|
|
||||||
import com.iluwatar.bytecode.util.InstructionConverterUtil;
|
import com.iluwatar.bytecode.util.InstructionConverterUtil;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The intention of Bytecode pattern is to give behavior the flexibility of data by encoding it as
|
* The intention of Bytecode pattern is to give behavior the flexibility of data by encoding it as
|
||||||
@ -40,8 +39,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
* ensure the behavior being defined can’t break the game, you need to sandbox it from the rest of
|
* ensure the behavior being defined can’t break the game, you need to sandbox it from the rest of
|
||||||
* the codebase.
|
* the codebase.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main app method.
|
* Main app method.
|
||||||
|
@ -23,9 +23,14 @@
|
|||||||
|
|
||||||
package com.iluwatar.bytecode;
|
package com.iluwatar.bytecode;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of instructions understandable by virtual machine.
|
* Representation of instructions understandable by virtual machine.
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
public enum Instruction {
|
public enum Instruction {
|
||||||
|
|
||||||
LITERAL(1),
|
LITERAL(1),
|
||||||
@ -40,15 +45,7 @@ public enum Instruction {
|
|||||||
ADD(10),
|
ADD(10),
|
||||||
DIVIDE(11);
|
DIVIDE(11);
|
||||||
|
|
||||||
private final int value;
|
private final int intValue;
|
||||||
|
|
||||||
Instruction(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIntValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts integer value to Instruction.
|
* Converts integer value to Instruction.
|
||||||
|
@ -24,10 +24,12 @@
|
|||||||
package com.iluwatar.bytecode;
|
package com.iluwatar.bytecode;
|
||||||
|
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of virtual machine.
|
* Implementation of virtual machine.
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
public class VirtualMachine {
|
public class VirtualMachine {
|
||||||
|
|
||||||
private final Stack<Integer> stack = new Stack<>();
|
private final Stack<Integer> stack = new Stack<>();
|
||||||
@ -108,10 +110,6 @@ public class VirtualMachine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stack<Integer> getStack() {
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHealth(int wizard, int amount) {
|
public void setHealth(int wizard, int amount) {
|
||||||
wizards[wizard].setHealth(amount);
|
wizards[wizard].setHealth(amount);
|
||||||
}
|
}
|
||||||
@ -135,8 +133,4 @@ public class VirtualMachine {
|
|||||||
public int getAgility(int wizard) {
|
public int getAgility(int wizard) {
|
||||||
return wizards[wizard].getAgility();
|
return wizards[wizard].getAgility();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Wizard[] getWizards() {
|
|
||||||
return wizards;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,18 @@
|
|||||||
|
|
||||||
package com.iluwatar.bytecode;
|
package com.iluwatar.bytecode;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.Getter;
|
||||||
import org.slf4j.LoggerFactory;
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represent game objects which properties can be changed by instructions interpreted by
|
* This class represent game objects which properties can be changed by instructions interpreted by
|
||||||
* virtual machine.
|
* virtual machine.
|
||||||
*/
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Slf4j
|
||||||
public class Wizard {
|
public class Wizard {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class);
|
|
||||||
|
|
||||||
private int health;
|
private int health;
|
||||||
|
|
||||||
@ -41,30 +44,6 @@ public class Wizard {
|
|||||||
private int numberOfPlayedSounds;
|
private int numberOfPlayedSounds;
|
||||||
private int numberOfSpawnedParticles;
|
private int numberOfSpawnedParticles;
|
||||||
|
|
||||||
public int getHealth() {
|
|
||||||
return health;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHealth(int health) {
|
|
||||||
this.health = health;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAgility() {
|
|
||||||
return agility;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAgility(int agility) {
|
|
||||||
this.agility = agility;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWisdom() {
|
|
||||||
return wisdom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWisdom(int wisdom) {
|
|
||||||
this.wisdom = wisdom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playSound() {
|
public void playSound() {
|
||||||
LOGGER.info("Playing sound");
|
LOGGER.info("Playing sound");
|
||||||
numberOfPlayedSounds++;
|
numberOfPlayedSounds++;
|
||||||
@ -75,11 +54,4 @@ public class Wizard {
|
|||||||
numberOfSpawnedParticles++;
|
numberOfSpawnedParticles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumberOfPlayedSounds() {
|
|
||||||
return numberOfPlayedSounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumberOfSpawnedParticles() {
|
|
||||||
return numberOfSpawnedParticles;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,19 +23,19 @@
|
|||||||
|
|
||||||
package com.iluwatar.bytecode;
|
package com.iluwatar.bytecode;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static com.iluwatar.bytecode.Instruction.*;
|
import static com.iluwatar.bytecode.Instruction.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for {@Link VirtualMachine}
|
* Test for {@link VirtualMachine}
|
||||||
*/
|
*/
|
||||||
public class VirtualMachineTest {
|
class VirtualMachineTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLiteral() {
|
void testLiteral() {
|
||||||
var bytecode = new int[2];
|
var bytecode = new int[2];
|
||||||
bytecode[0] = LITERAL.getIntValue();
|
bytecode[0] = LITERAL.getIntValue();
|
||||||
bytecode[1] = 10;
|
bytecode[1] = 10;
|
||||||
@ -48,7 +48,7 @@ public class VirtualMachineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetHealth() {
|
void testSetHealth() {
|
||||||
var wizardNumber = 0;
|
var wizardNumber = 0;
|
||||||
var bytecode = new int[5];
|
var bytecode = new int[5];
|
||||||
bytecode[0] = LITERAL.getIntValue();
|
bytecode[0] = LITERAL.getIntValue();
|
||||||
@ -64,7 +64,7 @@ public class VirtualMachineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetAgility() {
|
void testSetAgility() {
|
||||||
var wizardNumber = 0;
|
var wizardNumber = 0;
|
||||||
var bytecode = new int[5];
|
var bytecode = new int[5];
|
||||||
bytecode[0] = LITERAL.getIntValue();
|
bytecode[0] = LITERAL.getIntValue();
|
||||||
@ -80,7 +80,7 @@ public class VirtualMachineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetWisdom() {
|
void testSetWisdom() {
|
||||||
var wizardNumber = 0;
|
var wizardNumber = 0;
|
||||||
var bytecode = new int[5];
|
var bytecode = new int[5];
|
||||||
bytecode[0] = LITERAL.getIntValue();
|
bytecode[0] = LITERAL.getIntValue();
|
||||||
@ -96,7 +96,7 @@ public class VirtualMachineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetHealth() {
|
void testGetHealth() {
|
||||||
var wizardNumber = 0;
|
var wizardNumber = 0;
|
||||||
var bytecode = new int[8];
|
var bytecode = new int[8];
|
||||||
bytecode[0] = LITERAL.getIntValue();
|
bytecode[0] = LITERAL.getIntValue();
|
||||||
@ -115,7 +115,7 @@ public class VirtualMachineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPlaySound() {
|
void testPlaySound() {
|
||||||
var wizardNumber = 0;
|
var wizardNumber = 0;
|
||||||
var bytecode = new int[3];
|
var bytecode = new int[3];
|
||||||
bytecode[0] = LITERAL.getIntValue();
|
bytecode[0] = LITERAL.getIntValue();
|
||||||
@ -130,7 +130,7 @@ public class VirtualMachineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpawnParticles() {
|
void testSpawnParticles() {
|
||||||
var wizardNumber = 0;
|
var wizardNumber = 0;
|
||||||
var bytecode = new int[3];
|
var bytecode = new int[3];
|
||||||
bytecode[0] = LITERAL.getIntValue();
|
bytecode[0] = LITERAL.getIntValue();
|
||||||
@ -145,7 +145,7 @@ public class VirtualMachineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidInstruction() {
|
void testInvalidInstruction() {
|
||||||
var bytecode = new int[1];
|
var bytecode = new int[1];
|
||||||
bytecode[0] = 999;
|
bytecode[0] = 999;
|
||||||
var vm = new VirtualMachine();
|
var vm = new VirtualMachine();
|
||||||
|
@ -24,16 +24,16 @@
|
|||||||
package com.iluwatar.bytecode.util;
|
package com.iluwatar.bytecode.util;
|
||||||
|
|
||||||
import com.iluwatar.bytecode.Instruction;
|
import com.iluwatar.bytecode.Instruction;
|
||||||
import com.iluwatar.bytecode.util.InstructionConverterUtil;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for {@Link InstructionConverterUtil}
|
* Test for {@link InstructionConverterUtil}
|
||||||
*/
|
*/
|
||||||
public class InstructionConverterUtilTest {
|
class InstructionConverterUtilTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyInstruction() {
|
void testEmptyInstruction() {
|
||||||
var instruction = "";
|
var instruction = "";
|
||||||
|
|
||||||
var bytecode = InstructionConverterUtil.convertToByteCode(instruction);
|
var bytecode = InstructionConverterUtil.convertToByteCode(instruction);
|
||||||
@ -42,7 +42,7 @@ public class InstructionConverterUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInstructions() {
|
void testInstructions() {
|
||||||
var instructions = "LITERAL 35 SET_HEALTH SET_WISDOM SET_AGILITY PLAY_SOUND"
|
var instructions = "LITERAL 35 SET_HEALTH SET_WISDOM SET_AGILITY PLAY_SOUND"
|
||||||
+ " SPAWN_PARTICLES GET_HEALTH ADD DIVIDE";
|
+ " SPAWN_PARTICLES GET_HEALTH ADD DIVIDE";
|
||||||
|
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.caching;
|
package com.iluwatar.caching;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing
|
* The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing
|
||||||
@ -60,11 +59,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @see LruCache
|
* @see LruCache
|
||||||
* @see CachingPolicy
|
* @see CachingPolicy
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
|
@ -26,16 +26,14 @@ package com.iluwatar.caching;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The caching strategies are implemented in this class.
|
* The caching strategies are implemented in this class.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class CacheStore {
|
public class CacheStore {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(CacheStore.class);
|
|
||||||
|
|
||||||
private static LruCache cache;
|
private static LruCache cache;
|
||||||
|
|
||||||
private CacheStore() {
|
private CacheStore() {
|
||||||
|
@ -23,19 +23,19 @@
|
|||||||
|
|
||||||
package com.iluwatar.caching;
|
package com.iluwatar.caching;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum class containing the four caching strategies implemented in the pattern.
|
* Enum class containing the four caching strategies implemented in the pattern.
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
public enum CachingPolicy {
|
public enum CachingPolicy {
|
||||||
THROUGH("through"), AROUND("around"), BEHIND("behind"), ASIDE("aside");
|
THROUGH("through"),
|
||||||
|
AROUND("around"),
|
||||||
|
BEHIND("behind"),
|
||||||
|
ASIDE("aside");
|
||||||
|
|
||||||
private final String policy;
|
private final String policy;
|
||||||
|
|
||||||
CachingPolicy(String policy) {
|
|
||||||
this.policy = policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPolicy() {
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data structure/implementation of the application's cache. The data structure consists of a hash
|
* Data structure/implementation of the application's cache. The data structure consists of a hash
|
||||||
@ -37,11 +36,10 @@ import org.slf4j.LoggerFactory;
|
|||||||
* the data is moved to the front of the list to depict itself as the most-recently-used data. The
|
* the data is moved to the front of the list to depict itself as the most-recently-used data. The
|
||||||
* LRU data is always at the end of the list.
|
* LRU data is always at the end of the list.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class LruCache {
|
public class LruCache {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(LruCache.class);
|
static class Node {
|
||||||
|
|
||||||
class Node {
|
|
||||||
String userId;
|
String userId;
|
||||||
UserAccount userAccount;
|
UserAccount userAccount;
|
||||||
Node previous;
|
Node previous;
|
||||||
|
@ -23,49 +23,20 @@
|
|||||||
|
|
||||||
package com.iluwatar.caching;
|
package com.iluwatar.caching;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity class (stored in cache and DB) used in the application.
|
* Entity class (stored in cache and DB) used in the application.
|
||||||
*/
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@ToString
|
||||||
public class UserAccount {
|
public class UserAccount {
|
||||||
private String userId;
|
private String userId;
|
||||||
private String userName;
|
private String userName;
|
||||||
private String additionalInfo;
|
private String additionalInfo;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*/
|
|
||||||
public UserAccount(String userId, String userName, String additionalInfo) {
|
|
||||||
this.userId = userId;
|
|
||||||
this.userName = userName;
|
|
||||||
this.additionalInfo = additionalInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserId() {
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(String userId) {
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserName() {
|
|
||||||
return userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserName(String userName) {
|
|
||||||
this.userName = userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAdditionalInfo() {
|
|
||||||
return additionalInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdditionalInfo(String additionalInfo) {
|
|
||||||
this.additionalInfo = additionalInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return userId + ", " + userName + ", " + additionalInfo;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,9 @@ public abstract class Task {
|
|||||||
public abstract void execute();
|
public abstract void execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public final class SimpleTask extends Task {
|
public final class SimpleTask extends Task {
|
||||||
|
|
||||||
private static final Logger LOGGER = getLogger(SimpleTask.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
LOGGER.info("Perform some important activity and after call the callback method.");
|
LOGGER.info("Perform some important activity and after call the callback method.");
|
||||||
|
@ -23,19 +23,16 @@
|
|||||||
|
|
||||||
package com.iluwatar.callback;
|
package com.iluwatar.callback;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback pattern is more native for functional languages where functions are treated as
|
* Callback pattern is more native for functional languages where functions are treated as
|
||||||
* first-class citizens. Prior to Java 8 callbacks can be simulated using simple (alike command)
|
* first-class citizens. Prior to Java 8 callbacks can be simulated using simple (alike command)
|
||||||
* interfaces.
|
* interfaces.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public final class App {
|
public final class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = getLogger(App.class);
|
|
||||||
|
|
||||||
private App() {
|
private App() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,20 +23,16 @@
|
|||||||
|
|
||||||
package com.iluwatar.callback;
|
package com.iluwatar.callback;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of task that need to be executed.
|
* Implementation of task that need to be executed.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public final class SimpleTask extends Task {
|
public final class SimpleTask extends Task {
|
||||||
|
|
||||||
private static final Logger LOGGER = getLogger(SimpleTask.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
LOGGER.info("Perform some important activity and after call the"
|
LOGGER.info("Perform some important activity and after call the callback method.");
|
||||||
+ " callback method.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class CallbackTest {
|
|||||||
private Integer callingCount = 0;
|
private Integer callingCount = 0;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
void test() {
|
||||||
Callback callback = () -> callingCount++;
|
Callback callback = () -> callingCount++;
|
||||||
|
|
||||||
var task = new SimpleTask();
|
var task = new SimpleTask();
|
||||||
|
@ -68,8 +68,8 @@ public enum RequestType {
|
|||||||
Then the request handler hierarchy
|
Then the request handler hierarchy
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public abstract class RequestHandler {
|
public abstract class RequestHandler {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
|
|
||||||
private final RequestHandler next;
|
private final RequestHandler next;
|
||||||
|
|
||||||
public RequestHandler(RequestHandler next) {
|
public RequestHandler(RequestHandler next) {
|
||||||
|
@ -47,6 +47,5 @@ public class App {
|
|||||||
king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
|
king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
|
||||||
king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
|
king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
|
||||||
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));
|
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,22 +23,18 @@
|
|||||||
|
|
||||||
package com.iluwatar.chain;
|
package com.iluwatar.chain;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.AllArgsConstructor;
|
||||||
import org.slf4j.LoggerFactory;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RequestHandler.
|
* RequestHandler.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
public abstract class RequestHandler {
|
public abstract class RequestHandler {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
|
|
||||||
|
|
||||||
private final RequestHandler next;
|
private final RequestHandler next;
|
||||||
|
|
||||||
public RequestHandler(RequestHandler next) {
|
|
||||||
this.next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request handler.
|
* Request handler.
|
||||||
*/
|
*/
|
||||||
|
@ -28,6 +28,8 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public enum RequestType {
|
public enum RequestType {
|
||||||
|
|
||||||
DEFEND_CASTLE, TORTURE_PRISONER, COLLECT_TAX
|
DEFEND_CASTLE,
|
||||||
|
TORTURE_PRISONER,
|
||||||
|
COLLECT_TAX
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
*
|
*
|
||||||
* @author Jeroen Meulemeester
|
* @author Jeroen Meulemeester
|
||||||
*/
|
*/
|
||||||
public class OrcKingTest {
|
class OrcKingTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All possible requests
|
* All possible requests
|
||||||
@ -45,7 +45,7 @@ public class OrcKingTest {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMakeRequest() {
|
void testMakeRequest() {
|
||||||
final var king = new OrcKing();
|
final var king = new OrcKing();
|
||||||
|
|
||||||
REQUESTS.forEach(request -> {
|
REQUESTS.forEach(request -> {
|
||||||
|
@ -54,6 +54,7 @@ The service architecture is as follows:
|
|||||||
In terms of code, the end user application is:
|
In terms of code, the end user application is:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.circuitbreaker;
|
package com.iluwatar.circuitbreaker;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@ -55,10 +54,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* recovers, it goes back to the closed state and the cycle continues.
|
* recovers, it goes back to the closed state and the cycle continues.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
|
@ -35,7 +35,7 @@ public class DefaultCircuitBreakerTest {
|
|||||||
|
|
||||||
//long timeout, int failureThreshold, long retryTimePeriod
|
//long timeout, int failureThreshold, long retryTimePeriod
|
||||||
@Test
|
@Test
|
||||||
public void testEvaluateState() {
|
void testEvaluateState() {
|
||||||
var circuitBreaker = new DefaultCircuitBreaker(null, 1, 1, 100);
|
var circuitBreaker = new DefaultCircuitBreaker(null, 1, 1, 100);
|
||||||
//Right now, failureCount<failureThreshold, so state should be closed
|
//Right now, failureCount<failureThreshold, so state should be closed
|
||||||
assertEquals(circuitBreaker.getState(), "CLOSED");
|
assertEquals(circuitBreaker.getState(), "CLOSED");
|
||||||
@ -57,7 +57,7 @@ public class DefaultCircuitBreakerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetStateForBypass() {
|
void testSetStateForBypass() {
|
||||||
var circuitBreaker = new DefaultCircuitBreaker(null, 1, 1, 2000 * 1000 * 1000);
|
var circuitBreaker = new DefaultCircuitBreaker(null, 1, 1, 2000 * 1000 * 1000);
|
||||||
//Right now, failureCount<failureThreshold, so state should be closed
|
//Right now, failureCount<failureThreshold, so state should be closed
|
||||||
//Bypass it and set it to open
|
//Bypass it and set it to open
|
||||||
@ -66,7 +66,7 @@ public class DefaultCircuitBreakerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testApiResponses() throws RemoteServiceException {
|
void testApiResponses() throws RemoteServiceException {
|
||||||
RemoteService mockService = new RemoteService() {
|
RemoteService mockService = new RemoteService() {
|
||||||
@Override
|
@Override
|
||||||
public String call() throws RemoteServiceException {
|
public String call() throws RemoteServiceException {
|
||||||
@ -79,6 +79,5 @@ public class DefaultCircuitBreakerTest {
|
|||||||
var serviceStartTime = System.nanoTime() - 60 * 1000 * 1000 * 1000;
|
var serviceStartTime = System.nanoTime() - 60 * 1000 * 1000 * 1000;
|
||||||
var response = circuitBreaker.attemptRequest();
|
var response = circuitBreaker.attemptRequest();
|
||||||
assertEquals(response, "Remote Success");
|
assertEquals(response, "Remote Success");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
/**
|
/**
|
||||||
* Monitoring Service test
|
* Monitoring Service test
|
||||||
*/
|
*/
|
||||||
public class DelayedRemoteServiceTest {
|
class DelayedRemoteServiceTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing immediate response of the delayed service.
|
* Testing immediate response of the delayed service.
|
||||||
@ -39,7 +39,7 @@ public class DelayedRemoteServiceTest {
|
|||||||
* @throws RemoteServiceException
|
* @throws RemoteServiceException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultConstructor() throws RemoteServiceException {
|
void testDefaultConstructor() throws RemoteServiceException {
|
||||||
Assertions.assertThrows(RemoteServiceException.class, () -> {
|
Assertions.assertThrows(RemoteServiceException.class, () -> {
|
||||||
var obj = new DelayedRemoteService();
|
var obj = new DelayedRemoteService();
|
||||||
obj.call();
|
obj.call();
|
||||||
|
@ -30,18 +30,18 @@ import org.junit.jupiter.api.Test;
|
|||||||
/**
|
/**
|
||||||
* Monitoring Service test
|
* Monitoring Service test
|
||||||
*/
|
*/
|
||||||
public class MonitoringServiceTest {
|
class MonitoringServiceTest {
|
||||||
|
|
||||||
//long timeout, int failureThreshold, long retryTimePeriod
|
//long timeout, int failureThreshold, long retryTimePeriod
|
||||||
@Test
|
@Test
|
||||||
public void testLocalResponse() {
|
void testLocalResponse() {
|
||||||
var monitoringService = new MonitoringService(null,null);
|
var monitoringService = new MonitoringService(null,null);
|
||||||
var response = monitoringService.localResourceResponse();
|
var response = monitoringService.localResourceResponse();
|
||||||
assertEquals(response, "Local Service is working");
|
assertEquals(response, "Local Service is working");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDelayedRemoteResponseSuccess() {
|
void testDelayedRemoteResponseSuccess() {
|
||||||
var delayedService = new DelayedRemoteService(System.nanoTime()-2*1000*1000*1000, 2);
|
var delayedService = new DelayedRemoteService(System.nanoTime()-2*1000*1000*1000, 2);
|
||||||
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
||||||
1,
|
1,
|
||||||
@ -54,7 +54,7 @@ public class MonitoringServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDelayedRemoteResponseFailure() {
|
void testDelayedRemoteResponseFailure() {
|
||||||
var delayedService = new DelayedRemoteService(System.nanoTime(), 2);
|
var delayedService = new DelayedRemoteService(System.nanoTime(), 2);
|
||||||
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
||||||
1,
|
1,
|
||||||
@ -66,7 +66,7 @@ public class MonitoringServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQuickRemoteServiceResponse() {
|
void testQuickRemoteServiceResponse() {
|
||||||
var delayedService = new QuickRemoteService();
|
var delayedService = new QuickRemoteService();
|
||||||
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
||||||
1,
|
1,
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
package com.iluwatar.collectionpipeline;
|
package com.iluwatar.collectionpipeline;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In imperative-style programming, it is common to use for and while loops for most kinds of data
|
* In imperative-style programming, it is common to use for and while loops for most kinds of data
|
||||||
@ -35,10 +34,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* create sophisticated programs where data flow from upstream to downstream and is passed through a
|
* create sophisticated programs where data flow from upstream to downstream and is passed through a
|
||||||
* series of transformations.
|
* series of transformations.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
|
@ -23,86 +23,20 @@
|
|||||||
|
|
||||||
package com.iluwatar.collectionpipeline;
|
package com.iluwatar.collectionpipeline;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Car class that has the properties of make, model, year and category.
|
* A Car class that has the properties of make, model, year and category.
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class Car {
|
public class Car {
|
||||||
private final String make;
|
private final String make;
|
||||||
private final String model;
|
private final String model;
|
||||||
private final int year;
|
private final int year;
|
||||||
private final Category category;
|
private final Category category;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor to create an instance of car.
|
|
||||||
*
|
|
||||||
* @param make the make of the car
|
|
||||||
* @param model the model of the car
|
|
||||||
* @param yearOfMake the year of built of the car
|
|
||||||
* @param category the {@link Category} of the car
|
|
||||||
*/
|
|
||||||
public Car(String make, String model, int yearOfMake, Category category) {
|
|
||||||
this.make = make;
|
|
||||||
this.model = model;
|
|
||||||
this.year = yearOfMake;
|
|
||||||
this.category = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((category == null) ? 0 : category.hashCode());
|
|
||||||
result = prime * result + ((make == null) ? 0 : make.hashCode());
|
|
||||||
result = prime * result + ((model == null) ? 0 : model.hashCode());
|
|
||||||
result = prime * result + year;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Car other = (Car) obj;
|
|
||||||
if (category != other.category) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (make == null) {
|
|
||||||
if (other.make != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!make.equals(other.make)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (model == null) {
|
|
||||||
if (other.model != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!model.equals(other.model)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return year == other.year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMake() {
|
|
||||||
return make;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getModel() {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getYear() {
|
|
||||||
return year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Category getCategory() {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -27,5 +27,7 @@ package com.iluwatar.collectionpipeline;
|
|||||||
* Enum for the category of car.
|
* Enum for the category of car.
|
||||||
*/
|
*/
|
||||||
public enum Category {
|
public enum Category {
|
||||||
JEEP, SEDAN, CONVERTIBLE
|
JEEP,
|
||||||
|
SEDAN,
|
||||||
|
CONVERTIBLE
|
||||||
}
|
}
|
||||||
|
@ -24,23 +24,16 @@
|
|||||||
package com.iluwatar.collectionpipeline;
|
package com.iluwatar.collectionpipeline;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Person class that has the list of cars that the person owns and use.
|
* A Person class that has the list of cars that the person owns and use.
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class Person {
|
public class Person {
|
||||||
|
|
||||||
private final List<Car> cars;
|
private final List<Car> cars;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor to create an instance of person.
|
|
||||||
*
|
|
||||||
* @param cars the list of cars owned
|
|
||||||
*/
|
|
||||||
public Person(List<Car> cars) {
|
|
||||||
this.cars = cars;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Car> getCars() {
|
|
||||||
return cars;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -27,32 +27,31 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that Collection Pipeline methods work as expected.
|
* Tests that Collection Pipeline methods work as expected.
|
||||||
*/
|
*/
|
||||||
public class AppTest {
|
@Slf4j
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AppTest.class);
|
class AppTest {
|
||||||
|
|
||||||
private final List<Car> cars = CarFactory.createCars();
|
private final List<Car> cars = CarFactory.createCars();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetModelsAfter2000UsingFor() {
|
void testGetModelsAfter2000UsingFor() {
|
||||||
var models = ImperativeProgramming.getModelsAfter2000(cars);
|
var models = ImperativeProgramming.getModelsAfter2000(cars);
|
||||||
assertEquals(List.of("Avenger", "Wrangler", "Focus", "Cascada"), models);
|
assertEquals(List.of("Avenger", "Wrangler", "Focus", "Cascada"), models);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetModelsAfter2000UsingPipeline() {
|
void testGetModelsAfter2000UsingPipeline() {
|
||||||
var models = FunctionalProgramming.getModelsAfter2000(cars);
|
var models = FunctionalProgramming.getModelsAfter2000(cars);
|
||||||
assertEquals(List.of("Avenger", "Wrangler", "Focus", "Cascada"), models);
|
assertEquals(List.of("Avenger", "Wrangler", "Focus", "Cascada"), models);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetGroupingOfCarsByCategory() {
|
void testGetGroupingOfCarsByCategory() {
|
||||||
var modelsExpected = Map.of(
|
var modelsExpected = Map.of(
|
||||||
Category.CONVERTIBLE, List.of(
|
Category.CONVERTIBLE, List.of(
|
||||||
new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
|
new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
|
||||||
@ -74,7 +73,7 @@ public class AppTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetSedanCarsOwnedSortedByDate() {
|
void testGetSedanCarsOwnedSortedByDate() {
|
||||||
var john = new Person(cars);
|
var john = new Person(cars);
|
||||||
var modelsExpected = List.of(
|
var modelsExpected = List.of(
|
||||||
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
|
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.combinator;
|
package com.iluwatar.combinator;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,13 +40,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* {@link Finder#and(Finder)}
|
* {@link Finder#and(Finder)}
|
||||||
* Using them the became possible to get more complex functions {@link Finders}
|
* Using them the became possible to get more complex functions {@link Finders}
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class CombinatorApp {
|
public class CombinatorApp {
|
||||||
|
|
||||||
/**
|
|
||||||
* Logger.
|
|
||||||
*/
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(CombinatorApp.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main.
|
* main.
|
||||||
* @param args args
|
* @param args args
|
||||||
@ -63,14 +58,13 @@ public class CombinatorApp {
|
|||||||
res = finder.find(text());
|
res = finder.find(text());
|
||||||
LOGGER.info("the result of specialized(and) query[{}] is {}", queriesAnd, res);
|
LOGGER.info("the result of specialized(and) query[{}] is {}", queriesAnd, res);
|
||||||
|
|
||||||
finder = Finders.advancedFinder("it was","kingdom","sea");
|
finder = Finders.advancedFinder("it was", "kingdom", "sea");
|
||||||
res = finder.find(text());
|
res = finder.find(text());
|
||||||
LOGGER.info("the result of advanced query is {}", res);
|
LOGGER.info("the result of advanced query is {}", res);
|
||||||
|
|
||||||
res = Finders.filteredFinder(" was ", "many", "child").find(text());
|
res = Finders.filteredFinder(" was ", "many", "child").find(text());
|
||||||
LOGGER.info("the result of filtered query is {}", res);
|
LOGGER.info("the result of filtered query is {}", res);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String text() {
|
private static String text() {
|
||||||
|
@ -31,11 +31,10 @@ class CombinatorAppTest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Issue: Add at least one assertion to this test case.
|
* Issue: Add at least one assertion to this test case.
|
||||||
*
|
* <p>
|
||||||
* Solution: Inserted assertion to check whether the execution of the main method in {@link CombinatorApp#main(String[])}
|
* Solution: Inserted assertion to check whether the execution of the main method in {@link CombinatorApp#main(String[])}
|
||||||
* throws an exception.
|
* throws an exception.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldExecuteApplicationWithoutException() {
|
void shouldExecuteApplicationWithoutException() {
|
||||||
assertDoesNotThrow(() -> CombinatorApp.main(new String[]{}));
|
assertDoesNotThrow(() -> CombinatorApp.main(new String[]{}));
|
||||||
|
@ -35,7 +35,6 @@ class FinderTest {
|
|||||||
|
|
||||||
var result = Finder.contains("second").find(example);
|
var result = Finder.contains("second").find(example);
|
||||||
assertEquals(1, result.size());
|
assertEquals(1, result.size());
|
||||||
assertEquals("the second one ", result.get(0));
|
assertEquals( "the second one ", result.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,36 +35,36 @@ class FindersTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void advancedFinderTest() {
|
void advancedFinderTest() {
|
||||||
var res = advancedFinder("it was","kingdom","sea").find(text());
|
var res = advancedFinder("it was", "kingdom", "sea").find(text());
|
||||||
assertEquals(1, res.size());
|
assertEquals(1, res.size());
|
||||||
assertEquals("It was many and many a year ago,", res.get(0));
|
assertEquals( "It was many and many a year ago,", res.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void filteredFinderTest() {
|
void filteredFinderTest() {
|
||||||
var res = filteredFinder(" was ", "many", "child").find(text());
|
var res = filteredFinder(" was ", "many", "child").find(text());
|
||||||
assertEquals(1, res.size());
|
assertEquals(1, res.size());
|
||||||
assertEquals("But we loved with a love that was more than love-", res.get(0));
|
assertEquals( "But we loved with a love that was more than love-", res.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void specializedFinderTest() {
|
void specializedFinderTest() {
|
||||||
var res = specializedFinder("love","heaven").find(text());
|
var res = specializedFinder("love", "heaven").find(text());
|
||||||
assertEquals(1, res.size());
|
assertEquals(1, res.size());
|
||||||
assertEquals("With a love that the winged seraphs of heaven", res.get(0));
|
assertEquals( "With a love that the winged seraphs of heaven", res.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void expandedFinderTest() {
|
void expandedFinderTest() {
|
||||||
var res = expandedFinder("It was","kingdom").find(text());
|
var res = expandedFinder("It was", "kingdom").find(text());
|
||||||
assertEquals(3, res.size());
|
assertEquals(3, res.size());
|
||||||
assertEquals("It was many and many a year ago,", res.get(0));
|
assertEquals( "It was many and many a year ago,", res.get(0));
|
||||||
assertEquals("In a kingdom by the sea,", res.get(1));
|
assertEquals( "In a kingdom by the sea,", res.get(1));
|
||||||
assertEquals("In this kingdom by the sea;", res.get(2));
|
assertEquals( "In this kingdom by the sea;", res.get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String text(){
|
private String text() {
|
||||||
return
|
return
|
||||||
"It was many and many a year ago,\n"
|
"It was many and many a year ago,\n"
|
||||||
+ "In a kingdom by the sea,\n"
|
+ "In a kingdom by the sea,\n"
|
||||||
|
@ -39,6 +39,7 @@ Wikipedia says
|
|||||||
Here's the sample code with wizard and goblin. Let's start from the `Wizard` class.
|
Here's the sample code with wizard and goblin. Let's start from the `Wizard` class.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public class Wizard {
|
public class Wizard {
|
||||||
|
|
||||||
private final Deque<Command> undoStack = new LinkedList<>();
|
private final Deque<Command> undoStack = new LinkedList<>();
|
||||||
@ -77,10 +78,9 @@ public class Wizard {
|
|||||||
Next, we have the goblin who's the target of the spells.
|
Next, we have the goblin who's the target of the spells.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@Slf4j
|
||||||
public abstract class Target {
|
public abstract class Target {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Target.class);
|
|
||||||
|
|
||||||
private Size size;
|
private Size size;
|
||||||
|
|
||||||
private Visibility visibility;
|
private Visibility visibility;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user