add choreogr

This commit is contained in:
Besok 2019-11-09 17:42:49 +00:00
parent fbcfeb072a
commit 09b4663b9a
18 changed files with 719 additions and 21 deletions

View File

@ -22,13 +22,20 @@
*/
package com.iluwatar.saga.choreography;
import com.iluwatar.saga.orchestration.ChapterResult;
/**
* Chapter is an interface representing a contract for an external service.
* @param <K> is type for passing params
*/
public interface Chapter<K> {
* 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 Chapter {
/**
* In that case, every method is responsible to make a decision on what to do then
* @param saga incoming saga
* @return saga result
*/
Saga execute(Saga saga);
/**
* @return service name.
@ -37,17 +44,17 @@ public interface Chapter<K> {
/**
* The operation executed in general case.
* @param value incoming value
* @return result {@link ChapterResult}
* @param saga incoming saga
* @return result {@link Saga}
*/
ChapterResult<K> process(K value);
Saga process(Saga saga);
/**
* The operation executed in rollback case.
* @param value incoming value
* @return result {@link ChapterResult}
* @param saga incoming saga
* @return result {@link Saga}
*/
ChapterResult<K> rollback(K value);
Saga rollback(Saga saga);
}

View File

@ -0,0 +1,38 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
/**
* Class representing a service to book a fly
*/
public class FlyBookingService extends Service {
public FlyBookingService(ServiceDiscoveryService service) {
super(service);
}
@Override
public String getName() {
return "booking a Fly";
}
}

View File

@ -0,0 +1,40 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
/**
* Class representing a service to book a hotel
*/
public class HotelBookingService extends Service {
public HotelBookingService(ServiceDiscoveryService service) {
super(service);
}
@Override
public String getName() {
return "booking a Hotel";
}
}

View File

@ -0,0 +1,39 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
/**
* Class representing a service to init a new order.
*/
public class OrderService extends Service{
public OrderService(ServiceDiscoveryService service) {
super(service);
}
@Override
public String getName() {
return "init an order";
}
}

View File

@ -22,6 +22,10 @@
*/
package com.iluwatar.saga.choreography;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Saga representation.
* Saga consists of chapters.
@ -29,6 +33,127 @@ package com.iluwatar.saga.choreography;
*/
public class Saga {
private List<Chapter> chapters;
private int pos;
private boolean forward;
private boolean finished;
public static Saga create() {
return new Saga();
}
public SagaResult getResult() {
return !finished ?
SagaResult.PROGRESS :
forward ?
SagaResult.FINISHED :
SagaResult.ROLLBACKED;
}
public Saga chapter(String name) {
this.chapters.add(new Chapter(name));
return this;
}
public Saga setInValue(Object value){
if(chapters.isEmpty()){
return this;
}
chapters.get(chapters.size()-1).setInValue(value);
return this;
}
public Object getCurrentValue(){
return chapters.get(pos).getInValue();
}
public void setCurrentValue(Object value){
chapters.get(pos).setInValue(value);
}
public void setCurrentStatus(ChapterResult result){
chapters.get(pos).setResult(result);
}
void setFinished(boolean finished) {
this.finished = finished;
}
boolean isForward() {
return forward;
}
int forward() {
return ++pos;
}
int back() {
this.forward = false;
return --pos;
}
public Saga() {
this.chapters = new ArrayList<>();
this.pos = 0;
this.forward = true;
this.finished = false;
}
Chapter getCurrent() {
return chapters.get(pos);
}
boolean isPresent() {
return pos >= 0 && pos < chapters.size();
}
boolean isCurrentSuccess(){
return chapters.get(pos).isSuccess();
}
/***
* Class presents a chapter status and incoming parameters(incoming parameter transforms to outcoming parameter)
*/
public static class Chapter {
private String name;
private ChapterResult result;
private Object inValue;
public Chapter(String name) {
this.name = name;
this.result = ChapterResult.INIT;
}
public Object getInValue() {
return inValue;
}
public void setInValue(Object object) {
this.inValue = object;
}
public String getName() {
return name;
}
public void setResult(ChapterResult result){
this.result = result;
}
public boolean isSuccess(){
return result == ChapterResult.SUCCESS;
}
}
public enum ChapterResult {
INIT, SUCCESS, ROLLBACK
}
public enum SagaResult {
PROGRESS, FINISHED, ROLLBACKED
}
@Override
public String toString() {
return "Saga{" +
"chapters=" + Arrays.toString(chapters.toArray()) +
", pos=" + pos +
", forward=" + forward +
'}';
}
}

View File

@ -0,0 +1,77 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
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
* <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) 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)
*
* @see com.iluwatar.saga.choreography.Saga
* @see Service
*/
public class SagaApplication {
private static final Logger logger = LoggerFactory.getLogger(SagaApplication.class);
public static void main(String[] args) {
ServiceDiscoveryService sd = serviceDiscovery();
Chapter service = sd.findAny();
Saga goodOrderSaga = service.execute(newSaga("good_order"));
Saga badOrderSaga = service.execute(newSaga("bad_order"));
logger.info("orders: goodOrder is {}, badOrder is {}",
goodOrderSaga.getResult(), badOrderSaga.getResult());
}
private static Saga newSaga(Object value) {
return Saga
.create()
.chapter("init an order").setInValue(value)
.chapter("booking a Fly")
.chapter("booking a Hotel")
.chapter("withdrawing Money");
}
private static ServiceDiscoveryService serviceDiscovery() {
ServiceDiscoveryService sd = new ServiceDiscoveryService();
return sd
.discover(new OrderService(sd))
.discover(new FlyBookingService(sd))
.discover(new HotelBookingService(sd))
.discover(new WithdrawMoneyService(sd));
}
}

