Java 11 migrate all remaining s (#1120)

* Moves saga to Java 11

* Moves semaphore to Java 11

* Moves servant to Java 11

* Moves serverless to Java 11

* Moves service-layer to Java 11

* Moves service-locator to Java 11

* Moves sharding to Java 11

* Moves singleton to Java 11

* Moves spatial-partition to Java 11

* Moves specification to Java 11

* Moves state to Java 11

* Moves step-builder to Java 11

* Moves strategy to Java 11

* Moves subclass-sandbox to Java 11

* Fixes checkstyle issues
This commit is contained in:
Anurag Agarwal
2020-01-04 22:06:08 +05:30
committed by Ilkka Seppälä
parent 310ae50248
commit cd2a2e7711
98 changed files with 718 additions and 855 deletions

View File

@ -25,9 +25,9 @@ package com.iluwatar.saga.choreography;
/**
* ChoreographyChapter is an interface representing a contract for an external service.
* In that case, a service needs to make a decision what to do further
* hence the server needs to get all context representing {@link Saga}
* ChoreographyChapter is an interface representing a contract for an external service. In that
* case, a service needs to make a decision what to do further hence the server needs to get all
* context representing {@link Saga}
*/
public interface ChoreographyChapter {
@ -41,6 +41,7 @@ public interface ChoreographyChapter {
/**
* get name method.
*
* @return service name.
*/
String getName();

View File

@ -28,9 +28,8 @@ import java.util.Arrays;
import java.util.List;
/**
* Saga representation.
* Saga consists of chapters.
* Every ChoreographyChapter is executed a certain service.
* Saga representation. Saga consists of chapters. Every ChoreographyChapter is executed a certain
* service.
*/
public class Saga {
@ -61,6 +60,7 @@ public class Saga {
/**
* add chapter to saga.
*
* @param name chapter name
* @return this
*/
@ -71,6 +71,7 @@ public class Saga {
/**
* set value to last chapter.
*
* @param value invalue
* @return this
*/
@ -84,6 +85,7 @@ public class Saga {
/**
* get value from current chapter.
*
* @return value
*/
public Object getCurrentValue() {
@ -92,6 +94,7 @@ public class Saga {
/**
* set value to current chapter.
*
* @param value to set
*/
public void setCurrentValue(Object value) {
@ -100,6 +103,7 @@ public class Saga {
/**
* set status for current chapter.
*
* @param result to set
*/
public void setCurrentStatus(ChapterResult result) {
@ -145,8 +149,8 @@ public class Saga {
}
/**
* Class presents a chapter status and incoming
* parameters(incoming parameter transforms to outcoming parameter).
* Class presents a chapter status and incoming parameters(incoming parameter transforms to
* outcoming parameter).
*/
public static class Chapter {
private String name;
@ -173,6 +177,7 @@ public class Saga {
/**
* set result.
*
* @param result {@link ChapterResult}
*/
public void setResult(ChapterResult result) {
@ -181,6 +186,7 @@ public class Saga {
/**
* the result for chapter is good.
*
* @return true if is good otherwise bad
*/
public boolean isSuccess() {

View File

@ -27,22 +27,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This pattern is used in distributed services to perform a group of operations atomically.
* This is an analog of transaction in a database but in terms
* of microservices architecture this is executed
* in a distributed environment
* This pattern is used in distributed services to perform a group of operations atomically. This is
* an analog of transaction in a database but in terms of microservices architecture this is
* executed in a distributed environment
*
* <p>A saga is a sequence of local transactions in a certain context.
* If one transaction fails for some reason,
* the saga executes compensating transactions(rollbacks)
* If one transaction fails for some reason, the saga executes compensating transactions(rollbacks)
* to undo the impact of the preceding transactions.
*
* <p>In this approach, there are no mediators or orchestrators services.
* All chapters are handled and moved by services manually.
*
* <p>The major difference with choreography saga is an ability to handle crashed services
* (otherwise in choreography services very hard to prevent a saga
* if one of them has been crashed)
* (otherwise in choreography services very hard to prevent a saga if one of them has been crashed)
*
* @see com.iluwatar.saga.choreography.Saga
* @see Service
@ -54,10 +51,10 @@ public class SagaApplication {
* main method.
*/
public static void main(String[] args) {
ServiceDiscoveryService sd = serviceDiscovery();
ChoreographyChapter service = sd.findAny();
Saga goodOrderSaga = service.execute(newSaga("good_order"));
Saga badOrderSaga = service.execute(newSaga("bad_order"));
var sd = serviceDiscovery();
var service = sd.findAny();
var goodOrderSaga = service.execute(newSaga("good_order"));
var badOrderSaga = service.execute(newSaga("bad_order"));
LOGGER.info("orders: goodOrder is {}, badOrder is {}",
goodOrderSaga.getResult(), badOrderSaga.getResult());
@ -74,7 +71,7 @@ public class SagaApplication {
}
private static ServiceDiscoveryService serviceDiscovery() {
ServiceDiscoveryService sd = new ServiceDiscoveryService();
var sd = new ServiceDiscoveryService();
return sd
.discover(new OrderService(sd))
.discover(new FlyBookingService(sd))

View File

@ -29,8 +29,8 @@ import org.slf4j.LoggerFactory;
/**
* Common abstraction class representing services.
* implementing a general contract @see {@link ChoreographyChapter}
* Common abstraction class representing services. implementing a general contract @see {@link
* ChoreographyChapter}
*/
public abstract class Service implements ChoreographyChapter {
protected static final Logger LOGGER = LoggerFactory.getLogger(Service.class);
@ -43,9 +43,9 @@ public abstract class Service implements ChoreographyChapter {
@Override
public Saga execute(Saga saga) {
Saga nextSaga = saga;
var nextSaga = saga;
Object nextVal;
String chapterName = saga.getCurrent().getName();
var chapterName = saga.getCurrent().getName();
if (chapterName.equals(getName())) {
if (saga.isForward()) {
nextSaga = process(saga);
@ -67,7 +67,7 @@ public abstract class Service implements ChoreographyChapter {
nextSaga.setCurrentValue(nextVal);
}
Saga finalNextSaga = nextSaga;
var finalNextSaga = nextSaga;
return sd.find(chapterName).map(ch -> ch.execute(finalNextSaga))
.orElseThrow(serviceNotFoundException(chapterName));
@ -80,7 +80,7 @@ public abstract class Service implements ChoreographyChapter {
@Override
public Saga process(Saga saga) {
Object inValue = saga.getCurrentValue();
var inValue = saga.getCurrentValue();
LOGGER.info("The chapter '{}' has been started. "
+ "The data {} has been stored or calculated successfully",
getName(), inValue);
@ -91,7 +91,7 @@ public abstract class Service implements ChoreographyChapter {
@Override
public Saga rollback(Saga saga) {
Object inValue = saga.getCurrentValue();
var inValue = saga.getCurrentValue();
LOGGER.info("The Rollback for a chapter '{}' has been started. "
+ "The data {} has been rollbacked successfully",
getName(), inValue);

View File

@ -39,7 +39,7 @@ public class WithdrawMoneyService extends Service {
@Override
public Saga process(Saga saga) {
Object inValue = saga.getCurrentValue();
var inValue = saga.getCurrentValue();
if (inValue.equals("bad_order")) {
LOGGER.info("The chapter '{}' has been started. But the exception has been raised."

View File

@ -32,6 +32,7 @@ public interface OrchestrationChapter<K> {
/**
* method get name.
*
* @return service name.
*/
String getName();

View File

@ -27,9 +27,8 @@ import java.util.ArrayList;
import java.util.List;
/**
* Saga representation.
* Saga consists of chapters.
* Every ChoreographyChapter is executed by a certain service.
* Saga representation. Saga consists of chapters. Every ChoreographyChapter is executed by a
* certain service.
*/
public class Saga {

View File

@ -27,23 +27,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This pattern is used in distributed services to perform
* a group of operations atomically.
* This is an analog of transaction in a database but in terms
* of microservices architecture this is executed
* in a distributed environment
* This pattern is used in distributed services to perform a group of operations atomically. This is
* an analog of transaction in a database but in terms of microservices architecture this is
* executed in a distributed environment
*
* <p>A saga is a sequence of local transactions in a certain context.
* If one transaction fails for some reason,
* the saga executes compensating transactions(rollbacks)
* If one transaction fails for some reason, the saga executes compensating transactions(rollbacks)
* to undo the impact of the preceding transactions.
*
* <p>In this approach, there is an orchestrator @see {@link SagaOrchestrator}
* that manages all the transactions and directs
* the participant services to execute local transactions based on events.
* The major difference with choreography saga is an ability to handle crashed services
* (otherwise in choreography services very hard to prevent a saga
* if one of them has been crashed)
* that manages all the transactions and directs the participant services to execute local
* transactions based on events. The major difference with choreography saga is an ability to handle
* crashed services (otherwise in choreography services very hard to prevent a saga if one of them
* has been crashed)
*
* @see Saga
* @see SagaOrchestrator
@ -56,7 +52,7 @@ public class SagaApplication {
* method to show common saga logic.
*/
public static void main(String[] args) {
SagaOrchestrator sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
var sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
Saga.Result goodOrder = sagaOrchestrator.execute("good_order");
Saga.Result badOrder = sagaOrchestrator.execute("bad_order");
@ -77,11 +73,10 @@ public class SagaApplication {
}
private static ServiceDiscoveryService serviceDiscovery() {
return
new ServiceDiscoveryService()
.discover(new OrderService())
.discover(new FlyBookingService())
.discover(new HotelBookingService())
.discover(new WithdrawMoneyService());
return new ServiceDiscoveryService()
.discover(new OrderService())
.discover(new FlyBookingService())
.discover(new HotelBookingService())
.discover(new WithdrawMoneyService());
}
}

View File

@ -23,18 +23,18 @@
package com.iluwatar.saga.orchestration;
import static com.iluwatar.saga.orchestration.Saga.Result;
import static com.iluwatar.saga.orchestration.Saga.Result.CRASHED;
import static com.iluwatar.saga.orchestration.Saga.Result.FINISHED;
import static com.iluwatar.saga.orchestration.Saga.Result.ROLLBACK;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The orchestrator that manages all the transactions and directs
* the participant services to execute local transactions based on events.
* The orchestrator that manages all the transactions and directs the participant services to
* execute local transactions based on events.
*/
public class SagaOrchestrator {
private static final Logger LOGGER = LoggerFactory.getLogger(SagaOrchestrator.class);
@ -45,8 +45,9 @@ public class SagaOrchestrator {
/**
* Create a new service to orchetrate sagas.
*
* @param saga saga to process
* @param sd service discovery @see {@link ServiceDiscoveryService}
* @param sd service discovery @see {@link ServiceDiscoveryService}
*/
public SagaOrchestrator(Saga saga, ServiceDiscoveryService sd) {
this.saga = saga;
@ -59,30 +60,30 @@ public class SagaOrchestrator {
*
* @param value incoming value
* @param <K> type for incoming value
* @return result @see {@link Saga.Result}
* @return result @see {@link Result}
*/
@SuppressWarnings("unchecked")
public <K> Saga.Result execute(K value) {
public <K> Result execute(K value) {
state.cleanUp();
LOGGER.info(" The new saga is about to start");
Saga.Result result = FINISHED;
var result = FINISHED;
K tempVal = value;
while (true) {
int next = state.current();
Saga.Chapter ch = saga.get(next);
Optional<OrchestrationChapter> srvOpt = sd.find(ch.name);
var next = state.current();
var ch = saga.get(next);
var srvOpt = sd.find(ch.name);
if (!srvOpt.isPresent()) {
if (srvOpt.isEmpty()) {
state.directionToBack();
state.back();
continue;
}
OrchestrationChapter srv = srvOpt.get();
var srv = srvOpt.get();
if (state.isForward()) {
ChapterResult processRes = srv.process(tempVal);
var processRes = srv.process(tempVal);
if (processRes.isSuccess()) {
next = state.forward();
tempVal = (K) processRes.getValue();
@ -90,7 +91,7 @@ public class SagaOrchestrator {
state.directionToBack();
}
} else {
ChapterResult rlRes = srv.rollback(tempVal);
var rlRes = srv.rollback(tempVal);
if (rlRes.isSuccess()) {
next = state.back();
tempVal = (K) rlRes.getValue();

View File

@ -27,8 +27,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Common abstraction class representing services.
* implementing a general contract @see {@link OrchestrationChapter}
* Common abstraction class representing services. implementing a general contract @see {@link
* OrchestrationChapter}
*
* @param <K> type of incoming param
*/

View File

@ -33,10 +33,10 @@ public class SagaChoreographyTest {
@Test
public void executeTest() {
ServiceDiscoveryService sd = serviceDiscovery();
ChoreographyChapter service = sd.findAny();
Saga badOrderSaga = service.execute(newSaga("bad_order"));
Saga goodOrderSaga = service.execute(newSaga("good_order"));
var sd = serviceDiscovery();
var service = sd.findAny();
var badOrderSaga = service.execute(newSaga("bad_order"));
var goodOrderSaga = service.execute(newSaga("good_order"));
Assert.assertEquals(badOrderSaga.getResult(), Saga.SagaResult.ROLLBACKED);
Assert.assertEquals(goodOrderSaga.getResult(), Saga.SagaResult.FINISHED);
@ -52,7 +52,7 @@ public class SagaChoreographyTest {
}
private static ServiceDiscoveryService serviceDiscovery() {
ServiceDiscoveryService sd = new ServiceDiscoveryService();
var sd = new ServiceDiscoveryService();
return sd
.discover(new OrderService(sd))
.discover(new FlyBookingService(sd))

View File

@ -24,8 +24,6 @@ package com.iluwatar.saga.orchestration;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* empty test
*/

View File

@ -22,11 +22,12 @@
*/
package com.iluwatar.saga.orchestration;
import org.junit.Assert;
import org.junit.Test;
import static com.iluwatar.saga.orchestration.Saga.Result;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* test to test orchestration logic
@ -37,17 +38,16 @@ public class SagaOrchestratorInternallyTest {
@Test
public void executeTest() {
SagaOrchestrator sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
Saga.Result result = sagaOrchestrator.execute(1);
Assert.assertEquals(result, Saga.Result.ROLLBACK);
var sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
var result = sagaOrchestrator.execute(1);
Assert.assertEquals(result, Result.ROLLBACK);
Assert.assertArrayEquals(
records.toArray(new String[]{}),
new String[]{"+1", "+2", "+3", "+4", "-4", "-3", "-2", "-1"});
}
private static Saga newSaga() {
return Saga
.create()
return Saga.create()
.chapter("1")
.chapter("2")
.chapter("3")
@ -55,12 +55,11 @@ public class SagaOrchestratorInternallyTest {
}
private ServiceDiscoveryService serviceDiscovery() {
return
new ServiceDiscoveryService()
.discover(new Service1())
.discover(new Service2())
.discover(new Service3())
.discover(new Service4());
return new ServiceDiscoveryService()
.discover(new Service1())
.discover(new Service2())
.discover(new Service3())
.discover(new Service4());
}
class Service1 extends Service<Integer> {