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:
committed by
Ilkka Seppälä
parent
310ae50248
commit
cd2a2e7711
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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."
|
||||
|
@ -32,6 +32,7 @@ public interface OrchestrationChapter<K> {
|
||||
|
||||
/**
|
||||
* method get name.
|
||||
*
|
||||
* @return service name.
|
||||
*/
|
||||
String getName();
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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))
|
||||
|
@ -24,8 +24,6 @@ package com.iluwatar.saga.orchestration;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* empty test
|
||||
*/
|
||||
|
@ -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> {
|
||||
|
Reference in New Issue
Block a user