View File

@ -0,0 +1,103 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Common abstraction class representing services
* implementing a general contract @see {@link Chapter}
*/
public abstract class Service implements Chapter {
protected static final Logger logger = LoggerFactory.getLogger(Service.class);
private final ServiceDiscoveryService sd;
public Service(ServiceDiscoveryService service) {
this.sd = service;
}
@Override
public Saga execute(Saga saga) {
Saga nextSaga = saga;
Object nextVal;
String chapterName = saga.getCurrent().getName();
if (chapterName.equals(getName())) {
if (saga.isForward()) {
nextSaga = process(saga);
nextVal = nextSaga.getCurrentValue();
if (nextSaga.isCurrentSuccess()) {
nextSaga.forward();
} else {
nextSaga.back();
}
} else {
nextSaga = rollback(saga);
nextVal = nextSaga.getCurrentValue();
nextSaga.back();
}
if (isSagaFinished(nextSaga)) {
return nextSaga;
}
nextSaga.setCurrentValue(nextVal);
}
Saga finalNextSaga = nextSaga;
return sd.find(chapterName).map(ch -> ch.execute(finalNextSaga))
.orElseThrow(RuntimeException::new);
}
@Override
public Saga process(Saga saga) {
Object inValue = saga.getCurrentValue();
logger.info("The chapter '{}' has been started. The data {} has been stored or calculated successfully",
getName(), inValue);
saga.setCurrentStatus(Saga.ChapterResult.SUCCESS);
saga.setCurrentValue(inValue);
return saga;
}
@Override
public Saga rollback(Saga saga) {
Object inValue = saga.getCurrentValue();
logger.info("The Rollback for a chapter '{}' has been started. The data {} has been rollbacked successfully",
getName(), inValue);
saga.setCurrentStatus(Saga.ChapterResult.ROLLBACK);
saga.setCurrentValue(inValue);
return saga;
}
private boolean isSagaFinished(Saga saga) {
if (!saga.isPresent()) {
saga.setFinished(true);
logger.info(" the saga has been finished with {} status", saga.getResult());
return true;
}
return false;
}
}

View File

@ -0,0 +1,60 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
/**
* The class representing a service discovery pattern.
*/
public class ServiceDiscoveryService {
private Map<String, Chapter> services;
/**
* find any service
* @return any service
* @throws NoSuchElementException if no elements further
*/
public Chapter findAny(){
return services.values().iterator().next();
}
public Optional<Chapter> find(String service) {
return Optional.ofNullable(services.getOrDefault(service, null));
}
public ServiceDiscoveryService discover(Chapter chapterService) {
services.put(chapterService.getName(), chapterService);
return this;
}
public ServiceDiscoveryService() {
this.services = new HashMap<>();
}
}

View File

