content: package io.vividcode.happyride.tripservice.sagas.createtrip;
  
  import io.eventuate.tram.commands.common.Success;
  import io.eventuate.tram.sagas.orchestration.SagaDefinition;
  import io.eventuate.tram.sagas.simpledsl.SimpleSaga;
  import io.vividcode.happyride.paymentservice.api.events.PaymentFailedReply;
  import io.vividcode.happyride.tripservice.sagaparticipants.PaymentServiceProxy;
  import io.vividcode.happyride.tripservice.sagaparticipants.TripServiceProxy;
  import io.vividcode.happyride.tripservice.sagaparticipants.TripValidationServiceProxy;
  import java.util.function.Predicate;
  import org.springframework.stereotype.Component;
  
  @Component
  public class CreateTripSaga implements SimpleSaga<CreateTripSagaState> {
  
    private final SagaDefinition<CreateTripSagaState> sagaDefinition;
  
    public CreateTripSaga(final TripServiceProxy tripService,
        final TripValidationServiceProxy tripValidationService,
        final PaymentServiceProxy paymentService) {
      this.sagaDefinition = this.step()
          .withCompensation(tripService.reject,
              CreateTripSagaState::createRejectTripCommand)
          .step()
          .invokeParticipant(tripValidationService.validateTrip,
              CreateTripSagaState::createValidateTripCommand)
          .step()
          .invokeParticipant(paymentService.createPayment,
              CreateTripSagaState::createPaymentCommand)
          .step()
          .invokeParticipant(
              CreateTripSagaState::paymentRequired, paymentService.makePayment,
              CreateTripSagaState::makePaymentCommand)
          .onReply(PaymentFailedReply.class,
              CreateTripSagaState::handlePaymentFailedReply)
          .onReply(Success.class, (state, success) -> state.markAsPaid())
          .step()
          .invokeParticipant(CreateTripSagaState::shouldConfirmTrip,
              tripService.confirm,
              CreateTripSagaState::createConfirmTripCommand)
          .step()
          .invokeParticipant(
              ((Predicate<CreateTripSagaState>) CreateTripSagaState::shouldConfirmTrip)
                  .negate(),
              tripService.reject, CreateTripSagaState::createRejectTripCommand)
          .build();
    }
  
    @Override
    public SagaDefinition<CreateTripSagaState> getSagaDefinition() {
      return this.sagaDefinition;
    }
  }
  