Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial saga #21

Merged
merged 4 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ services:
AWS_ACCESS_KEY_ID: "fakekey"
AWS_SECRET_ACCESS_KEY: "fakeaccesskey"
AWS_DYNAMODB_ENDPOINT: payments_db:54000
AWS_REGION: us-east-1
AWS_REGION: us-east-2
ADMIN_ACCESS_TOKEN: token
MOCK_PAYMENT_PROVIDER: true
MP_TOKEN: token
Expand All @@ -34,9 +34,21 @@ services:
environment:
AWS_ACCESS_KEY_ID: "fakekey"
AWS_SECRET_ACCESS_KEY: "fakeaccesskey"
AWS_REGION: us-east-1
AWS_REGION: us-east-2
command: ["-D\"java.library.path\"=./DynamoDBLocal_lib", "-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"]

localstack:
image: localstack/localstack:latest
container_name: localstack-sqs-sns
ports:
- "4566:4566"
- "4510-4559:4510-4559"
environment:
- SERVICES=sqs,sns
- AWS_DEFAULT_REGION=us-east-2
volumes:
- ./src/main/resources/localstack/localstack-init.sh:/etc/localstack/init/ready.d/init-aws.sh

volumes:
payments_db:
driver: local
16 changes: 16 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<name>payments</name>
<description>Payments API</description>
<properties>
<awsspring.version>3.0.4</awsspring.version>
<java.version>17</java.version>
<kotlin.version>1.8.22</kotlin.version>
<kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget>
Expand Down Expand Up @@ -110,6 +111,14 @@
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
</dependency>
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-starter-sns</artifactId>
</dependency>
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-starter-sqs</artifactId>
</dependency>
<dependency>
<groupId>io.github.boostchicken</groupId>
<artifactId>spring-data-dynamodb</artifactId>
Expand Down Expand Up @@ -149,6 +158,13 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-dependencies</artifactId>
<version>${awsspring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package com.fiap.payments.adapter.controller

import com.fiap.payments.domain.entities.Payment
import com.fiap.payments.driver.web.PaymentAPI
import com.fiap.payments.driver.web.request.PaymentHTTPRequest
import com.fiap.payments.usecases.ChangePaymentStatusUseCase
import com.fiap.payments.usecases.LoadPaymentUseCase
import com.fiap.payments.usecases.ProvidePaymentRequestUseCase
import com.fiap.payments.usecases.SyncPaymentUseCase
import org.slf4j.LoggerFactory
import org.springframework.http.ResponseEntity
Expand All @@ -15,7 +13,6 @@ import org.springframework.web.bind.annotation.RestController
class PaymentController(
private val loadPaymentUseCase: LoadPaymentUseCase,
private val syncPaymentUseCase: SyncPaymentUseCase,
private val providePaymentRequestUseCase: ProvidePaymentRequestUseCase,
private val changePaymentStatusUseCase: ChangePaymentStatusUseCase,
) : PaymentAPI {
private val log = LoggerFactory.getLogger(javaClass)
Expand All @@ -28,9 +25,6 @@ class PaymentController(
return ResponseEntity.ok(loadPaymentUseCase.getByPaymentId(paymentId))
}

override fun create(paymentHTTPRequest: PaymentHTTPRequest): ResponseEntity<Payment> {
return ResponseEntity.ok(providePaymentRequestUseCase.providePaymentRequest(paymentHTTPRequest))
}

override fun fail(paymentId: String): ResponseEntity<Payment> {
return ResponseEntity.ok(changePaymentStatusUseCase.failPayment(paymentId))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package com.fiap.payments.adapter.controller.config

import com.fiap.payments.PaymentsApiApp
import com.fiap.payments.adapter.gateway.OrderGateway
import com.fiap.payments.adapter.gateway.PaymentGateway
import com.fiap.payments.adapter.gateway.PaymentProviderGateway
import com.fiap.payments.usecases.ChangePaymentStatusUseCase
import com.fiap.payments.usecases.ConfirmOrderUseCase
import com.fiap.payments.usecases.LoadPaymentUseCase
import com.fiap.payments.usecases.services.OrderService
import com.fiap.payments.usecases.services.PaymentService
import com.fiap.payments.usecases.services.PaymentSyncService
import org.springframework.context.annotation.Bean
Expand All @@ -21,13 +18,11 @@ class ServiceConfig {
@Bean
fun createPaymentService(
paymentRepository: PaymentGateway,
paymentProvider: PaymentProviderGateway,
confirmOrderUseCase: ConfirmOrderUseCase
paymentProvider: PaymentProviderGateway
): PaymentService {
return PaymentService(
paymentRepository,
paymentProvider,
confirmOrderUseCase
)
}

Expand All @@ -46,10 +41,4 @@ class ServiceConfig {
)
}

@Bean
fun paymentOrderService(orderGateway: OrderGateway): OrderService {
return OrderService(
orderGateway
)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ interface PaymentGateway {
fun findAll(): List<Payment>

fun upsert(payment: Payment): Payment

fun publishPayment(payment: Payment): Payment
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package com.fiap.payments.adapter.gateway

import com.fiap.payments.domain.entities.PaymentRequest
import com.fiap.payments.domain.valueobjects.PaymentStatus
import com.fiap.payments.driver.web.request.PaymentHTTPRequest
import com.fiap.payments.driver.messaging.event.PaymentRequestEvent

interface PaymentProviderGateway {
fun createExternalOrder(paymentId: String, paymentHTTPRequest: PaymentHTTPRequest): PaymentRequest
fun createExternalOrder(paymentId: String, paymentHTTPRequest: PaymentRequestEvent): PaymentRequest

fun checkExternalOrderStatus(externalOrderGlobalId: String): PaymentStatus
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.fiap.payments.adapter.gateway.impl

import com.fiap.payments.adapter.gateway.PaymentGateway
import com.fiap.payments.adapter.messaging.PaymentSender
import com.fiap.payments.domain.entities.Payment
import com.fiap.payments.driver.database.persistence.mapper.PaymentMapper
import com.fiap.payments.driver.database.persistence.repository.PaymentDynamoRepository
import org.mapstruct.factory.Mappers

class PaymentGatewayImpl(
private val paymentRepository: PaymentDynamoRepository,
private val paymentSender: PaymentSender
) : PaymentGateway {
private val mapper = Mappers.getMapper(PaymentMapper::class.java)

Expand Down Expand Up @@ -37,6 +39,11 @@ class PaymentGatewayImpl(
return persist(paymentUpdated)
}

override fun publishPayment(payment: Payment): Payment {
paymentSender.sendPayment(payment)
return payment
}

private fun persist(payment: Payment): Payment =
payment
.let(mapper::toEntity)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.fiap.payments.adapter.messaging

import com.fiap.payments.domain.entities.Payment

interface PaymentSender {
fun sendPayment(payment: Payment)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fiap.payments.adapter.messaging.config

import com.fasterxml.jackson.databind.ObjectMapper
import com.fiap.payments.adapter.messaging.PaymentSender
import com.fiap.payments.adapter.messaging.impl.PaymentSenderImpl
import io.awspring.cloud.sns.core.SnsTemplate
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class MessagingConfig {

@Bean
fun createPaymentSender(snsTemplate: SnsTemplate,
@Value("\${topic.response-payment}") topicName: String,
objectMapper: ObjectMapper): PaymentSender {
return PaymentSenderImpl(snsTemplate, topicName, objectMapper)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fiap.payments.adapter.messaging.impl

import com.fasterxml.jackson.databind.ObjectMapper
import com.fiap.payments.adapter.messaging.PaymentSender
import com.fiap.payments.domain.entities.Payment
import io.awspring.cloud.sns.core.SnsTemplate
import org.springframework.messaging.support.GenericMessage

class PaymentSenderImpl(
private val snsTemplate: SnsTemplate,
private val topicName: String,
private val mapper: ObjectMapper
) : PaymentSender {

override fun sendPayment(payment: Payment) {
snsTemplate.send(
topicName, GenericMessage(mapper.writeValueAsString(payment))
)
}
}
20 changes: 0 additions & 20 deletions src/main/kotlin/com/fiap/payments/client/OrderApiClient.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.fiap.payments.driver.database.config
import com.fiap.payments.PaymentsApiApp
import com.fiap.payments.adapter.gateway.*
import com.fiap.payments.adapter.gateway.impl.*
import com.fiap.payments.client.OrderApiClient
import com.fiap.payments.adapter.messaging.PaymentSender
import com.fiap.payments.driver.database.persistence.repository.*
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
Expand All @@ -14,17 +14,13 @@ import org.springframework.context.annotation.Configuration
class GatewayConfig {

@Bean("PaymentGateway")
fun createPaymentGateway(paymentJpaRepository: PaymentDynamoRepository): PaymentGateway {
return PaymentGatewayImpl(paymentJpaRepository)
fun createPaymentGateway(paymentJpaRepository: PaymentDynamoRepository, paymentSender: PaymentSender): PaymentGateway {
return PaymentGatewayImpl(paymentJpaRepository, paymentSender)
}

@Bean("TransactionalGateway")
fun createTransactionalGateway(): TransactionalGateway {
return TransactionalGatewayImpl()
}

@Bean("OrderGateway")
fun createOrderGateway(orderApiClient: OrderApiClient): OrderGateway {
return OrderGatewayImpl(orderApiClient)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import com.fiap.payments.client.MercadoPagoQRCodeOrderRequest
import com.fiap.payments.client.MercadoPagoQRCodeOrderRequestItem
import com.fiap.payments.domain.entities.PaymentRequest
import com.fiap.payments.domain.valueobjects.PaymentStatus
import com.fiap.payments.driver.web.request.PaymentHTTPRequest
import com.fiap.payments.driver.messaging.event.PaymentRequestEvent

class MercadoPagoPaymentProvider(
private val mercadoPagoClient: MercadoPagoClient,
private val webhookBaseUrl: String,
) : PaymentProviderGateway {

override fun createExternalOrder(paymentId: String, paymentHTTPRequest: PaymentHTTPRequest): PaymentRequest {
override fun createExternalOrder(paymentId: String, paymentHTTPRequest: PaymentRequestEvent): PaymentRequest {
// source_news=ipn indicates application will receive only Instant Payment Notifications (IPNs), not webhooks
val notificationUrl = "${webhookBaseUrl}/payments/notifications/${paymentId}?source_news=ipn"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package com.fiap.payments.driver.database.provider
import com.fiap.payments.adapter.gateway.PaymentProviderGateway
import com.fiap.payments.domain.entities.PaymentRequest
import com.fiap.payments.domain.valueobjects.PaymentStatus
import com.fiap.payments.driver.web.request.PaymentHTTPRequest
import com.fiap.payments.driver.messaging.event.PaymentRequestEvent
import org.slf4j.LoggerFactory
import java.util.*

class PaymentProviderGatewayMock: PaymentProviderGateway {
private val log = LoggerFactory.getLogger(javaClass)

override fun createExternalOrder(paymentId: String, paymentHTTPRequest: PaymentHTTPRequest): PaymentRequest {
override fun createExternalOrder(paymentId: String, paymentHTTPRequest: PaymentRequestEvent): PaymentRequest {
log.info("Providing mocked payment request for order [${paymentHTTPRequest.orderInfo.number}]")
return PaymentRequest(
externalOrderId = UUID.randomUUID().toString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.fiap.payments.driver.messaging.consumer

import com.fiap.payments.driver.messaging.event.PaymentRequestEvent
import com.fiap.payments.usecases.ProvidePaymentRequestUseCase
import io.awspring.cloud.sqs.annotation.SqsListener
import org.slf4j.LoggerFactory
import org.springframework.context.event.EventListener
import org.springframework.messaging.MessageHeaders
import org.springframework.messaging.handler.annotation.Headers
import org.springframework.scheduling.annotation.EnableAsync
import org.springframework.stereotype.Component

@Component
@EnableAsync
class RequestPaymentConsumer(
private val providePaymentRequestUseCase: ProvidePaymentRequestUseCase) {

private val log = LoggerFactory.getLogger(javaClass)


@SqsListener("\${sqs.queues.request-payment}")
fun onMessage(message: PaymentRequestEvent, @Headers headers: MessageHeaders) {
log.info(message.toString())
providePaymentRequestUseCase.providePaymentRequest(message)
}
}


Loading
Loading