@ -0,0 +1,53 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
/**
* Class representing a service to withdraw a money
*/
public class WithdrawMoneyService extends Service {
public WithdrawMoneyService(ServiceDiscoveryService service) {
super(service);
}
@Override
public String getName() {
return "withdrawing Money";
}
@Override
public Saga process(Saga saga) {
Object inValue = saga.getCurrentValue();
if (inValue.equals("bad_order") ) {
logger.info("The chapter '{}' has been started. But the exception has been raised." +
"The rollback is about to start",
getName(), inValue);
saga.setCurrentStatus(Saga.ChapterResult.ROLLBACK);
return saga;
}
return super.process(saga);
}
}

View File

@ -28,7 +28,7 @@ import java.util.List;
/**
* Saga representation.
* Saga consists of chapters.
* Every Chapter is executed a certain service.
* Every Chapter is executed by a certain service.
*/
public class Saga {
@ -39,7 +39,6 @@ public class Saga {
}
public Saga chapter(String name) {
this.chapters.add(new Chapter(name));
return this;

View File

@ -24,7 +24,6 @@
package com.iluwatar.saga.orchestration;
import com.iluwatar.saga.ServiceDiscoveryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,6 +37,8 @@ import org.slf4j.LoggerFactory;
*
* 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)
*
* @see Saga
* @see SagaOrchestrator
@ -49,7 +50,7 @@ public class SagaApplication {
public static void main(String[] args) {
SagaOrchestrator sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
Saga.Result goodOrder = sagaOrchestrator.execute("god_order");
Saga.Result goodOrder = sagaOrchestrator.execute("good_order");
Saga.Result badOrder = sagaOrchestrator.execute("bad_order");
Saga.Result crashedOrder = sagaOrchestrator.execute("crashed_order");

View File

@ -22,7 +22,6 @@
*/
package com.iluwatar.saga.orchestration;
import com.iluwatar.saga.ServiceDiscoveryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -48,6 +47,7 @@ public class SagaOrchestrator {
}
/**
* pipeline to execute saga process/story
*
* @param value incoming value
* @param <K> type for incoming value

View File

@ -20,9 +20,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga;
import com.iluwatar.saga.orchestration.Chapter;
package com.iluwatar.saga.orchestration;
import java.util.HashMap;
import java.util.Map;

View File

@ -0,0 +1,35 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
import com.iluwatar.saga.orchestration.SagaApplication;
import org.junit.Test;
import static org.junit.Assert.*;
public class SagaApplicationTest {
@Test
public void mainTest() {
SagaApplication.main(new String[]{});
}
}

View File

@ -0,0 +1,59 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.choreography;
import org.junit.Assert;
import org.junit.Test;
public class SagaChoreographyTest {
@Test
public void executeTest() {
ServiceDiscoveryService sd = serviceDiscovery();
Chapter service = sd.findAny();
Saga badOrderSaga = service.execute(newSaga("bad_order"));
Saga goodOrderSaga = service.execute(newSaga("good_order"));
Assert.assertEquals(badOrderSaga.getResult(), Saga.SagaResult.ROLLBACKED);
Assert.assertEquals(goodOrderSaga.getResult(), Saga.SagaResult.FINISHED);
}
private static Saga newSaga(Object value) {
return Saga
.create()
.chapter("init an order").setInValue(value)
.chapter("booking a Fly")
.chapter("booking a Hotel")
.chapter("withdrawing Money");
}
private static ServiceDiscoveryService serviceDiscovery() {
ServiceDiscoveryService sd = new ServiceDiscoveryService();
return sd
.discover(new OrderService(sd))
.discover(new FlyBookingService(sd))
.discover(new HotelBookingService(sd))
.discover(new WithdrawMoneyService(sd));
}
}

View File

@ -1,3 +1,25 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.orchestration;
import org.junit.Test;

View File

@ -1,6 +1,27 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.orchestration;
import com.iluwatar.saga.ServiceDiscoveryService;
import org.junit.Assert;
import org.junit.Test;
@ -12,7 +33,7 @@ public class SagaOrchestratorInternallyTest {
private List<String> records = new ArrayList<>();
@Test
public void execute() {
public void executeTest() {
SagaOrchestrator sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
Saga.Result result = sagaOrchestrator.execute(1);
Assert.assertEquals(result, Saga.Result.ROLLBACK);

View File

@ -1,6 +1,27 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.saga.orchestration;
import com.iluwatar.saga.ServiceDiscoveryService;
import org.junit.Assert;
import org.junit.Test;