Repository: KimByeongKou/fastcampus-pay
Branch: main
Commit: e61875092c50
Files: 173
Total size: 138.2 KB
Directory structure:
gitextract_owzcci7l/
├── .gitignore
├── .idea/
│ ├── .gitignore
│ ├── compiler.xml
│ ├── gradle.xml
│ ├── jarRepositories.xml
│ ├── misc.xml
│ ├── modules/
│ │ ├── common/
│ │ │ └── fastcampus-pay.common.main.iml
│ │ └── settlement-service/
│ │ └── fastcampus-pay.settlement-service.main.iml
│ ├── modules.xml
│ ├── uiDesigner.xml
│ └── vcs.xml
├── Dockerfile
├── README.md
├── banking-service/
│ ├── build.gradle
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── fastcampuspay/
│ └── banking/
│ ├── BankingApplication.java
│ ├── BankingConfiguration.java
│ ├── BankingConfigurationProperties.java
│ ├── SwaggerConfig.java
│ ├── adapter/
│ │ ├── in/
│ │ │ └── web/
│ │ │ ├── FindBankingAccountInfoController.java
│ │ │ ├── RegisterBankingAccountInfoController.java
│ │ │ ├── RegisterBankingAccountInfoRequest.java
│ │ │ └── RequestTransferMoneyController.java
│ │ └── out/
│ │ └── persistence/
│ │ ├── BankingAccountPersistenceAdapter.java
│ │ ├── BankingAccountRegisterInfoJpaEntity.java
│ │ ├── BankingAccountRegisterInfoMapper.java
│ │ └── SpringDataBankingAccountRegisterInfoRepository.java
│ ├── application/
│ │ ├── port/
│ │ │ ├── in/
│ │ │ │ ├── RegisterBankingAccountCommand.java
│ │ │ │ └── RegisterBankingAccountUseCase.java
│ │ │ └── out/
│ │ │ └── RegisterBankingAccountPort.java
│ │ └── service/
│ │ └── RegisterBankingAccount.java
│ └── domain/
│ ├── BankingAccountRegisterInfo.java
│ └── TransferMoney.java
├── build.gradle
├── common/
│ ├── build.gradle
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── fastcampuspay/
│ └── common/
│ ├── PersistenceAdapter.java
│ ├── SelfValidating.java
│ ├── UseCase.java
│ ├── WebAdapter.java
│ └── events/
│ └── RegisterAccountEvent.java
├── db/
│ ├── conf.d/
│ │ └── my.cnf
│ └── initdb.d/
│ ├── create_table.sql
│ └── load_data.sql
├── docker-compose.yaml
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── membership-service/
│ ├── build.gradle
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── fastcampuspay/
│ └── membership/
│ ├── MembershipApplication.java
│ ├── MembershipConfiguration.java
│ ├── MembershipConfigurationProperties.java
│ ├── SwaggerConfig.java
│ ├── adapter/
│ │ ├── in/
│ │ │ └── web/
│ │ │ ├── FindMembershipController.java
│ │ │ ├── FindMembershipRequest.java
│ │ │ ├── LoginAuthMembershipController.java
│ │ │ ├── RegisterMembershipController.java
│ │ │ ├── RegisterMembershipRequest.java
│ │ │ ├── UpdateMembershipController.java
│ │ │ └── UpdateMembershipRequest.java
│ │ └── out/
│ │ └── persistence/
│ │ ├── MembershipJpaEntity.java
│ │ ├── MembershipMapper.java
│ │ ├── MembershipPersistenceAdapter.java
│ │ └── SpringDataMembershipRepository.java
│ ├── application/
│ │ ├── port/
│ │ │ ├── in/
│ │ │ │ ├── FindMembershipCommand.java
│ │ │ │ ├── FindMembershipUseCase.java
│ │ │ │ ├── RegisterMembershipCommand.java
│ │ │ │ ├── RegisterMembershipUseCase.java
│ │ │ │ ├── UpdateMembershipCommand.java
│ │ │ │ ├── UpdateMembershipEventCommand.java
│ │ │ │ ├── UpdateMembershipUseCase.java
│ │ │ │ └── aggregate/
│ │ │ │ └── MembershipAggregate.java
│ │ │ └── out/
│ │ │ ├── FindMembershipPort.java
│ │ │ ├── RegisterMembershipPort.java
│ │ │ ├── UpdateMembershipPort.java
│ │ │ └── query/
│ │ │ ├── FindMembershipQuery.java
│ │ │ └── MembershipQueryHandler.java
│ │ ├── saga/
│ │ │ ├── MembershipCreateEvent.java
│ │ │ ├── MembershipUpdateEvent.java
│ │ │ ├── Order.java
│ │ │ ├── OrderCancelledEvent.java
│ │ │ ├── OrderConfirmedEvent.java
│ │ │ ├── OrderCreatedEvent.java
│ │ │ ├── OrderPlacedEvent.java
│ │ │ ├── OrderSaga.java
│ │ │ ├── Payment.java
│ │ │ ├── PaymentCancelledEvent.java
│ │ │ ├── PaymentCompletedEvent.java
│ │ │ └── PaymentRequestedCommand.java
│ │ └── service/
│ │ ├── FindMembership.java
│ │ ├── RegisterMembership.java
│ │ └── UpdateMembership.java
│ └── domain/
│ └── Membership.java
├── money-local-service/
│ ├── build.gradle
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── fastcampuspay/
│ └── moneylocal/
│ ├── MoneyLocalApplication.java
│ ├── MoneyLocalConfiguration.java
│ ├── MoneyLocalConfigurationProperties.java
│ ├── SwaggerConfig.java
│ ├── adapter/
│ │ ├── in/
│ │ │ └── web/
│ │ │ └── CalculateLocalMoneyController.java
│ │ └── out/
│ │ └── persistence/
│ │ ├── LocalMoneyJpaEntity.java
│ │ ├── LocalMoneyMapper.java
│ │ ├── LocalMoneyPersistenceAdapter.java
│ │ └── SpringDataLocalMoneyRepository.java
│ ├── application/
│ │ ├── port/
│ │ │ ├── in/
│ │ │ │ ├── RechargeMoneyCommand.java
│ │ │ │ └── RechargeMoneyUseCase.java
│ │ │ └── out/
│ │ │ └── RechargeMoneyPort.java
│ │ └── service/
│ │ └── RechargeMoney.java
│ └── domain/
│ └── MemberMoney.java
├── money-service/
│ ├── build.gradle
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── fastcampuspay/
│ └── money/
│ ├── MoneyApplication.java
│ ├── MoneyConfiguration.java
│ ├── MoneyConfigurationProperties.java
│ ├── SwaggerConfig.java
│ ├── adapter/
│ │ ├── in/
│ │ │ └── web/
│ │ │ ├── FindMoneyController.java
│ │ │ ├── RechargeMoneyController.java
│ │ │ └── RequestTransferMoneyController.java
│ │ └── out/
│ │ └── persistence/
│ │ ├── RechargeMoneyJpaEntity.java
│ │ ├── RechargeMoneyMapper.java
│ │ ├── RechargeMoneyPersistenceAdapter.java
│ │ └── SpringDataRechargeMoneyRepository.java
│ ├── application/
│ │ ├── port/
│ │ │ ├── in/
│ │ │ │ ├── RechargeMoneyCommand.java
│ │ │ │ └── RechargeMoneyUseCase.java
│ │ │ └── out/
│ │ │ └── RechargeMoneyPort.java
│ │ └── service/
│ │ └── RechargeMoney.java
│ └── domain/
│ └── MemberMoney.java
├── payment-service/
│ ├── build.gradle
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── fastcampuspay/
│ └── payment/
│ ├── PaymentApplication.java
│ ├── PaymentConfiguration.java
│ ├── PaymentConfigurationProperties.java
│ ├── SwaggerConfig.java
│ ├── adapter/
│ │ ├── in/
│ │ │ └── web/
│ │ │ ├── FindPaymentController.java
│ │ │ └── RequestTransferMoneyController.java
│ │ └── out/
│ │ └── persistence/
│ │ ├── PaymentJpaEntity.java
│ │ ├── PaymentMapper.java
│ │ ├── RechargeMoneyPersistenceAdapter.java
│ │ └── SpringDataPaymentRepository.java
│ ├── application/
│ │ ├── port/
│ │ │ ├── in/
│ │ │ │ ├── RechargeMoneyCommand.java
│ │ │ │ └── RechargeMoneyUseCase.java
│ │ │ └── out/
│ │ │ └── RechargeMoneyPort.java
│ │ └── service/
│ │ └── RechargeMoney.java
│ └── domain/
│ └── MemberMoney.java
├── remittance-service/
│ ├── build.gradle
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── fastcampuspay/
│ └── remittance/
│ ├── RemittanceApplication.java
│ ├── RemittanceConfiguration.java
│ ├── RemittanceConfigurationProperties.java
│ ├── SwaggerConfig.java
│ ├── adapter/
│ │ ├── in/
│ │ │ └── web/
│ │ │ ├── FindRemittanceController.java
│ │ │ └── RequestRemittanceMoneyController.java
│ │ └── out/
│ │ └── persistence/
│ │ ├── RemittanceMoneyJpaEntity.java
│ │ ├── RemittanceMoneyMapper.java
│ │ ├── RemittanceMoneyPersistenceAdapter.java
│ │ └── SpringDataRemittanceMoneyRepository.java
│ ├── application/
│ │ ├── port/
│ │ │ ├── in/
│ │ │ │ ├── RemittanceMoneyCommand.java
│ │ │ │ └── RemittanceMoneyUseCase.java
│ │ │ └── out/
│ │ │ └── RemittanceMoneyPort.java
│ │ └── service/
│ │ └── RemittanceMoney.java
│ └── domain/
│ └── RemittanceMoney.java
├── settings.gradle
└── settlement-service/
├── build.gradle
└── src/
└── main/
└── java/
└── com/
└── fastcampuspay/
└── settlement/
├── SettlementApplication.java
├── SettlementConfiguration.java
├── SettlementConfigurationProperties.java
├── SwaggerConfig.java
├── adapter/
│ ├── in/
│ │ └── web/
│ │ └── SettlementStartController.java
│ └── out/
│ └── persistence/
│ ├── RechargeMoneyMapper.java
│ ├── RechargeMoneyPersistenceAdapter.java
│ ├── SettlementJpaEntity.java
│ └── SpringDataSettlementRepository.java
├── application/
│ ├── port/
│ │ ├── in/
│ │ │ ├── RechargeMoneyCommand.java
│ │ │ └── RechargeMoneyUseCase.java
│ │ └── out/
│ │ └── RechargeMoneyPort.java
│ └── service/
│ └── RechargeMoney.java
└── domain/
└── MemberMoney.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
/*/build/
axon-server-se/*/*
db/data/*
================================================
FILE: .idea/.gitignore
================================================
# 디폴트 무시된 파일
/shelf/
/workspace.xml
# 에디터 기반 HTTP 클라이언트 요청
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Zeppelin ignored files
/ZeppelinRemoteNotebooks/
================================================
FILE: .idea/compiler.xml
================================================
================================================
FILE: .idea/gradle.xml
================================================
================================================
FILE: .idea/jarRepositories.xml
================================================
================================================
FILE: .idea/misc.xml
================================================
================================================
FILE: .idea/modules/common/fastcampus-pay.common.main.iml
================================================
================================================
FILE: .idea/modules/settlement-service/fastcampus-pay.settlement-service.main.iml
================================================
================================================
FILE: .idea/modules.xml
================================================
================================================
FILE: .idea/uiDesigner.xml
================================================
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
================================================
FILE: .idea/vcs.xml
================================================
================================================
FILE: Dockerfile
================================================
FROM openjdk:11-slim-stretch
EXPOSE 8080
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
#"-Djava.security.egd=file:/dev/./urandom",
#"-Dspring.profiles.active=prod",
ENTRYPOINT ["java", "-jar", "/app.jar"]
================================================
FILE: README.md
================================================
# FastCampus-Pay Project Overview

일반적인 간편결제 도메인을 주제로, MSA 를 중점적으로 학습하기 위한 교육용 프로젝트입니다.
회원(Membership), 뱅킹(Banking), 머니(Money), 송금(Remittance), 결제(Payment), 정산(Settlement) 6개의 서비스로 구성되어 있으며, 각각의 독립적인 프로젝트로 구성되어 있어요.
각 서비스에서는 기본적인 기능을 먼저 Hexagonal Architecture 로 구현하고, 일부 기능들에 EDA, CQRS, Event Sourcing, Saga Pattern 등을 적용하며 진행해 보아요.
기본적으로 Springboot 와 Java 11 을 기준으로 프로젝트를 구성하고, EDA 구현을 위해서 Axon Framework v4.6.0 을 사용해요.
로깅 파이프라인은 따로 구성하진 않았지만, kafka 의 실습을 목적으로 하는 간단한 로깅 파이프라인을 구성할 예정이에요.
실제 간편 결제 도메인 시스템과는 복잡성 측면에서 차이가 있지만, 간단한 버전을 기준으로 MSA 를 구성하고, 각 서비스의 기능을 구현하며, EDA 를 적용해 보는 것을 목표로 진행해요.
아래 내용들은 수업 진행 방향 및 실습 진행 속도에 따라 유동적일 수 있어요.
## Overall Architecture for Monolithic System

## Overall Architecture for MSA

## Membership Service (Part. 2, 3, 6, 7)
고객의 회원 가입, 회원 정보 변경, 회원 정보 조회 등의 기능을 제공하는 서비스입니다.
- Part 2.
- Hexagonal Architecture 를 활용하여 기본적인 Membership Service 를 구현 (회원 가입)
- Part 3.
- gradle build tool 을 이용하여 Docker build 연동. 추가적인 Membership Service 를 구현 (회원 정보 변경)
- Part 6.
- Axon Framework 를 이용하여 Event Driven Architecture 로 리팩토링.
- 고객 정보가 변경될 경우, 이벤트를 발행하고, 이를 구독하는 Money 서비스 에서 고객의 머니 정보를 변경하는 CQRS 패턴 구현 (with/ AWS DynamoDB)
- Part 7.
- 보안을 위해 JWT 를 이용한 간단한 API 인증 구현
### API Lists
- registerMembership
- updateMembershipByMemberId (CQRS Trigger)
- findMembershipByMemberId
- loginByMembershipIdPw
- authByToken
#### Using Stack
- Spring Boot, Java 11, Spring Data JPA, H2, Mysql, Lombok, Gradle, JWT, Axon Framework, Docker, Docker Compose, AWS DynamoDB
### Sequence Diagram Example (회원 가입, JWT 토큰 인증 프로세스)

## Banking Service (Part. 3)
고객의 계좌 정보 등록, 등록된 계좌 정보 조회, 입/출금, 거래내역 조회 등의 기능을 제공하는 서비스입니다.
- Part 3.
- Hexagonal Architecture 를 활용하여 기본적인 Banking Service 를 구현 (가상의 법인 계좌 및 고객 계좌 정보 등록, 은행으로 입/출금 요청하기)
### API Lists
- registerBankingAccount
- requestTransferMoneyToBank
- findRegisteredBankingAccountByMemberId
- findTransferMoneyInfoByMemberId
- findTransferMoneyInfoByBankingId
#### Using Stack
- Spring Boot, Java 11, Spring Data JPA, H2, Mysql, Lombok, Gradle, JWT, Axon Framework, Docker, Docker Compose
### Sequence Diagram Example (입/출금 요청 프로세스)

## Money Service (Part. 3, 4, 5, 6)
고객의 충전 잔액(머니) CRUD, 충전 내역 조회 등의 기능을 제공하는 서비스입니다.
- Part 3.
- Hexagonal Architecture 를 활용하여 Membership 서비스 및 Banking 서비스를 이용하는 충전 잔액(머니)을 충전하는 기능 구현
- 충전 내역 조회 기능 구현
- Part 4.
- kafka 을 이용한 간단 로깅 파이프라인 적용 (kafka 를 이용한 로깅 파이프라인은 실습을 위한 간단한 구현이며, 실제로는 ELK/EFK 등을 이용한 로깅 파이프라인을 구성하는 것을 추천합니다.)
- 충전 잔액(머니) 충전 프로세스를 Async 방식으로 구현하고, Polling 을 통한 결과 조회 방식 구현
- Part 5.
- 충전 잔액(머니)을 충전하는 기능은 Axon Framework 를 이용하여 Saga Pattern 적용 및 리팩토링
- Part 6.
- Axon Framework 를 이용하여 Event Driven Architecture 로 리팩토링.
- Membership 서비스로부터 고객 정보 변경 이벤트를 수신하고, 이를 기반으로 CQRS 패턴을 구현 (with/ AWS DynamoDB)
- "지역별 고객들의 잔액 총합 View" 을 얻어오려면?
### API Lists
- rechargeMoneyByMemberId
- findMoneyInfoByRechargeMoneyId
- findMoneyHistoryByMemberId
- transferMoneyBetweenMembers
### MoneyLocal Service (for CQRS)
- calculateMoneySumByLocal
- MembershipUpdate (EventHandler)
#### Using Stack
- Spring Boot, Java 11, Spring Data JPA, H2, Mysql, Lombok, Gradle, JWT, Axon Framework, Docker, Docker Compose, Kafka, Kafka-ui, Zookeeper, AWS DynamoDB
### Sequence Diagram Example (충전 잔액(머니) 충전 프로세스)

## Remittance Service (Part. 4, 5, 6)
고객 간 송금 기능 및 송금 내역 정보 조회 등의 기능을 제공하는 서비스입니다.
- Part 4.
- Hexagonal Architecture 를 활용하여 Membership 서비스, Banking 서비스, Money 서비스를 이용하는 고객 간 혹은 계좌 송금 기능 구현
- Part 5.
- 고객 간 송금하는 기능은 기능은 Axon Framework 를 이용하여 Saga Pattern 적용 및 리팩토링
- Part 6.
- 특정 송금 건을 기준으로, 머니의 충전 내역을 조회해보는 기능 구현을 위해 API Aggregation Pattern 적용
### API Lists
- requestRemittance
- findRemittanceInfoByRemittanceId
- findRemittanceHistoryByMemberId
- findMoneyTransferringByRemittanceId (API Aggregation, Banking + Money)
#### Using Stack
- Spring Boot, Java 11, Spring Data JPA, H2, Mysql, Lombok, Gradle, JWT, Axon Framework, Docker, Docker Compose, AWS DynamoDB
### Sequence Diagram Example (송금 프로세스)

## Payment Service (Part. 5)
가맹점에서 Fastcampus Pay 를 이용한 간편 결제 및 결제 내역 조회 등의 기능을 제공하는 서비스입니다.
- Part 5.
- Hexagonal Architecture 를 활용하여 Membership 서비스, Money 서비스를 이용하는 가맹점에서의 결제 기능 구현
- Membership Service 의 가맹점주 기능 확장
### API Lists
- requestPaymentAtMerchant
- findPaymentByPaymentId
- listPaymentsByPeriod
#### Using Stack
- Spring Boot, Java 11, Spring Data JPA, Mysql, Lombok, Gradle, Axon Framework, Docker, Docker Compose
### Sequence Diagram Example (결제 프로세스)

## Settlement Service (Part. 6)
완료된 결제 내역을 기준으로 가맹점에 정산된 금액을 입금하고, 수수료 수취를 위한 기능을 제공하는 서비스입니다.
- Part 6.
- Hexagonal Architecture 를 활용하여 Payment 서비스를 이용하는 기간별 정산 기능 구현.
- 수수료 수취 기능 구현, 가맹점주 계좌로 입금 기능 구현.
### API Lists
- startSettlementByPeriod
#### Using Stack
- Spring Boot, Java 11, Spring Data JPA, Mysql, Lombok, Gradle, JWT, Axon Framework, Docker, Docker Compose
### Sequence Diagram Example (정산 프로세스)

## Execution
```
./gradlew docker
docker-compose up -d
```
## Service Endpoint & Swagger UI
- Membership Service
- http://localhost:8081/membership/
- http://localhost:8081/swagger-ui.html
- Banking Service
- http://localhost:8082/banking/
- http://localhost:8082/swagger-ui.html
- Money Service
- http://localhost:8083/money/
- http://localhost:8083/swagger-ui.html
- Money Local Service (CQRS View Service)
- http://localhost:8084/money-local/
- http://localhost:8084/swagger-ui.html
- Remittance Service
- http://localhost:8085/remittance/
- http://localhost:8085/swagger-ui.html
- Payment Service
- http://localhost:8086/payment/
- http://localhost:8086/swagger-ui.html
- Settlement Service
- http://localhost:8087/settlement/
- http://localhost:8087/swagger-ui.html
- Mysql
- http://localhost:3306
- root password: rootpassword
- database: fastcampus_pay
- User/PW : mysqluser / mysqlpw
- Kafka UI
- http://localhost:8989
- Axon Server Dashboard
- http://localhost:8024
## Trouble Shooting
### 1. gradle build(docker build) 시, dockerPrepare 단계에서 error 가 발생하는 경우
```
./gradlew --stop
./gradlew docker
```
## Sample Screenshots





================================================
FILE: banking-service/build.gradle
================================================
plugins {
id 'com.palantir.docker' version '0.25.0'
}
ext{
axonVersion = "4.6.0"
}
group = 'com.fastcampuspay.banking'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation 'org.jetbrains:annotations:23.0.0'
implementation project(path: ':common')
// runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
}
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('../Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/BankingApplication.java
================================================
package com.fastcampuspay.banking;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BankingApplication {
public static void main(String[] args) {
SpringApplication.run(BankingApplication.class, args);
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/BankingConfiguration.java
================================================
package com.fastcampuspay.banking;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(BankingConfigurationProperties.class)
public class BankingConfiguration {
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/BankingConfigurationProperties.java
================================================
package com.fastcampuspay.banking;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "banking")
public class BankingConfigurationProperties {
private long transferThreshold = Long.MAX_VALUE;
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/SwaggerConfig.java
================================================
package com.fastcampuspay.banking;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket restAPI() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fastcampuspay.banking"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.build();
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/in/web/FindBankingAccountInfoController.java
================================================
package com.fastcampuspay.banking.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class FindBankingAccountInfoController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@GetMapping(path = "/banking/registered-banking-account/")
ResponseEntity findRegisteredBankingAccountByMemberId(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
@GetMapping(path = "/banking/transfer-money/")
ResponseEntity findTransferMoneyInfoByMemberId(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
@GetMapping(path = "/banking/transfer-money-info/")
ResponseEntity findTransferMoneyInfoByBankingId(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/in/web/RegisterBankingAccountInfoController.java
================================================
package com.fastcampuspay.banking.adapter.in.web;
import com.fastcampuspay.banking.application.port.in.RegisterBankingAccountCommand;
import com.fastcampuspay.banking.application.port.in.RegisterBankingAccountUseCase;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class RegisterBankingAccountInfoController {
private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@PostMapping(path = "/banking/account/")
void registerBankingAccount(@RequestBody RegisterBankingAccountInfoRequest request){
// RegisterMembershipRequest
// name, address, email
RegisterBankingAccountCommand command = RegisterBankingAccountCommand.builder()
.name(request.getName())
.address(request.getAddress())
.email(request.getEmail())
.build();
registerBankingAccountUseCase.registerBankingAccount(command);
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/in/web/RegisterBankingAccountInfoRequest.java
================================================
package com.fastcampuspay.banking.adapter.in.web;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class RegisterBankingAccountInfoRequest {
private String name;
private String address;
private String email;
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/in/web/RequestTransferMoneyController.java
================================================
package com.fastcampuspay.banking.adapter.in.web;
import com.fastcampuspay.banking.domain.BankingAccountRegisterInfo;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class RequestTransferMoneyController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@PostMapping(path = "/banking/transfer-money")
ResponseEntity requestTransferMoneyToBank(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/out/persistence/BankingAccountPersistenceAdapter.java
================================================
package com.fastcampuspay.banking.adapter.out.persistence;
import com.fastcampuspay.banking.application.port.out.RegisterBankingAccountPort;
import com.fastcampuspay.banking.domain.BankingAccountRegisterInfo;
import com.fastcampuspay.common.PersistenceAdapter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@PersistenceAdapter
class BankingAccountPersistenceAdapter implements RegisterBankingAccountPort {
private final SpringDataBankingAccountRegisterInfoRepository bankingAccountRepository;
private final BankingAccountRegisterInfoMapper bankingAccountRegisterInfoMapper;
private Long orZero(Long value){
return value == null ? 0L : value;
}
@Override
public void registerBankingAccount(BankingAccountRegisterInfo.BankingAccountRegisterInfoId bankingAccountRegisterInfoId) {
bankingAccountRepository.save(
new BankingAccountRegisterInfoJpaEntity(
Long.parseLong(bankingAccountRegisterInfoId.getBankingAccountRegisterInfoId())
)
);
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/out/persistence/BankingAccountRegisterInfoJpaEntity.java
================================================
package com.fastcampuspay.banking.adapter.out.persistence;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "banking_account_register_info")
@Data
@AllArgsConstructor
@NoArgsConstructor
class BankingAccountRegisterInfoJpaEntity {
@Id
@GeneratedValue
private Long registerInfoId;
// private String name;
//
// private String address;
//
// private String email;
//
// private boolean isValid;
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/out/persistence/BankingAccountRegisterInfoMapper.java
================================================
package com.fastcampuspay.banking.adapter.out.persistence;
import com.fastcampuspay.banking.domain.BankingAccountRegisterInfo;
import org.springframework.stereotype.Component;
@Component
class BankingAccountRegisterInfoMapper {
BankingAccountRegisterInfo mapToDomainEntity(
BankingAccountRegisterInfoJpaEntity bankingAccountRegisterInfoJpaEntity) {
System.out.println(bankingAccountRegisterInfoJpaEntity.toString());
return BankingAccountRegisterInfo.generateBankingAccountRegisterInfo(
new BankingAccountRegisterInfo.BankingAccountRegisterInfoId(bankingAccountRegisterInfoJpaEntity.getRegisterInfoId()+"")
);
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/adapter/out/persistence/SpringDataBankingAccountRegisterInfoRepository.java
================================================
package com.fastcampuspay.banking.adapter.out.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
interface SpringDataBankingAccountRegisterInfoRepository extends JpaRepository {
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/application/port/in/RegisterBankingAccountCommand.java
================================================
package com.fastcampuspay.banking.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Value;
import javax.validation.constraints.NotNull;
@Value
@Builder
@EqualsAndHashCode(callSuper = false)
public
class RegisterBankingAccountCommand extends SelfValidating {
@NotNull
private final String name;
@NotNull
private final String email;
@NotNull
private final String address;
@NotNull
private final boolean isValid;
public RegisterBankingAccountCommand(String name, String email, String address, boolean isValid) {
this.name = name;
this.email = email;
this.address = address;
this.isValid = isValid;
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/application/port/in/RegisterBankingAccountUseCase.java
================================================
package com.fastcampuspay.banking.application.port.in;
public interface RegisterBankingAccountUseCase {
void registerBankingAccount(RegisterBankingAccountCommand command);
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/application/port/out/RegisterBankingAccountPort.java
================================================
package com.fastcampuspay.banking.application.port.out;
import com.fastcampuspay.banking.domain.BankingAccountRegisterInfo;
public interface RegisterBankingAccountPort {
void registerBankingAccount(
BankingAccountRegisterInfo.BankingAccountRegisterInfoId bankingAccountRegisterInfoId
);
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/application/service/RegisterBankingAccount.java
================================================
package com.fastcampuspay.banking.application.service;
import com.fastcampuspay.banking.application.port.in.RegisterBankingAccountCommand;
import com.fastcampuspay.banking.application.port.in.RegisterBankingAccountUseCase;
import com.fastcampuspay.banking.application.port.out.RegisterBankingAccountPort;
import com.fastcampuspay.banking.domain.BankingAccountRegisterInfo;
import com.fastcampuspay.common.UseCase;
import lombok.RequiredArgsConstructor;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class RegisterBankingAccount implements RegisterBankingAccountUseCase {
private final RegisterBankingAccountPort rport;
@Override
public void registerBankingAccount(RegisterBankingAccountCommand command) {
rport.registerBankingAccount(new BankingAccountRegisterInfo.BankingAccountRegisterInfoId(command.getEmail()));
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/domain/BankingAccountRegisterInfo.java
================================================
package com.fastcampuspay.banking.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class BankingAccountRegisterInfo {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String bankingAccountRegisterInfoId;
// @Getter private final String name;
// @Getter private final String email;
// @Getter private final String address;
// @Getter private final boolean isValid;
public static BankingAccountRegisterInfo generateBankingAccountRegisterInfo(
BankingAccountRegisterInfoId bankingAccountRegisterInfoId) {
return new BankingAccountRegisterInfo(
bankingAccountRegisterInfoId.bankingAccountRegisterInfoId
);
}
@Value
public static class BankingAccountRegisterInfoId {
public BankingAccountRegisterInfoId(String value) {
this.bankingAccountRegisterInfoId = value;
}
String bankingAccountRegisterInfoId ;
}
}
================================================
FILE: banking-service/src/main/java/com/fastcampuspay/banking/domain/TransferMoney.java
================================================
package com.fastcampuspay.banking.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class TransferMoney {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String transferMoneyId;
public static TransferMoney generateTransferMoney(
TransferMoneyId transferMoneyId) {
return new TransferMoney(
transferMoneyId.transferMoneyId
);
}
@Value
public static class TransferMoneyId {
public TransferMoneyId(String value) {
this.transferMoneyId = value;
}
String transferMoneyId ;
}
}
================================================
FILE: build.gradle
================================================
buildscript {
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE"
}
}
plugins {
id 'org.springframework.boot' version '2.5.2'
id 'java'
}
subprojects {
compileJava {
sourceCompatibility = 11
targetCompatibility = 11
}
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
testImplementation 'com.tngtech.archunit:archunit:1.0.1'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
maxHeapSize = "1024m" //원하는 만큼 변경
}
}
bootRun {
enabled = false
}
bootJar {
enabled = false
}
bootBuildImage{
enabled = false
}
================================================
FILE: common/build.gradle
================================================
group 'org.mypay.common'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
implementation 'org.springframework.boot:spring-boot-starter-validation'
}
test {
useJUnitPlatform()
}
================================================
FILE: common/src/main/java/com/fastcampuspay/common/PersistenceAdapter.java
================================================
package com.fastcampuspay.common;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface PersistenceAdapter {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
================================================
FILE: common/src/main/java/com/fastcampuspay/common/SelfValidating.java
================================================
package com.fastcampuspay.common;
import javax.validation.*;
import java.util.Set;
public abstract class SelfValidating {
private Validator validator;
public SelfValidating() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
/**
* Evaluates all Bean Validations on the attributes of this
* instance.
*/
protected void validateSelf() {
Set> violations = validator.validate((T) this);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
}
================================================
FILE: common/src/main/java/com/fastcampuspay/common/UseCase.java
================================================
package com.fastcampuspay.common;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface UseCase {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
================================================
FILE: common/src/main/java/com/fastcampuspay/common/WebAdapter.java
================================================
package com.fastcampuspay.common;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface WebAdapter {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
================================================
FILE: common/src/main/java/com/fastcampuspay/common/events/RegisterAccountEvent.java
================================================
package com.fastcampuspay.common.events;
import java.util.Objects;
public class RegisterAccountEvent {
private final String accountId;
public RegisterAccountEvent(){
this.accountId = "0000";
}
public RegisterAccountEvent(String accountId) {
this.accountId = accountId;
}
public String getAccountId() {
return accountId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RegisterAccountEvent that = (RegisterAccountEvent) o;
return Objects.equals(accountId, that.accountId);
}
@Override
public int hashCode() {
return Objects.hash(accountId);
}
@Override
public String toString() {
return "OrderCreatedEvent{" + "orderId='" + accountId + '\'' + '}';
}
}
================================================
FILE: db/conf.d/my.cnf
================================================
================================================
FILE: db/initdb.d/create_table.sql
================================================
CREATE DATABASE IF NOT EXISTS fastcampus_pay;
USE fastcampus_pay;
-- for Axon Framework (for Mismatching of Axon and Mysql)
create table IF NOT EXISTS dead_letter_entry (
dead_letter_id varchar(255) not null,
cause_message varchar(255),
cause_type varchar(255),
diagnostics longblob,
enqueued_at datetime not null,
`index` bigint not null,
last_touched datetime,
aggregate_identifier varchar(255),
event_identifier varchar(255) not null,
message_type varchar(255) not null,
meta_data longblob, payload longblob not null,
payload_revision varchar(255),
payload_type varchar(255) not null,
sequence_number bigint,
time_stamp varchar(255) not null,
token longblob, token_type varchar(255),
type varchar(255),
processing_group varchar(255) not null,
processing_started datetime,
sequence_identifier varchar(255) not null,
primary key (dead_letter_id)
) engine=InnoDB
================================================
FILE: db/initdb.d/load_data.sql
================================================
================================================
FILE: docker-compose.yaml
================================================
version: '3'
services:
zookeeper:
image: 'arm64v8/zookeeper:3.8'
networks:
- fastcampuspay_network
ports:
- '2181:2181'
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
- ZOO_TLS_CLIENT_AUTH=none
- ZOO_TLS_QUORUM_CLIENT_AUTH=none
kafka:
image: 'bitnami/kafka:3.4.0'
networks:
- fastcampuspay_network
ports:
- '9092:9092'
environment:
- KAFKA_BROKER_ID=1
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_LISTENERS=LC://kafka:29092,LX://kafka:9092
- KAFKA_CFG_ADVERTISED_LISTENERS=LC://kafka:29092,LX://${DOCKER_HOST_IP:-localhost}:9092
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=LC:PLAINTEXT,LX:PLAINTEXT
- KAFKA_CFG_INTER_BROKER_LISTENER_NAME=LC
depends_on:
- zookeeper
kafka-ui:
image: provectuslabs/kafka-ui
container_name: kafka-ui
networks:
- fastcampuspay_network
ports:
- "8989:8080"
restart: always
depends_on:
- kafka
- zookeeper
environment:
- KAFKA_CLUSTERS_0_NAME=local
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:29092
- KAFKA_CLUSTERS_0_ZOOKEEPER=zookeeper:2181
mysql:
image: mysql:8.0
networks:
- fastcampuspay_network
volumes:
- ./db/conf.d:/etc/mysql/conf.d
- ./db/data:/var/lib/mysql
- ./db/initdb.d:/docker-entrypoint-initdb.d
env_file: .env
ports:
- "3306:3306"
environment:
- TZ=Asia/Seoul
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_USER=mysqluser
- MYSQL_PASSWORD=mysqlpw
axon-server:
container_name: axon-server
image: axoniq/axonserver:4.6.3-jdk-11-dev
networks:
- fastcampuspay_network
ports:
- "8024:8024"
- "8124:8124"
volumes:
- axonserver-data:/axonserver/data
- axonserver-events:/axonserver/events
- axonserver-config:/axonserver/config:ro
membership-service:
image: fastcampus-pay-membership-service:0.0.1-SNAPSHOT
networks:
- fastcampuspay_network
ports:
- "8081:8080"
depends_on:
- axon-server
- mysql
environment:
- AXON_AXONSERVER_SERVERS=axon-server:8124
- AXON_SERIALIZER_EVENTS=jackson
- AXON_SERIALIZER_MESSAGES=jackson
- AXON_SERIALIZER_GENERAL=xstream
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fastcampus_pay?useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=mysqluser
- SPRING_DATASOURCE_PASSWORD=mysqlpw
- SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQL5InnoDBDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
banking-service:
image: fastcampus-pay-banking-service:0.0.1-SNAPSHOT
networks:
- fastcampuspay_network
ports:
- "8082:8080"
depends_on:
- axon-server
- mysql
environment:
- AXON_AXONSERVER_SERVERS=axon-server:8124
- AXON_SERIALIZER_EVENTS=jackson
- AXON_SERIALIZER_MESSAGES=jackson
- AXON_SERIALIZER_GENERAL=xstream
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fastcampus_pay?useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=mysqluser
- SPRING_DATASOURCE_PASSWORD=mysqlpw
- SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQL5InnoDBDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
money-service:
image: fastcampus-pay-money-service:0.0.1-SNAPSHOT
networks:
- fastcampuspay_network
ports:
- "8083:8080"
depends_on:
- axon-server
- mysql
environment:
- AXON_AXONSERVER_SERVERS=axon-server:8124
- AXON_SERIALIZER_EVENTS=jackson
- AXON_SERIALIZER_MESSAGES=jackson
- AXON_SERIALIZER_GENERAL=xstream
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fastcampus_pay?useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=mysqluser
- SPRING_DATASOURCE_PASSWORD=mysqlpw
- SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQL5InnoDBDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
money-local-service:
image: fastcampus-pay-money-local-service:0.0.1-SNAPSHOT
networks:
- fastcampuspay_network
ports:
- "8084:8080"
depends_on:
- axon-server
- mysql
environment:
- AXON_AXONSERVER_SERVERS=axon-server:8124
- AXON_SERIALIZER_EVENTS=jackson
- AXON_SERIALIZER_MESSAGES=jackson
- AXON_SERIALIZER_GENERAL=xstream
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fastcampus_pay?useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=mysqluser
- SPRING_DATASOURCE_PASSWORD=mysqlpw
- SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQL5InnoDBDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
remittance-service:
image: fastcampus-pay-remittance-service:0.0.1-SNAPSHOT
networks:
- fastcampuspay_network
ports:
- "8085:8080"
depends_on:
- axon-server
- mysql
environment:
- AXON_AXONSERVER_SERVERS=axon-server:8124
- AXON_SERIALIZER_EVENTS=jackson
- AXON_SERIALIZER_MESSAGES=jackson
- AXON_SERIALIZER_GENERAL=xstream
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fastcampus_pay?useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=mysqluser
- SPRING_DATASOURCE_PASSWORD=mysqlpw
- SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQL5InnoDBDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
payment-service:
image: fastcampus-pay-payment-service:0.0.1-SNAPSHOT
networks:
- fastcampuspay_network
ports:
- "8086:8080"
depends_on:
- axon-server
- mysql
environment:
- AXON_AXONSERVER_SERVERS=axon-server:8124
- AXON_SERIALIZER_EVENTS=jackson
- AXON_SERIALIZER_MESSAGES=jackson
- AXON_SERIALIZER_GENERAL=xstream
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fastcampus_pay?useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=mysqluser
- SPRING_DATASOURCE_PASSWORD=mysqlpw
- SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQL5InnoDBDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
settlement-service:
image: fastcampus-pay-settlement-service:0.0.1-SNAPSHOT
networks:
- fastcampuspay_network
ports:
- "8087:8080"
depends_on:
- axon-server
- mysql
environment:
- AXON_AXONSERVER_SERVERS=axon-server:8124
- AXON_SERIALIZER_EVENTS=jackson
- AXON_SERIALIZER_MESSAGES=jackson
- AXON_SERIALIZER_GENERAL=xstream
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fastcampus_pay?useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=mysqluser
- SPRING_DATASOURCE_PASSWORD=mysqlpw
- SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQL5InnoDBDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
volumes:
axonserver-data:
driver: local
driver_opts:
o: bind
type: none
device: ${PWD}/axon-server-se/data
axonserver-events:
driver: local
driver_opts:
o: bind
type: none
device: ${PWD}/axon-server-se/events
axonserver-config:
driver: local
driver_opts:
o: bind
type: none
device: ${PWD}/axon-server-se/config
networks:
fastcampuspay_network:
driver: bridge
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: gradle.properties
================================================
org.gradle.jvmargs=-Xmx2g
org.gradle.caching=true
org.gradle.configureondemand=true
org.gradle.parallel=false
================================================
FILE: gradlew
================================================
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
================================================
FILE: gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: membership-service/build.gradle
================================================
plugins {
id 'com.palantir.docker' version '0.25.0'
}
ext{
axonVersion = "4.6.0"
}
group = 'com.fastcampuspay.membership'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation project(path: ':common')
implementation 'org.jetbrains:annotations:23.0.0'
// runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
}
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('../Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/MembershipApplication.java
================================================
package com.fastcampuspay.membership;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MembershipApplication {
public static void main(String[] args) {
SpringApplication.run(MembershipApplication.class, args);
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/MembershipConfiguration.java
================================================
package com.fastcampuspay.membership;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(MembershipConfigurationProperties.class)
public class MembershipConfiguration {
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/MembershipConfigurationProperties.java
================================================
package com.fastcampuspay.membership;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "membership")
public class MembershipConfigurationProperties {
private long transferThreshold = Long.MAX_VALUE;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/SwaggerConfig.java
================================================
package com.fastcampuspay.membership;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket restAPI() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fastcampuspay.membership"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.build();
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/in/web/FindMembershipController.java
================================================
package com.fastcampuspay.membership.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import com.fastcampuspay.membership.application.port.in.FindMembershipCommand;
import com.fastcampuspay.membership.application.port.in.FindMembershipUseCase;
import com.fastcampuspay.membership.domain.Membership;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class FindMembershipController {
private final FindMembershipUseCase findMembershipUseCase;
@GetMapping(path = "/membership/{membershipId}")
ResponseEntity findMembershipByMemberId(@PathVariable String membershipId){
FindMembershipCommand command = FindMembershipCommand.builder()
.membershipId(membershipId)
.build();
return ResponseEntity.ok(findMembershipUseCase.findMembership(command));
}
@GetMapping(path = "/membership/axon/{membershipId}")
ResponseEntity findAxonMembershipByMemberId(@PathVariable String membershipId){
FindMembershipCommand command = FindMembershipCommand.builder()
.membershipId(membershipId)
.build();
return ResponseEntity.ok(findMembershipUseCase.findAxonMembership(command));
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/in/web/FindMembershipRequest.java
================================================
package com.fastcampuspay.membership.adapter.in.web;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class FindMembershipRequest {
private String membershipId;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/in/web/LoginAuthMembershipController.java
================================================
package com.fastcampuspay.membership.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class LoginAuthMembershipController {
@PostMapping(path = "/membership/login/")
ResponseEntity loginByMembershipIdPw(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
@PostMapping(path = "/membership/auth/")
ResponseEntity authByToken(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/in/web/RegisterMembershipController.java
================================================
package com.fastcampuspay.membership.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import com.fastcampuspay.membership.application.port.in.RegisterMembershipCommand;
import com.fastcampuspay.membership.application.port.in.RegisterMembershipUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class RegisterMembershipController {
private final RegisterMembershipUseCase registerMembershipUseCase;
@PostMapping(path = "/membership/register/")
void registerMembership(@RequestBody RegisterMembershipRequest request){
// RegisterMembershipRequest
// name, address, email
RegisterMembershipCommand command = RegisterMembershipCommand.builder()
.name(request.getName())
.address(request.getAddress())
.email(request.getEmail())
.build();
registerMembershipUseCase.registerMembership(command);
}
@PostMapping(path = "/membership/axon-register/")
void registerAxonMembership(@RequestBody RegisterMembershipRequest request){
RegisterMembershipCommand command = RegisterMembershipCommand.builder()
.name(request.getName())
.address(request.getAddress())
.email(request.getEmail())
.build();
registerMembershipUseCase.registerAxonMembership(command);
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/in/web/RegisterMembershipRequest.java
================================================
package com.fastcampuspay.membership.adapter.in.web;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class RegisterMembershipRequest {
private String name;
private String address;
private String email;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/in/web/UpdateMembershipController.java
================================================
package com.fastcampuspay.membership.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import com.fastcampuspay.membership.application.port.in.UpdateMembershipCommand;
import com.fastcampuspay.membership.application.port.in.UpdateMembershipUseCase;
import com.fastcampuspay.membership.domain.Membership;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class UpdateMembershipController {
private final UpdateMembershipUseCase updateMembershipUseCase;
@PutMapping(path = "/membership/update")
ResponseEntity updateMembershipByMemberId(@RequestBody UpdateMembershipRequest membershipToBeUpdated){
// updateMembership
UpdateMembershipCommand command = UpdateMembershipCommand.builder()
.membershipId(membershipToBeUpdated.getMembershipId())
.name(membershipToBeUpdated.getName())
.address(membershipToBeUpdated.getAddress())
.email(membershipToBeUpdated.getEmail())
.isValid(membershipToBeUpdated.isValid())
.build();
return ResponseEntity.ok(updateMembershipUseCase.updateMembership(command));
}
@PutMapping(path = "/membership/axon-update")
ResponseEntity updateAxonMembershipByMemberId(@RequestBody UpdateMembershipRequest membershipToBeUpdated){
System.out.println("axon update controller");
// updateMembership
UpdateMembershipCommand command = UpdateMembershipCommand.builder()
.membershipId(membershipToBeUpdated.getMembershipId())
.name(membershipToBeUpdated.getName())
.address(membershipToBeUpdated.getAddress())
.email(membershipToBeUpdated.getEmail())
.isValid(membershipToBeUpdated.isValid())
.build();
return ResponseEntity.ok(updateMembershipUseCase.updateAxonMembership(command));
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/in/web/UpdateMembershipRequest.java
================================================
package com.fastcampuspay.membership.adapter.in.web;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UpdateMembershipRequest {
private String membershipId;
private String name;
private String address;
private String email;
private boolean isValid;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/out/persistence/MembershipJpaEntity.java
================================================
package com.fastcampuspay.membership.adapter.out.persistence;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "membership")
@Data
@AllArgsConstructor
@NoArgsConstructor
class MembershipJpaEntity {
@Id
@GeneratedValue
private Long membershipId;
private String name;
private String address;
private String email;
private boolean isValid;
private String aggregateIdentifier;
public MembershipJpaEntity(String name, String address, String email, boolean isValid, String aggregateIdentifier) {
this.name = name;
this.address = address;
this.email = email;
this.isValid = isValid;
this.aggregateIdentifier = aggregateIdentifier;
}
@Override
public String toString() {
return "MembershipJpaEntity{" +
"membershipId=" + membershipId +
", name='" + name + '\'' +
", address='" + address + '\'' +
", email='" + email + '\'' +
", isValid=" + isValid +
", aggregateIdentifier='" + aggregateIdentifier + '\'' +
'}';
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/out/persistence/MembershipMapper.java
================================================
package com.fastcampuspay.membership.adapter.out.persistence;
import com.fastcampuspay.membership.domain.Membership;
import org.springframework.stereotype.Component;
@Component
class MembershipMapper {
Membership mapToDomainEntity(
MembershipJpaEntity membership) {
System.out.println(membership.toString());
return Membership.generateMember(
new Membership.MembershipId(membership.getMembershipId()+""),
new Membership.MembershipName(membership.getName()),
new Membership.MembershipEmail(membership.getEmail()),
new Membership.MembershipAddress(membership.getAddress()),
new Membership.MembershipIsValid(membership.isValid()),
new Membership.MembershipAggregateIdentifier(membership.getAggregateIdentifier())
);
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/out/persistence/MembershipPersistenceAdapter.java
================================================
package com.fastcampuspay.membership.adapter.out.persistence;
import com.fastcampuspay.common.PersistenceAdapter;
import com.fastcampuspay.membership.application.port.out.FindMembershipPort;
import com.fastcampuspay.membership.application.port.out.RegisterMembershipPort;
import com.fastcampuspay.membership.application.port.out.UpdateMembershipPort;
import com.fastcampuspay.membership.domain.Membership;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@PersistenceAdapter
class MembershipPersistenceAdapter implements RegisterMembershipPort, FindMembershipPort, UpdateMembershipPort {
private final SpringDataMembershipRepository membershipRepository;
private final MembershipMapper membershipMapper;
@Override
public void createMembership(Membership.MembershipName membershipName
, Membership.MembershipEmail membershipEmail
, Membership.MembershipAddress membershipAddress
, Membership.MembershipIsValid membershipIsValid
, Membership.MembershipAggregateIdentifier membershipAggregateIdentifier
) {
membershipRepository.save(
new MembershipJpaEntity(
membershipName.getNameValue(),
membershipEmail.getEmailValue(),
membershipAddress.getAddressValue(),
membershipIsValid.isValidValue(),
membershipAggregateIdentifier.getAggregateIdentifier()
)
);
}
@Override
public Membership findMembership(Membership.MembershipId membershipId) {
return membershipMapper.mapToDomainEntity(
membershipRepository.getById(Long.parseLong(membershipId.getMembershipId()))
);
}
@Override
public Membership updateMembership(Membership.MembershipId membershipId, Membership.MembershipName membershipName, Membership.MembershipEmail membershipEmail, Membership.MembershipAddress membershipAddress, Membership.MembershipIsValid membershipIsValid) {
// update membership Info
MembershipJpaEntity membershipJpaEntity = membershipRepository.getById(Long.parseLong(membershipId.getMembershipId()));
membershipJpaEntity.setName(membershipName.getNameValue());
membershipJpaEntity.setEmail(membershipEmail.getEmailValue());
membershipJpaEntity.setAddress(membershipAddress.getAddressValue());
membershipJpaEntity.setValid(membershipIsValid.isValidValue());
// save
MembershipJpaEntity updatedMembership = membershipRepository.save(membershipJpaEntity);
// return
return membershipMapper.mapToDomainEntity(updatedMembership);
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/adapter/out/persistence/SpringDataMembershipRepository.java
================================================
package com.fastcampuspay.membership.adapter.out.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
interface SpringDataMembershipRepository extends JpaRepository {
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/FindMembershipCommand.java
================================================
package com.fastcampuspay.membership.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
public
class FindMembershipCommand extends SelfValidating {
private final String membershipId;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/FindMembershipUseCase.java
================================================
package com.fastcampuspay.membership.application.port.in;
import com.fastcampuspay.membership.domain.Membership;
public interface FindMembershipUseCase {
Membership findMembership(FindMembershipCommand command);
Membership findAxonMembership(FindMembershipCommand command);
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/RegisterMembershipCommand.java
================================================
package com.fastcampuspay.membership.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
@Builder
@Data
@EqualsAndHashCode(callSuper = false)
public
class RegisterMembershipCommand extends SelfValidating {
@NotNull
private final String name;
@NotNull
private final String email;
@NotNull
private final String address;
@NotNull
private final boolean isValid;
public RegisterMembershipCommand(String name, String email, String address, boolean isValid) {
this.name = name;
this.email = email;
this.address = address;
this.isValid = isValid;
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/RegisterMembershipUseCase.java
================================================
package com.fastcampuspay.membership.application.port.in;
public interface RegisterMembershipUseCase {
void registerMembership(RegisterMembershipCommand command);
void registerAxonMembership(RegisterMembershipCommand command);
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/UpdateMembershipCommand.java
================================================
package com.fastcampuspay.membership.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.axonframework.modelling.command.TargetAggregateIdentifier;
import javax.validation.constraints.NotNull;
@Builder
@Data
@EqualsAndHashCode(callSuper = false)
public class UpdateMembershipCommand extends SelfValidating {
@NotNull
@TargetAggregateIdentifier
private String membershipId;
private String name;
private String address;
private String email;
private boolean isValid;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/UpdateMembershipEventCommand.java
================================================
package com.fastcampuspay.membership.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.*;
import org.axonframework.modelling.command.TargetAggregateIdentifier;
import javax.validation.constraints.NotNull;
@Builder
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
public class UpdateMembershipEventCommand extends SelfValidating {
@NotNull
@TargetAggregateIdentifier
private String aggregateIdentifier;
private String name;
private String address;
private String email;
private boolean isValid;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/UpdateMembershipUseCase.java
================================================
package com.fastcampuspay.membership.application.port.in;
import com.fastcampuspay.membership.domain.Membership;
public interface UpdateMembershipUseCase {
Membership updateMembership(UpdateMembershipCommand command);
Membership updateAxonMembership(UpdateMembershipCommand command);
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/in/aggregate/MembershipAggregate.java
================================================
package com.fastcampuspay.membership.application.port.in.aggregate;
import com.fastcampuspay.membership.application.port.in.RegisterMembershipCommand;
import com.fastcampuspay.membership.application.port.in.UpdateMembershipCommand;
import com.fastcampuspay.membership.application.port.in.UpdateMembershipEventCommand;
import com.fastcampuspay.membership.application.saga.MembershipCreateEvent;
import com.fastcampuspay.membership.application.saga.MembershipUpdateEvent;
import lombok.Data;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.eventsourcing.EventSourcingHandler;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.spring.stereotype.Aggregate;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
@Aggregate()
@Data
public class MembershipAggregate {
@AggregateIdentifier
private String id;
private String name;
private String email;
private String address;
@CommandHandler
public MembershipAggregate(@NotNull RegisterMembershipCommand command) {
System.out.println("RegisterMembershipCommand Handler");
// store event
apply(new MembershipCreateEvent(command.getName(), command.getEmail(), command.getAddress()));
}
@CommandHandler
public String handle(@NotNull UpdateMembershipEventCommand command) {
System.out.println("UpdateMembershipEventCommand Handler");
id = command.getAggregateIdentifier();
// store event
apply(new MembershipUpdateEvent(id, command.getName(), command.getEmail(), command.getAddress()));
return id;
}
@CommandHandler
public String handle (@NotNull UpdateMembershipCommand command) {
System.out.println("UpdateMembershipCommand Handler");
String aggregateIdentifier = command.getMembershipId();
id = aggregateIdentifier;
// store event
apply(new MembershipUpdateEvent(aggregateIdentifier, command.getName(), command.getEmail(), command.getAddress()));
return aggregateIdentifier;
}
@EventSourcingHandler
public void on(MembershipCreateEvent event) {
System.out.println("MembershipCreateEvent Sourcing Handler");
id = UUID.randomUUID().toString();
name = event.getName() ;
email = event.getEmail();
address = event.getAddress();
}
@EventSourcingHandler
public void on(MembershipUpdateEvent event) {
System.out.println("MembershipUpdateEvent Sourcing Handler");
name = event.getName() ;
email = event.getEmail();
address = event.getAddress();
}
public MembershipAggregate() {
// Required by Axon to construct an empty instance to initiate Event Sourcing.
}
@Override
public String toString() {
return "MembershipAggregate{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", email='" + email + '\'' +
", address='" + address + '\'' +
'}';
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/out/FindMembershipPort.java
================================================
package com.fastcampuspay.membership.application.port.out;
import com.fastcampuspay.membership.domain.Membership;
public interface FindMembershipPort {
Membership findMembership(
Membership.MembershipId membershipId
);
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/out/RegisterMembershipPort.java
================================================
package com.fastcampuspay.membership.application.port.out;
import com.fastcampuspay.membership.domain.Membership;
public interface RegisterMembershipPort {
void createMembership(
Membership.MembershipName membershipName
, Membership.MembershipEmail membershipEmail
, Membership.MembershipAddress membershipAddress
, Membership.MembershipIsValid membershipIsValid
, Membership.MembershipAggregateIdentifier membershipAggregateIdentifier
);
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/out/UpdateMembershipPort.java
================================================
package com.fastcampuspay.membership.application.port.out;
import com.fastcampuspay.membership.domain.Membership;
public interface UpdateMembershipPort {
Membership updateMembership(
Membership.MembershipId membershipId
, Membership.MembershipName membershipName
, Membership.MembershipEmail membershipEmail
, Membership.MembershipAddress membershipAddress
, Membership.MembershipIsValid membershipIsValid
);
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/out/query/FindMembershipQuery.java
================================================
package com.fastcampuspay.membership.application.port.out.query;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class FindMembershipQuery {
String membershipId;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/port/out/query/MembershipQueryHandler.java
================================================
package com.fastcampuspay.membership.application.port.out.query;
import com.fastcampuspay.membership.application.port.out.FindMembershipPort;
import com.fastcampuspay.membership.domain.Membership;
import lombok.RequiredArgsConstructor;
import org.axonframework.queryhandling.QueryHandler;
import org.springframework.stereotype.Component;
@RequiredArgsConstructor
@Component
public class MembershipQueryHandler{
private final FindMembershipPort fport;
@QueryHandler
public Membership handle(FindMembershipQuery query) {
System.out.println("MembershipQueryHandler Handler");
// Retrieve the event sourcing repository
// EventSourcingRepository repository = EventSourcingRepository.builder(MembershipAggregate.class).eventStore(eventStore).build();
// MembershipAggregate user = repository.load(query.getMembershipId()).getWrappedAggregate().getAggregateRoot();
// System.out.println(user.toString());
return fport.findMembership(new Membership.MembershipId(query.getMembershipId()));
// return Membership.generateMember(
// new Membership.MembershipId(user.getId()+""),
// new Membership.MembershipName(user.getName()),
// new Membership.MembershipEmail(user.getEmail()),
// new Membership.MembershipAddress(user.getAddress()),
// new Membership.MembershipIsValid(true)
// );
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/MembershipCreateEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class MembershipCreateEvent {
private String name;
private String email;
private String address;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/MembershipUpdateEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class MembershipUpdateEvent {
private String membershipId;
private String name;
private String email;
private String address;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/Order.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.Data;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.spring.stereotype.Aggregate;
@Data
@Aggregate()
public class Order {
@AggregateIdentifier
private String orderId;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/OrderCancelledEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class OrderCancelledEvent {
private String orderId;
private String paymentId;
private String name;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/OrderConfirmedEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class OrderConfirmedEvent {
private String orderId;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/OrderCreatedEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
public class OrderCreatedEvent {
private String orderId;
private String customerName;
public OrderCreatedEvent(String orderId, String customerName) {
this.orderId = orderId;
this.customerName = customerName;
}
public String getOrderId() {
return orderId;
}
public String getCustomerName() {
return customerName;
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/OrderPlacedEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.Data;
@Data
public class OrderPlacedEvent {
private String orderId;
private String name;
public OrderPlacedEvent(){
orderId = "default-123";
}
public OrderPlacedEvent(String orderId){
this.orderId = orderId;
}
public OrderPlacedEvent(String orderId, String name){
this.orderId = orderId;
this.name = name;
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/OrderSaga.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.axonframework.commandhandling.gateway.CommandGateway;
import org.axonframework.eventhandling.EventBus;
import org.axonframework.modelling.saga.SagaEventHandler;
import org.axonframework.modelling.saga.SagaLifecycle;
import org.axonframework.modelling.saga.StartSaga;
import org.axonframework.spring.stereotype.Saga;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.UUID;
@Saga
@Getter
@NoArgsConstructor
public class OrderSaga {
private String orderId;
private String paymentId;
private double amount;
@NonNull
private transient EventBus eventBus;
@NonNull
private transient CommandGateway commandGateway;
@Autowired
public void setEventBus(EventBus eventBus) {
this.eventBus = eventBus;
}
@Autowired
public void setCommandGateway(CommandGateway commandGateway) {
this.commandGateway = commandGateway;
}
@StartSaga
@SagaEventHandler(associationProperty = "orderId")
public void handle(OrderPlacedEvent event) {
SagaLifecycle.associateWith("orderId", event.getOrderId());
System.out.println("Order placed");
orderId = event.getOrderId();
paymentId = UUID.randomUUID().toString();
amount = 100.0; // hardcoded for simplicity
PaymentRequestedCommand command = new PaymentRequestedCommand(paymentId, orderId, amount);
commandGateway.send(command).whenComplete((Object result, Throwable throwable) -> {
// if (throwable == null) {
System.out.println("Payment requested");
this.orderId = "finished";
SagaLifecycle.associateWith("paymentId", paymentId);
// eventBus.publish(GenericEventMessage.asEventMessage(new PaymentCompletedEvent("1345", event.getOrderId())));
// }
System.out.println("Payment failed");
SagaLifecycle.end();
});
}
@SagaEventHandler(associationProperty = "orderId")
public void handle(OrderConfirmedEvent event) {
System.out.println("Payment completed");
SagaLifecycle.end();
// // OrderConfirmedEvent orderConfirmedEvent = new OrderConfirmedEvent(orderId);
// if (this.orderId != null) {
// System.out.println("Payment completed");
// // SagaLifecycle.associateWith("orderId", orderId);
// // eventBus.publish(orderConfirmedEvent);
// } else{
// System.out.println("Order Cancelled");
// // commandGateway.send(new OrderCancelledEvent(event.getOrderId()));
// }
// System.out.println("Payment completed");
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/Payment.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.Data;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.spring.stereotype.Aggregate;
@Data
@Aggregate()
public class Payment {
private String orderId;
@AggregateIdentifier
private String paymentId;
// getters and setters
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/PaymentCancelledEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class PaymentCancelledEvent {
private String orderId;
private String paymentId;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/PaymentCompletedEvent.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class PaymentCompletedEvent {
private String paymentId;
private String orderId;
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/saga/PaymentRequestedCommand.java
================================================
package com.fastcampuspay.membership.application.saga;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class PaymentRequestedCommand {
private String paymentId;
private String orderId;
private double amount;
// getters and setters
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/service/FindMembership.java
================================================
package com.fastcampuspay.membership.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.membership.application.port.in.FindMembershipCommand;
import com.fastcampuspay.membership.application.port.in.FindMembershipUseCase;
import com.fastcampuspay.membership.application.port.out.FindMembershipPort;
import com.fastcampuspay.membership.application.port.out.query.FindMembershipQuery;
import com.fastcampuspay.membership.domain.Membership;
import lombok.RequiredArgsConstructor;
import org.axonframework.messaging.responsetypes.ResponseTypes;
import org.axonframework.queryhandling.QueryGateway;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class FindMembership implements FindMembershipUseCase {
private final FindMembershipPort fport;
private final QueryGateway queryGateway;
@Override
public Membership findMembership(FindMembershipCommand command) {
return fport.findMembership(new Membership.MembershipId(command.getMembershipId()));
}
@Override
public Membership findAxonMembership(FindMembershipCommand command) {
FindMembershipQuery getQuery = new FindMembershipQuery(command.getMembershipId());
queryGateway.query(getQuery, ResponseTypes.instanceOf(Membership.class))
.whenComplete((Object result, Throwable throwable) -> {
if (throwable == null) {
System.out.println(result.toString());
}
else {
System.out.println("error : " + throwable.getMessage());
}
});
return null;
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/service/RegisterMembership.java
================================================
package com.fastcampuspay.membership.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.membership.application.port.in.RegisterMembershipCommand;
import com.fastcampuspay.membership.application.port.in.RegisterMembershipUseCase;
import com.fastcampuspay.membership.application.port.out.RegisterMembershipPort;
import com.fastcampuspay.membership.domain.Membership;
import lombok.RequiredArgsConstructor;
import org.axonframework.commandhandling.gateway.CommandGateway;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class RegisterMembership implements RegisterMembershipUseCase {
private final RegisterMembershipPort rport;
private final CommandGateway commandGateway;
@Override
public void registerMembership(RegisterMembershipCommand command) {
rport.createMembership(
new Membership.MembershipName(command.getName()),
new Membership.MembershipEmail(command.getEmail()),
new Membership.MembershipAddress(command.getAddress()),
new Membership.MembershipIsValid(command.isValid()),
new Membership.MembershipAggregateIdentifier("default")
);
}
@Override
public void registerAxonMembership(RegisterMembershipCommand command) {
commandGateway.send(command)
.whenComplete((Object result, Throwable throwable) -> {
if (throwable == null) {
System.out.println("Aggregate ID:" + result.toString());
rport.createMembership(
new Membership.MembershipName(command.getName()),
new Membership.MembershipEmail(command.getEmail()),
new Membership.MembershipAddress(command.getAddress()),
new Membership.MembershipIsValid(command.isValid()),
new Membership.MembershipAggregateIdentifier(result.toString())
);
}
else{
System.out.println("error : " + throwable.getMessage());
}
});
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/application/service/UpdateMembership.java
================================================
package com.fastcampuspay.membership.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.membership.application.port.in.UpdateMembershipCommand;
import com.fastcampuspay.membership.application.port.in.UpdateMembershipEventCommand;
import com.fastcampuspay.membership.application.port.in.UpdateMembershipUseCase;
import com.fastcampuspay.membership.application.port.out.FindMembershipPort;
import com.fastcampuspay.membership.application.port.out.UpdateMembershipPort;
import com.fastcampuspay.membership.domain.Membership;
import lombok.RequiredArgsConstructor;
import org.axonframework.commandhandling.gateway.CommandGateway;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class UpdateMembership implements UpdateMembershipUseCase {
private final UpdateMembershipPort uport;
private final FindMembershipPort fport;
private final CommandGateway commandGateway;
@Override
public Membership updateMembership(UpdateMembershipCommand command) {
return uport.updateMembership(
new Membership.MembershipId(command.getMembershipId()),
new Membership.MembershipName(command.getName()),
new Membership.MembershipEmail(command.getEmail()),
new Membership.MembershipAddress(command.getAddress()),
new Membership.MembershipIsValid(command.isValid())
);
}
@Override
public Membership updateAxonMembership(UpdateMembershipCommand command) {
System.out.println("update axon membership");
Membership membership = fport.findMembership(new Membership.MembershipId(command.getMembershipId()));
UpdateMembershipEventCommand eventCommand = UpdateMembershipEventCommand.builder()
.aggregateIdentifier(membership.getAggregateIdentifier())
.name(command.getName())
.email(command.getEmail())
.address(command.getAddress())
.isValid(command.isValid())
.build();
commandGateway.send(eventCommand).whenComplete((Object result, Throwable throwable) -> {
if (throwable == null) {
System.out.println("Aggregate ID:" + result);
} else {
System.out.println("error : " + throwable.getMessage());
}
});
this.updateMembership(command);
return null;
}
}
================================================
FILE: membership-service/src/main/java/com/fastcampuspay/membership/domain/Membership.java
================================================
package com.fastcampuspay.membership.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Membership {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String membershipId;
@Getter private final String name;
@Getter private final String email;
@Getter private final String address;
@Getter private final boolean isValid;
@Getter private final String aggregateIdentifier;
public static Membership generateMember(
MembershipId membershipId, MembershipName membershipName, MembershipEmail membershipEmail, MembershipAddress membershipAddress, MembershipIsValid membershipIsValid,
MembershipAggregateIdentifier membershipAggregateIdentifier) {
return new Membership(
membershipId.membershipId,
membershipName.nameValue,
membershipEmail.emailValue,
membershipAddress.addressValue,
membershipIsValid.isValidValue,
membershipAggregateIdentifier.aggregateIdentifier
);
}
@Value
public static class MembershipId {
public MembershipId(String value) {
this.membershipId = value;
}
String membershipId ;
}
@Value
public static class MembershipName {
public MembershipName(String value) {
this.nameValue = value;
}
String nameValue;
}
@Value
public static class MembershipEmail {
public MembershipEmail(String value) {
this.emailValue = value;
}
String emailValue;
}
@Value
public static class MembershipAddress {
public MembershipAddress(String value) {
this.addressValue = value;
}
String addressValue;
}
@Value
public static class MembershipIsValid {
public MembershipIsValid(boolean value) {
this.isValidValue = value;
}
boolean isValidValue;
}
@Value
public static class MembershipAggregateIdentifier {
public MembershipAggregateIdentifier(String value) {
this.aggregateIdentifier = value;
}
String aggregateIdentifier;
}
}
================================================
FILE: money-local-service/build.gradle
================================================
plugins {
id 'com.palantir.docker' version '0.25.0'
}
ext{
axonVersion = "4.6.0"
}
group = 'com.fastcampuspay.moneylocal'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation 'org.jetbrains:annotations:23.0.0'
implementation project(path: ':common')
// runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
}
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('../Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/MoneyLocalApplication.java
================================================
package com.fastcampuspay.moneylocal;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MoneyLocalApplication {
public static void main(String[] args) {
SpringApplication.run(MoneyLocalApplication.class, args);
}
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/MoneyLocalConfiguration.java
================================================
package com.fastcampuspay.moneylocal;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(MoneyLocalConfigurationProperties.class)
public class MoneyLocalConfiguration {
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/MoneyLocalConfigurationProperties.java
================================================
package com.fastcampuspay.moneylocal;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "banking")
public class MoneyLocalConfigurationProperties {
private long transferThreshold = Long.MAX_VALUE;
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/SwaggerConfig.java
================================================
package com.fastcampuspay.moneylocal;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket restAPI() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fastcampuspay.money"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.build();
}
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/adapter/in/web/CalculateLocalMoneyController.java
================================================
package com.fastcampuspay.moneylocal.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
// CQRS Controller
@WebAdapter
@RestController
@RequiredArgsConstructor
class CalculateLocalMoneyController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@GetMapping(path = "/money-local/calculate-money-sum")
ResponseEntity calculateMoneySumByLocal(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
// TODO
// - MembershipUpdate EventHandler (EventHandler)
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/adapter/out/persistence/LocalMoneyJpaEntity.java
================================================
package com.fastcampuspay.moneylocal.adapter.out.persistence;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "local_money")
@Data
@AllArgsConstructor
@NoArgsConstructor
class LocalMoneyJpaEntity {
@Id
@GeneratedValue
private Long localMoneyId;
// private String name;
//
// private String address;
//
// private String email;
//
// private boolean isValid;
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/adapter/out/persistence/LocalMoneyMapper.java
================================================
package com.fastcampuspay.moneylocal.adapter.out.persistence;
import com.fastcampuspay.moneylocal.domain.MemberMoney;
import org.springframework.stereotype.Component;
@Component
class LocalMoneyMapper {
MemberMoney mapToDomainEntity(
LocalMoneyJpaEntity rechargeMoneyJpaEntity) {
System.out.println(rechargeMoneyJpaEntity.toString());
return MemberMoney.generateMemberMoney(
new MemberMoney.MemberMoneyId(rechargeMoneyJpaEntity.getLocalMoneyId()+"")
);
}
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/adapter/out/persistence/LocalMoneyPersistenceAdapter.java
================================================
package com.fastcampuspay.moneylocal.adapter.out.persistence;
import com.fastcampuspay.common.PersistenceAdapter;
import com.fastcampuspay.moneylocal.application.port.out.RechargeMoneyPort;
import com.fastcampuspay.moneylocal.domain.MemberMoney;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@PersistenceAdapter
class LocalMoneyPersistenceAdapter implements RechargeMoneyPort {
// private final SpringDataRechargeMoneyRepository rechargeMoneyRepository;
// private final RechargeMoneyMapper rechargeMoneyMapper;
@Override
public void rechargeMoney(MemberMoney.MemberMoneyId memberMoneyId) {
}
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/adapter/out/persistence/SpringDataLocalMoneyRepository.java
================================================
package com.fastcampuspay.moneylocal.adapter.out.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
interface SpringDataLocalMoneyRepository extends JpaRepository {
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/application/port/in/RechargeMoneyCommand.java
================================================
package com.fastcampuspay.moneylocal.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
@Builder
@Data
@EqualsAndHashCode(callSuper = false)
public
class RechargeMoneyCommand extends SelfValidating {
@NotNull
private final String name;
@NotNull
private final String email;
@NotNull
private final String address;
@NotNull
private final boolean isValid;
public RechargeMoneyCommand(String name, String email, String address, boolean isValid) {
this.name = name;
this.email = email;
this.address = address;
this.isValid = isValid;
}
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/application/port/in/RechargeMoneyUseCase.java
================================================
package com.fastcampuspay.moneylocal.application.port.in;
public interface RechargeMoneyUseCase {
void rechargeMoney(RechargeMoneyCommand command);
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/application/port/out/RechargeMoneyPort.java
================================================
package com.fastcampuspay.moneylocal.application.port.out;
import com.fastcampuspay.moneylocal.domain.MemberMoney;
public interface RechargeMoneyPort {
void rechargeMoney(
MemberMoney.MemberMoneyId memberMoneyId
);
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/application/service/RechargeMoney.java
================================================
package com.fastcampuspay.moneylocal.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.moneylocal.application.port.in.RechargeMoneyCommand;
import com.fastcampuspay.moneylocal.application.port.in.RechargeMoneyUseCase;
import lombok.RequiredArgsConstructor;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class RechargeMoney implements RechargeMoneyUseCase {
@Override
public void rechargeMoney(RechargeMoneyCommand command) {
}
}
================================================
FILE: money-local-service/src/main/java/com/fastcampuspay/moneylocal/domain/MemberMoney.java
================================================
package com.fastcampuspay.moneylocal.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class MemberMoney {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String memberMoneyId;
// @Getter private final String name;
// @Getter private final String email;
// @Getter private final String address;
// @Getter private final boolean isValid;
public static MemberMoney generateMemberMoney(
MemberMoneyId memberMoneyId) {
return new MemberMoney(
memberMoneyId.getMemberMoneyId()
);
}
@Value
public static class MemberMoneyId {
public MemberMoneyId(String value) {
this.memberMoneyId = value;
}
String memberMoneyId ;
}
}
================================================
FILE: money-service/build.gradle
================================================
plugins {
id 'com.palantir.docker' version '0.25.0'
}
ext{
axonVersion = "4.6.0"
}
group = 'com.fastcampuspay.money'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation 'org.jetbrains:annotations:23.0.0'
implementation project(path: ':common')
// runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
}
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('../Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/MoneyApplication.java
================================================
package com.fastcampuspay.money;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MoneyApplication {
public static void main(String[] args) {
SpringApplication.run(MoneyApplication.class, args);
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/MoneyConfiguration.java
================================================
package com.fastcampuspay.money;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(MoneyConfigurationProperties.class)
public class MoneyConfiguration {
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/MoneyConfigurationProperties.java
================================================
package com.fastcampuspay.money;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "banking")
public class MoneyConfigurationProperties {
private long transferThreshold = Long.MAX_VALUE;
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/SwaggerConfig.java
================================================
package com.fastcampuspay.money;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket restAPI() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fastcampuspay.money"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.build();
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/adapter/in/web/FindMoneyController.java
================================================
package com.fastcampuspay.money.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class FindMoneyController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@GetMapping(path = "/money/money-history")
ResponseEntity findMoneyHistoryByMemberId(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
@GetMapping(path = "/money/money-info")
ResponseEntity findMoneyInfoByRechargeMoneyId(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/adapter/in/web/RechargeMoneyController.java
================================================
package com.fastcampuspay.money.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class RechargeMoneyController {
// private final RechargeMoneyUseCase registerBankingAccountUseCase;
@PostMapping(path = "/money/recharge/")
ResponseEntity rechargeMoney(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/adapter/in/web/RequestTransferMoneyController.java
================================================
package com.fastcampuspay.money.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class RequestTransferMoneyController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@PostMapping(path = "/money/transfer")
ResponseEntity requestTransferMoneyBetweenMembers(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/adapter/out/persistence/RechargeMoneyJpaEntity.java
================================================
package com.fastcampuspay.money.adapter.out.persistence;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "recharge_money")
@Data
@AllArgsConstructor
@NoArgsConstructor
class RechargeMoneyJpaEntity {
@Id
@GeneratedValue
private Long rechargeMoneyId;
// private String name;
//
// private String address;
//
// private String email;
//
// private boolean isValid;
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/adapter/out/persistence/RechargeMoneyMapper.java
================================================
package com.fastcampuspay.money.adapter.out.persistence;
import com.fastcampuspay.money.domain.MemberMoney;
import org.springframework.stereotype.Component;
@Component
class RechargeMoneyMapper {
MemberMoney mapToDomainEntity(
RechargeMoneyJpaEntity rechargeMoneyJpaEntity) {
System.out.println(rechargeMoneyJpaEntity.toString());
return MemberMoney.generateMemberMoney(
new MemberMoney.MemberMoneyId(rechargeMoneyJpaEntity.getRechargeMoneyId()+"")
);
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/adapter/out/persistence/RechargeMoneyPersistenceAdapter.java
================================================
package com.fastcampuspay.money.adapter.out.persistence;
import com.fastcampuspay.common.PersistenceAdapter;
import com.fastcampuspay.money.application.port.out.RechargeMoneyPort;
import com.fastcampuspay.money.domain.MemberMoney;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@PersistenceAdapter
class RechargeMoneyPersistenceAdapter implements RechargeMoneyPort {
// private final SpringDataRechargeMoneyRepository rechargeMoneyRepository;
// private final RechargeMoneyMapper rechargeMoneyMapper;
@Override
public void rechargeMoney(MemberMoney.MemberMoneyId memberMoneyId) {
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/adapter/out/persistence/SpringDataRechargeMoneyRepository.java
================================================
package com.fastcampuspay.money.adapter.out.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
interface SpringDataRechargeMoneyRepository extends JpaRepository {
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/application/port/in/RechargeMoneyCommand.java
================================================
package com.fastcampuspay.money.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Value;
import javax.validation.constraints.NotNull;
@Value
@Builder
@EqualsAndHashCode(callSuper = false)
public
class RechargeMoneyCommand extends SelfValidating {
@NotNull
private final String name;
@NotNull
private final String email;
@NotNull
private final String address;
@NotNull
private final boolean isValid;
public RechargeMoneyCommand(String name, String email, String address, boolean isValid) {
this.name = name;
this.email = email;
this.address = address;
this.isValid = isValid;
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/application/port/in/RechargeMoneyUseCase.java
================================================
package com.fastcampuspay.money.application.port.in;
public interface RechargeMoneyUseCase {
void rechargeMoney(RechargeMoneyCommand command);
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/application/port/out/RechargeMoneyPort.java
================================================
package com.fastcampuspay.money.application.port.out;
import com.fastcampuspay.money.domain.MemberMoney;
public interface RechargeMoneyPort {
void rechargeMoney(
MemberMoney.MemberMoneyId memberMoneyId
);
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/application/service/RechargeMoney.java
================================================
package com.fastcampuspay.money.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.money.application.port.in.RechargeMoneyCommand;
import com.fastcampuspay.money.application.port.in.RechargeMoneyUseCase;
import com.fastcampuspay.money.application.port.out.RechargeMoneyPort;
import lombok.RequiredArgsConstructor;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class RechargeMoney implements RechargeMoneyUseCase {
private final RechargeMoneyPort rport;
@Override
public void rechargeMoney(RechargeMoneyCommand command) {
}
}
================================================
FILE: money-service/src/main/java/com/fastcampuspay/money/domain/MemberMoney.java
================================================
package com.fastcampuspay.money.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class MemberMoney {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String memberMoneyId;
// @Getter private final String name;
// @Getter private final String email;
// @Getter private final String address;
// @Getter private final boolean isValid;
public static MemberMoney generateMemberMoney(
MemberMoneyId memberMoneyId) {
return new MemberMoney(
memberMoneyId.getMemberMoneyId()
);
}
@Value
public static class MemberMoneyId {
public MemberMoneyId(String value) {
this.memberMoneyId = value;
}
String memberMoneyId ;
}
}
================================================
FILE: payment-service/build.gradle
================================================
plugins {
id 'com.palantir.docker' version '0.25.0'
}
ext{
axonVersion = "4.6.0"
}
group = 'com.fastcampuspay.payment'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation 'org.jetbrains:annotations:23.0.0'
implementation project(path: ':common')
// runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
}
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('../Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/PaymentApplication.java
================================================
package com.fastcampuspay.payment;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PaymentApplication {
public static void main(String[] args) {
SpringApplication.run(PaymentApplication.class, args);
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/PaymentConfiguration.java
================================================
package com.fastcampuspay.payment;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(PaymentConfigurationProperties.class)
public class PaymentConfiguration {
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/PaymentConfigurationProperties.java
================================================
package com.fastcampuspay.payment;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "banking")
public class PaymentConfigurationProperties {
private long transferThreshold = Long.MAX_VALUE;
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/SwaggerConfig.java
================================================
package com.fastcampuspay.payment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket restAPI() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fastcampuspay.money"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.build();
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/adapter/in/web/FindPaymentController.java
================================================
package com.fastcampuspay.payment.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class FindPaymentController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@GetMapping(path = "/payment/info")
ResponseEntity findPaymentByPaymentId(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
@GetMapping(path = "/payment/list-by-period")
ResponseEntity listPaymentsByPeriod(){
// RegisterMembershipRequest
// name, address, email
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/adapter/in/web/RequestTransferMoneyController.java
================================================
package com.fastcampuspay.payment.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class RequestTransferMoneyController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@PostMapping(path = "/payment/request")
ResponseEntity requestPaymentAtMerchant(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/adapter/out/persistence/PaymentJpaEntity.java
================================================
package com.fastcampuspay.payment.adapter.out.persistence;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "payment")
@Data
@AllArgsConstructor
@NoArgsConstructor
class PaymentJpaEntity {
@Id
@GeneratedValue
private Long rechargeMoneyId;
// private String name;
//
// private String address;
//
// private String email;
//
// private boolean isValid;
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/adapter/out/persistence/PaymentMapper.java
================================================
package com.fastcampuspay.payment.adapter.out.persistence;
import com.fastcampuspay.payment.domain.MemberMoney;
import org.springframework.stereotype.Component;
@Component
class PaymentMapper {
MemberMoney mapToDomainEntity(
PaymentJpaEntity rechargeMoneyJpaEntity) {
System.out.println(rechargeMoneyJpaEntity.toString());
return MemberMoney.generateMemberMoney(
new MemberMoney.MemberMoneyId(rechargeMoneyJpaEntity.getRechargeMoneyId()+"")
);
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/adapter/out/persistence/RechargeMoneyPersistenceAdapter.java
================================================
package com.fastcampuspay.payment.adapter.out.persistence;
import com.fastcampuspay.common.PersistenceAdapter;
import com.fastcampuspay.payment.application.port.out.RechargeMoneyPort;
import com.fastcampuspay.payment.domain.MemberMoney;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@PersistenceAdapter
class PaymentPersistenceAdapter implements RechargeMoneyPort {
// private final SpringDataRechargeMoneyRepository rechargeMoneyRepository;
// private final RechargeMoneyMapper rechargeMoneyMapper;
@Override
public void rechargeMoney(MemberMoney.MemberMoneyId memberMoneyId) {
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/adapter/out/persistence/SpringDataPaymentRepository.java
================================================
package com.fastcampuspay.payment.adapter.out.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
interface SpringDataPaymentRepository extends JpaRepository {
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/application/port/in/RechargeMoneyCommand.java
================================================
package com.fastcampuspay.payment.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
public
class RechargeMoneyCommand extends SelfValidating {
@NotNull
private final String name;
@NotNull
private final String email;
@NotNull
private final String address;
@NotNull
private final boolean isValid;
public RechargeMoneyCommand(String name, String email, String address, boolean isValid) {
this.name = name;
this.email = email;
this.address = address;
this.isValid = isValid;
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/application/port/in/RechargeMoneyUseCase.java
================================================
package com.fastcampuspay.payment.application.port.in;
public interface RechargeMoneyUseCase {
void rechargeMoney(RechargeMoneyCommand command);
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/application/port/out/RechargeMoneyPort.java
================================================
package com.fastcampuspay.payment.application.port.out;
import com.fastcampuspay.payment.domain.MemberMoney;
public interface RechargeMoneyPort {
void rechargeMoney(
MemberMoney.MemberMoneyId memberMoneyId
);
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/application/service/RechargeMoney.java
================================================
package com.fastcampuspay.payment.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.payment.application.port.in.RechargeMoneyCommand;
import com.fastcampuspay.payment.application.port.in.RechargeMoneyUseCase;
import lombok.RequiredArgsConstructor;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class RechargeMoney implements RechargeMoneyUseCase {
@Override
public void rechargeMoney(RechargeMoneyCommand command) {
}
}
================================================
FILE: payment-service/src/main/java/com/fastcampuspay/payment/domain/MemberMoney.java
================================================
package com.fastcampuspay.payment.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class MemberMoney {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String memberMoneyId;
// @Getter private final String name;
// @Getter private final String email;
// @Getter private final String address;
// @Getter private final boolean isValid;
public static MemberMoney generateMemberMoney(
MemberMoneyId memberMoneyId) {
return new MemberMoney(
memberMoneyId.getMemberMoneyId()
);
}
@Value
public static class MemberMoneyId {
public MemberMoneyId(String value) {
this.memberMoneyId = value;
}
String memberMoneyId ;
}
}
================================================
FILE: remittance-service/build.gradle
================================================
plugins {
id 'com.palantir.docker' version '0.25.0'
}
ext{
axonVersion = "4.6.0"
}
group = 'com.fastcampuspay.remittance'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation 'org.jetbrains:annotations:23.0.0'
implementation project(path: ':common')
// runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
}
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('../Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/RemittanceApplication.java
================================================
package com.fastcampuspay.remittance;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RemittanceApplication {
public static void main(String[] args) {
SpringApplication.run(RemittanceApplication.class, args);
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/RemittanceConfiguration.java
================================================
package com.fastcampuspay.remittance;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(RemittanceConfigurationProperties.class)
public class RemittanceConfiguration {
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/RemittanceConfigurationProperties.java
================================================
package com.fastcampuspay.remittance;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "banking")
public class RemittanceConfigurationProperties {
private long transferThreshold = Long.MAX_VALUE;
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/SwaggerConfig.java
================================================
package com.fastcampuspay.remittance;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket restAPI() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fastcampuspay.remittance"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.build();
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/adapter/in/web/FindRemittanceController.java
================================================
package com.fastcampuspay.remittance.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class FindRemittanceController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@GetMapping(path = "/remittance/info")
ResponseEntity findRemittanceInfoByRemittanceId(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
@GetMapping(path = "/remittance/history")
ResponseEntity findRemittanceHistoryByMemberId(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
// (API Aggregation, Banking + Money)
@GetMapping(path = "/remittance/transferred-money")
ResponseEntity findMoneyTransferringByRemittanceId(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/adapter/in/web/RequestRemittanceMoneyController.java
================================================
package com.fastcampuspay.remittance.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class RequestRemittanceMoneyController {
// private final RechargeMoneyUseCase registerBankingAccountUseCase;
@PostMapping(path = "/remittance/request/")
ResponseEntity requestRemittance(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/adapter/out/persistence/RemittanceMoneyJpaEntity.java
================================================
package com.fastcampuspay.remittance.adapter.out.persistence;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "remittance_money")
@Data
@AllArgsConstructor
@NoArgsConstructor
class RemittanceMoneyJpaEntity {
@Id
@GeneratedValue
private Long remittanceMoneyId;
// private String name;
//
// private String address;
//
// private String email;
//
// private boolean isValid;
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/adapter/out/persistence/RemittanceMoneyMapper.java
================================================
package com.fastcampuspay.remittance.adapter.out.persistence;
import com.fastcampuspay.remittance.domain.RemittanceMoney;
import org.springframework.stereotype.Component;
@Component
class RemittanceMoneyMapper {
RemittanceMoney mapToDomainEntity(
RemittanceMoneyJpaEntity remittanceMoneyJpaEntity) {
System.out.println(remittanceMoneyJpaEntity.toString());
return RemittanceMoney.generateRemittanceMoney(
new RemittanceMoney.RemittanceMoneyId(remittanceMoneyJpaEntity.getRemittanceMoneyId()+"")
);
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/adapter/out/persistence/RemittanceMoneyPersistenceAdapter.java
================================================
package com.fastcampuspay.remittance.adapter.out.persistence;
import com.fastcampuspay.common.PersistenceAdapter;
import com.fastcampuspay.remittance.application.port.out.RemittanceMoneyPort;
import com.fastcampuspay.remittance.domain.RemittanceMoney;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@PersistenceAdapter
class RemittanceMoneyPersistenceAdapter implements RemittanceMoneyPort {
private final SpringDataRemittanceMoneyRepository remittanceMoneyRepository;
private final RemittanceMoneyMapper remittanceMoneyMapper;
private Long orZero(Long value){
return value == null ? 0L : value;
}
@Override
public void remittanceMoney(RemittanceMoney.RemittanceMoneyId remittanceMoneyId) {
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/adapter/out/persistence/SpringDataRemittanceMoneyRepository.java
================================================
package com.fastcampuspay.remittance.adapter.out.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
interface SpringDataRemittanceMoneyRepository extends JpaRepository {
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/application/port/in/RemittanceMoneyCommand.java
================================================
package com.fastcampuspay.remittance.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Value;
import javax.validation.constraints.NotNull;
@Value
@Builder
@EqualsAndHashCode(callSuper = false)
public
class RemittanceMoneyCommand extends SelfValidating {
@NotNull
private final String name;
@NotNull
private final String email;
@NotNull
private final String address;
@NotNull
private final boolean isValid;
public RemittanceMoneyCommand(String name, String email, String address, boolean isValid) {
this.name = name;
this.email = email;
this.address = address;
this.isValid = isValid;
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/application/port/in/RemittanceMoneyUseCase.java
================================================
package com.fastcampuspay.remittance.application.port.in;
public interface RemittanceMoneyUseCase {
void remittanceMoney(RemittanceMoneyCommand command);
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/application/port/out/RemittanceMoneyPort.java
================================================
package com.fastcampuspay.remittance.application.port.out;
import com.fastcampuspay.remittance.domain.RemittanceMoney;
public interface RemittanceMoneyPort {
void remittanceMoney(
RemittanceMoney.RemittanceMoneyId remittanceMoneyId
);
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/application/service/RemittanceMoney.java
================================================
package com.fastcampuspay.remittance.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.remittance.application.port.in.RemittanceMoneyCommand;
import com.fastcampuspay.remittance.application.port.in.RemittanceMoneyUseCase;
import com.fastcampuspay.remittance.application.port.out.RemittanceMoneyPort;
import lombok.RequiredArgsConstructor;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class RemittanceMoney implements RemittanceMoneyUseCase {
private final RemittanceMoneyPort rport;
@Override
public void remittanceMoney(RemittanceMoneyCommand command) {
}
}
================================================
FILE: remittance-service/src/main/java/com/fastcampuspay/remittance/domain/RemittanceMoney.java
================================================
package com.fastcampuspay.remittance.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RemittanceMoney {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String memberMoneyId;
// @Getter private final String name;
// @Getter private final String email;
// @Getter private final String address;
// @Getter private final boolean isValid;
public static RemittanceMoney generateRemittanceMoney(
RemittanceMoneyId memberMoneyId) {
return new RemittanceMoney(
memberMoneyId.getRemittanceMoney()
);
}
@Value
public static class RemittanceMoneyId {
public RemittanceMoneyId(String value) {
this.remittanceMoney = value;
}
String remittanceMoney ;
}
}
================================================
FILE: settings.gradle
================================================
rootProject.name = 'fastcampus-pay'
include 'common'
include 'membership-service'
include 'banking-service'
include 'money-service'
include 'money-local-service'
include 'remittance-service'
include 'payment-service'
include 'settlement-service'
================================================
FILE: settlement-service/build.gradle
================================================
plugins {
id 'com.palantir.docker' version '0.25.0'
}
ext{
axonVersion = "4.6.0"
}
group = 'com.fastcampuspay.settlement'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation 'org.jetbrains:annotations:23.0.0'
implementation project(path: ':common')
// runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
}
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('../Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/SettlementApplication.java
================================================
package com.fastcampuspay.settlement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SettlementApplication {
public static void main(String[] args) {
SpringApplication.run(SettlementApplication.class, args);
}
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/SettlementConfiguration.java
================================================
package com.fastcampuspay.settlement;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(SettlementConfigurationProperties.class)
public class SettlementConfiguration {
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/SettlementConfigurationProperties.java
================================================
package com.fastcampuspay.settlement;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "banking")
public class SettlementConfigurationProperties {
private long transferThreshold = Long.MAX_VALUE;
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/SwaggerConfig.java
================================================
package com.fastcampuspay.settlement;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket restAPI() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fastcampuspay.money"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.build();
}
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/adapter/in/web/SettlementStartController.java
================================================
package com.fastcampuspay.settlement.adapter.in.web;
import com.fastcampuspay.common.WebAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@WebAdapter
@RestController
@RequiredArgsConstructor
class SettlementStartController {
// private final RegisterBankingAccountUseCase registerBankingAccountUseCase;
@PostMapping(path = "/settlement/start")
ResponseEntity startSettlementByPeriod(){
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
}
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/adapter/out/persistence/RechargeMoneyMapper.java
================================================
package com.fastcampuspay.settlement.adapter.out.persistence;
import com.fastcampuspay.settlement.domain.MemberMoney;
import org.springframework.stereotype.Component;
@Component
class SettlementMapper {
MemberMoney mapToDomainEntity(
SettlementJpaEntity rechargeMoneyJpaEntity) {
System.out.println(rechargeMoneyJpaEntity.toString());
return MemberMoney.generateMemberMoney(
new MemberMoney.MemberMoneyId(rechargeMoneyJpaEntity.getRechargeMoneyId()+"")
);
}
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/adapter/out/persistence/RechargeMoneyPersistenceAdapter.java
================================================
package com.fastcampuspay.settlement.adapter.out.persistence;
import com.fastcampuspay.common.PersistenceAdapter;
import com.fastcampuspay.settlement.application.port.out.RechargeMoneyPort;
import com.fastcampuspay.settlement.domain.MemberMoney;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@PersistenceAdapter
class RechargeMoneyPersistenceAdapter implements RechargeMoneyPort {
// private final SpringDataRechargeMoneyRepository rechargeMoneyRepository;
// private final RechargeMoneyMapper rechargeMoneyMapper;
@Override
public void rechargeMoney(MemberMoney.MemberMoneyId memberMoneyId) {
}
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/adapter/out/persistence/SettlementJpaEntity.java
================================================
package com.fastcampuspay.settlement.adapter.out.persistence;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "settlement")
@Data
@AllArgsConstructor
@NoArgsConstructor
class SettlementJpaEntity {
@Id
@GeneratedValue
private Long rechargeMoneyId;
// private String name;
//
// private String address;
//
// private String email;
//
// private boolean isValid;
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/adapter/out/persistence/SpringDataSettlementRepository.java
================================================
package com.fastcampuspay.settlement.adapter.out.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
interface SpringDataSettlementRepository extends JpaRepository {
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/application/port/in/RechargeMoneyCommand.java
================================================
package com.fastcampuspay.settlement.application.port.in;
import com.fastcampuspay.common.SelfValidating;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Value;
import javax.validation.constraints.NotNull;
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
public
class RechargeMoneyCommand extends SelfValidating {
@NotNull
private final String name;
@NotNull
private final String email;
@NotNull
private final String address;
@NotNull
private final boolean isValid;
public RechargeMoneyCommand(String name, String email, String address, boolean isValid) {
this.name = name;
this.email = email;
this.address = address;
this.isValid = isValid;
}
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/application/port/in/RechargeMoneyUseCase.java
================================================
package com.fastcampuspay.settlement.application.port.in;
public interface RechargeMoneyUseCase {
void rechargeMoney(RechargeMoneyCommand command);
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/application/port/out/RechargeMoneyPort.java
================================================
package com.fastcampuspay.settlement.application.port.out;
import com.fastcampuspay.settlement.domain.MemberMoney;
public interface RechargeMoneyPort {
void rechargeMoney(
MemberMoney.MemberMoneyId memberMoneyId
);
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/application/service/RechargeMoney.java
================================================
package com.fastcampuspay.settlement.application.service;
import com.fastcampuspay.common.UseCase;
import com.fastcampuspay.settlement.application.port.in.RechargeMoneyCommand;
import com.fastcampuspay.settlement.application.port.in.RechargeMoneyUseCase;
import lombok.RequiredArgsConstructor;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@UseCase
@Transactional
public class RechargeMoney implements RechargeMoneyUseCase {
@Override
public void rechargeMoney(RechargeMoneyCommand command) {
}
}
================================================
FILE: settlement-service/src/main/java/com/fastcampuspay/settlement/domain/MemberMoney.java
================================================
package com.fastcampuspay.settlement.domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Value;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class MemberMoney {
/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
@Getter private final String memberMoneyId;
// @Getter private final String name;
// @Getter private final String email;
// @Getter private final String address;
// @Getter private final boolean isValid;
public static MemberMoney generateMemberMoney(
MemberMoneyId memberMoneyId) {
return new MemberMoney(
memberMoneyId.getMemberMoneyId()
);
}
@Value
public static class MemberMoneyId {
public MemberMoneyId(String value) {
this.memberMoneyId = value;
}
String memberMoneyId ;
}
}