Polish payment service
This commit is contained in:
@@ -11,8 +11,6 @@ import javax.persistence.*;
|
||||
/**
|
||||
* The domain event {@link PaymentEvent} tracks the type and state of events as applied to the {@link Payment} domain
|
||||
* object. This event resource can be used to event source the aggregate state of {@link Payment}.
|
||||
* <p>
|
||||
* This event resource also provides a transaction log that can be used to append actions to the event.
|
||||
*
|
||||
* @author kbastani
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
package demo.event;
|
||||
|
||||
/**
|
||||
* The repository for managing the persistence of {@link PaymentEvent}s.
|
||||
*
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
public interface PaymentEventRepository extends EventRepository<PaymentEvent, Long> {
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import demo.payment.Payment;
|
||||
import demo.payment.PaymentStatus;
|
||||
|
||||
/**
|
||||
* The {@link PaymentEventType} represents a collection of possible events that describe
|
||||
* state transitions of {@link PaymentStatus} on the {@link Payment} aggregate.
|
||||
* The {@link PaymentEventType} represents a collection of possible events that describe state transitions of
|
||||
* {@link PaymentStatus} on the {@link Payment} aggregate.
|
||||
*
|
||||
* @author kbastani
|
||||
*/
|
||||
|
||||
@@ -12,12 +12,10 @@ import java.util.Set;
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
|
||||
/**
|
||||
* The {@link Payment} domain object contains information related to
|
||||
* a user's payment. The status of an payment is event sourced using
|
||||
* events logged to the {@link PaymentEvent} collection attached to
|
||||
* this resource.
|
||||
* The {@link Payment} domain object contains information related to a user's payment. The status of an payment is
|
||||
* event sourced using events logged to the {@link PaymentEvent} collection attached to this resource.
|
||||
*
|
||||
* @author kbastani
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
@Entity
|
||||
public class Payment extends BaseEntity {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package demo.payment;
|
||||
|
||||
/**
|
||||
* The {@link PaymentCommand} represents an action that can be performed to an
|
||||
* {@link Payment} aggregate. Commands initiate an action that can mutate the state of
|
||||
* an payment entity as it transitions between {@link PaymentStatus} values.
|
||||
* The {@link PaymentCommand} represents an action that can be performed to an {@link Payment} aggregate. Commands
|
||||
* initiate an action that can mutate the state of an payment entity as it transitions between {@link PaymentStatus}
|
||||
* values.
|
||||
*
|
||||
* @author kbastani
|
||||
* @author Kenneth Bastani
|
||||
*/
|
||||
public enum PaymentCommand {
|
||||
CONNECT_ORDER,
|
||||
|
||||
@@ -3,10 +3,9 @@ package demo.payment;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
|
||||
/**
|
||||
* A hypermedia resource that describes the collection of commands that
|
||||
* can be applied to a {@link Payment} aggregate.
|
||||
* A hypermedia resource that describes the collection of commands that can be applied to a {@link Payment} aggregate.
|
||||
*
|
||||
* @author kbastani
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
public class PaymentCommands extends ResourceSupport {
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ import java.util.Optional;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
|
||||
/**
|
||||
* The REST API for managing {@link Payment} entities and {@link PaymentEvent}s.
|
||||
*
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1")
|
||||
@ExposesResourceFor(Payment.class)
|
||||
@@ -107,7 +112,6 @@ public class PaymentController {
|
||||
if (payment != null)
|
||||
paymentResource = getPaymentResource(payment);
|
||||
|
||||
|
||||
return paymentResource;
|
||||
}
|
||||
|
||||
@@ -138,8 +142,8 @@ public class PaymentController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an {@link PaymentEvent} domain event to the event log of the {@link Payment}
|
||||
* aggregate with the specified paymentId.
|
||||
* Appends an {@link PaymentEvent} domain event to the event log of the {@link Payment} aggregate with the
|
||||
* specified paymentId.
|
||||
*
|
||||
* @param paymentId is the unique identifier for the {@link Payment}
|
||||
* @param event is the {@link PaymentEvent} that attempts to alter the state of the {@link Payment}
|
||||
@@ -167,8 +171,8 @@ public class PaymentController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link PaymentCommand} hypermedia resource that lists the available commands that can be applied
|
||||
* to an {@link Payment} entity.
|
||||
* Get the {@link PaymentCommand} hypermedia resource that lists the available commands that can be applied to a
|
||||
* {@link Payment} entity.
|
||||
*
|
||||
* @param id is the {@link Payment} identifier to provide command links for
|
||||
* @return an {@link PaymentCommands} with a collection of embedded command links
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package demo.payment;
|
||||
|
||||
/**
|
||||
* The {@link Payment} method for the transaction.
|
||||
*
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
public enum PaymentMethod {
|
||||
CREDIT_CARD
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@ package demo.payment;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* The repository for managing the persistence of {@link Payment} entities.
|
||||
*
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
public interface PaymentRepository extends JpaRepository<Payment, Long> {
|
||||
Payment findPaymentByOrderId(@Param("orderId") Long orderId);
|
||||
}
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
package demo.payment;
|
||||
|
||||
import demo.event.EventService;
|
||||
import demo.util.ConsistencyModel;
|
||||
import demo.event.PaymentEvent;
|
||||
import demo.event.PaymentEventType;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import demo.util.ConsistencyModel;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The {@link PaymentService} provides transactional support for managing {@link Payment}
|
||||
* entities. This service also provides event sourcing support for {@link PaymentEvent}.
|
||||
* Events can be appended to an {@link Payment}, which contains a append-only log of
|
||||
* actions that can be used to support remediation for distributed transactions that encountered
|
||||
* a partial failure.
|
||||
* The {@link PaymentService} provides transactional support for managing {@link Payment} entities. This service also
|
||||
* provides event sourcing support for {@link PaymentEvent}. Events can be appended to an {@link Payment}, which
|
||||
* contains a append-only log of actions that can be used to support remediation for distributed transactions that
|
||||
* encountered a partial failure.
|
||||
*
|
||||
* @author kbastani
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
@Service
|
||||
@CacheConfig(cacheNames = {"payments"})
|
||||
public class PaymentService {
|
||||
|
||||
private final PaymentRepository paymentRepository;
|
||||
@@ -34,14 +28,10 @@ public class PaymentService {
|
||||
this.eventService = eventService;
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "payments", key = "#payment.getPaymentId().toString()")
|
||||
public Payment registerPayment(Payment payment) {
|
||||
|
||||
payment = createPayment(payment);
|
||||
|
||||
// cacheManager.getCache("payments")
|
||||
// .evict(payment.getPaymentId());
|
||||
|
||||
// Trigger the payment creation event
|
||||
PaymentEvent event = appendEvent(payment.getPaymentId(),
|
||||
new PaymentEvent(PaymentEventType.PAYMENT_CREATED));
|
||||
@@ -59,7 +49,6 @@ public class PaymentService {
|
||||
* @param payment is the {@link Payment} to create
|
||||
* @return the newly created {@link Payment}
|
||||
*/
|
||||
@CacheEvict(cacheNames = "payments", key = "#payment.getPaymentId().toString()")
|
||||
public Payment createPayment(Payment payment) {
|
||||
|
||||
// Save the payment to the repository
|
||||
@@ -74,7 +63,6 @@ public class PaymentService {
|
||||
* @param id is the unique identifier of a {@link Payment} entity
|
||||
* @return an {@link Payment} entity
|
||||
*/
|
||||
@Cacheable(cacheNames = "payments", key = "#id.toString()")
|
||||
public Payment getPayment(Long id) {
|
||||
return paymentRepository.findOne(id);
|
||||
}
|
||||
@@ -86,7 +74,6 @@ public class PaymentService {
|
||||
* @param payment is the {@link Payment} containing updated fields
|
||||
* @return the updated {@link Payment} entity
|
||||
*/
|
||||
@CachePut(cacheNames = "payments", key = "#id.toString()")
|
||||
public Payment updatePayment(Long id, Payment payment) {
|
||||
Assert.notNull(id, "Payment id must be present in the resource URL");
|
||||
Assert.notNull(payment, "Payment request body cannot be null");
|
||||
@@ -112,7 +99,6 @@ public class PaymentService {
|
||||
*
|
||||
* @param id is the unique identifier for the {@link Payment}
|
||||
*/
|
||||
@CacheEvict(cacheNames = "payments", key = "#id.toString()")
|
||||
public Boolean deletePayment(Long id) {
|
||||
Assert.state(paymentRepository.exists(id),
|
||||
"The payment with the supplied id does not exist");
|
||||
@@ -144,13 +130,15 @@ public class PaymentService {
|
||||
Payment payment = getPayment(paymentId);
|
||||
Assert.notNull(payment, "The payment with the supplied id does not exist");
|
||||
|
||||
// Add the entity to the event
|
||||
event.setEntity(payment);
|
||||
event = eventService.save(paymentId, event);
|
||||
|
||||
// Add the event to the entity
|
||||
payment.getEvents().add(event);
|
||||
paymentRepository.saveAndFlush(payment);
|
||||
|
||||
// Raise the event using the supplied consistency model
|
||||
// Applies the event for the chosen consistency model
|
||||
switch (consistencyModel) {
|
||||
case BASE:
|
||||
eventService.sendAsync(event);
|
||||
@@ -170,10 +158,8 @@ public class PaymentService {
|
||||
* @param paymentCommand is the command to apply to the {@link Payment}
|
||||
* @return a hypermedia resource containing the updated {@link Payment}
|
||||
*/
|
||||
@CachePut(cacheNames = "payments", key = "#id.toString()")
|
||||
public Payment applyCommand(Long id, PaymentCommand paymentCommand) {
|
||||
Payment payment = getPayment(id);
|
||||
|
||||
Assert.notNull(payment, "The payment for the supplied id could not be found");
|
||||
|
||||
PaymentStatus status = payment.getStatus();
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package demo.payment;
|
||||
|
||||
/**
|
||||
* The {@link PaymentStatus} describes the state of an {@link Payment}.
|
||||
* The aggregate state of a {@link Payment} is sourced from attached domain
|
||||
* events in the form of {@link demo.event.PaymentEvent}.
|
||||
* The {@link PaymentStatus} describes the state of an {@link Payment}. The aggregate state of a {@link Payment} is
|
||||
* sourced from attached domain events in the form of {@link demo.event.PaymentEvent}.
|
||||
*
|
||||
* @author kbastani
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
public enum PaymentStatus {
|
||||
PAYMENT_CREATED,
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package demo.util;
|
||||
|
||||
/**
|
||||
* The {@link ConsistencyModel} is used to configure how an {@link demo.event.Event} will be applied to an entity.
|
||||
* BASE is eventually consistent and will process an event workflow asynchronously using Spring Cloud Stream.
|
||||
* ACID uses strong eventual consistency and will process an event workflow sequentially and return the result to the
|
||||
* calling thread.
|
||||
*
|
||||
* @author Kenny Bastani
|
||||
*/
|
||||
public enum ConsistencyModel {
|
||||
BASE,
|
||||
ACID
|
||||
|
||||
Reference in New Issue
Block a user