Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • xkollar3/online-banking-service
1 result
Show changes
Commits on Source (2)
......@@ -65,6 +65,19 @@ services:
- POSTGRES_PASSWORD=changemelater
- POSTGRES_USER=transaction_service
- POSTGRES_DB=transaction_db
transaction-broker:
container_name: transaction-broker
image: apache/activemq-artemis
ports:
- 61616:61616
- 8161:8161
volumes:
- transaction-broker-data:/var/log/activemq
- transaction-broker-data:/opt/activemq/conf
- transaction-broker-data:/opt/activemq/data
environment:
- ACTIVEMQ_USERNAME=admin
- ACTIVEMQ_PASSWORD=password
user-service:
container_name: user-service
build:
......@@ -115,4 +128,5 @@ volumes:
user-db-data: { }
currency-db-data: { }
transaction-db-data: { }
transaction-broker-data: { }
grafana_storage: { }
......@@ -110,6 +110,11 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>6.1.6</version>
</dependency>
</dependencies>
<build>
......
......@@ -2,6 +2,7 @@ package cz.muni.fi.obs.data.dbo;
public enum TransactionState {
PROCESSING,
SUCCESSFUL,
FAILED;
}
......@@ -5,6 +5,7 @@ import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.exceptions.ResourceNotFoundException;
import cz.muni.fi.obs.jms.JmsProducer;
import cz.muni.fi.obs.service.AccountService;
import cz.muni.fi.obs.service.TransactionService;
import lombok.extern.slf4j.Slf4j;
......@@ -22,11 +23,13 @@ public class TransactionManagementFacade {
private final TransactionService transactionService;
private final AccountService accountService;
private final JmsProducer jmsProducer;
@Autowired
public TransactionManagementFacade(TransactionService transactionService, AccountService accountService) {
public TransactionManagementFacade(TransactionService transactionService, AccountService accountService, JmsProducer jmsProducer) {
this.transactionService = transactionService;
this.accountService = accountService;
this.jmsProducer = jmsProducer;
}
public Optional<TransactionDbo> getTransactionById(String id) {
......
package cz.muni.fi.obs.jms;
import cz.muni.fi.obs.service.TransactionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import static cz.muni.fi.obs.jms.JmsProducer.TRANSACTION_QUEUE_NAME;
@Component
@Slf4j
public class JmsConsumer {
private final TransactionService transactionService;
@Autowired
public JmsConsumer(TransactionService transactionService) {
this.transactionService = transactionService;
}
@JmsListener(destination = TRANSACTION_QUEUE_NAME, concurrency = "1-4")
public void listenTransactions(String transactionId) {
log.info("Executing transaction with id: " + transactionId);
transactionService.executeTransaction(transactionId);
}
}
package cz.muni.fi.obs.jms;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class JmsProducer {
private final JmsTemplate jmsTemplate;
public final static String TRANSACTION_QUEUE_NAME = "transactions";
@Autowired
public JmsProducer(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public void sendMessage(String transactionId) {
log.info("Attempting to send message: " + transactionId);
jmsTemplate.convertAndSend(TRANSACTION_QUEUE_NAME, transactionId);
}
}
......@@ -22,6 +22,7 @@ import java.util.Optional;
import java.util.UUID;
import static cz.muni.fi.obs.data.dbo.TransactionState.FAILED;
import static cz.muni.fi.obs.data.dbo.TransactionState.PROCESSING;
import static cz.muni.fi.obs.data.dbo.TransactionState.SUCCESSFUL;
@Slf4j
......@@ -71,29 +72,37 @@ public class TransactionService {
AccountDbo depositsToAccount = accountRepository.findAccountDboByAccountNumber(transaction.depositsToAccountNumber())
.orElseThrow(() -> new ResourceNotFoundException(AccountDbo.class, transaction.depositsToAccountNumber()));
CurrencyExchangeRequest request = CurrencyExchangeRequest.builder()
.from(transaction.withdrawsFromAccountNumber())
.to(transaction.depositsToAccountNumber())
.amount(transaction.withdrawAmount())
.build();
CurrencyExchangeResult exchangeResult = callCurrencyClient(request);
var transactionDbo = TransactionDbo.builder()
TransactionDbo transactionDbo = TransactionDbo.builder()
.id(UUID.randomUUID().toString())
.withdrawsFrom(withdrawsFromAccount)
.note(transaction.note())
.depositsTo(depositsToAccount)
.depositAmount(exchangeResult.destAmount())
.withdrawAmount(transaction.withdrawAmount())
.variableSymbol(transaction.variableSymbol())
.conversionRate(exchangeResult.exchangeRate())
.transactionState(computeTransactionState(withdrawsFromAccount.getId(), transaction.withdrawAmount()))
.transactionState(PROCESSING)
.build();
return repository.save(transactionDbo);
}
public void executeTransaction(String transactionId) {
TransactionDbo transaction = repository.findById(transactionId)
.orElseThrow(() -> new ResourceNotFoundException(TransactionDbo.class, transactionId));
CurrencyExchangeRequest request = CurrencyExchangeRequest.builder()
.from(transaction.getWithdrawsFrom().getCurrencyCode())
.to(transaction.getDepositsTo().getCurrencyCode())
.amount(transaction.getWithdrawAmount())
.build();
CurrencyExchangeResult exchangeResult = callCurrencyClient(request);
transaction.setConversionRate(exchangeResult.exchangeRate());
transaction.setDepositAmount(exchangeResult.destAmount());
transaction.setTransactionState(computeTransactionState(transaction.getWithdrawsFrom().getId(), transaction.getWithdrawAmount()));
repository.save(transaction);
}
private TransactionState computeTransactionState(String id, BigDecimal withdrawAmount) {
return calculateAccountBalance(id).compareTo(withdrawAmount) > 0 ? SUCCESSFUL : FAILED;
}
......
ALTER TABLE transactions
ALTER COLUMN deposited_amount drop not null;
ALTER TABLE transactions
ALTER COLUMN conversion_rate drop not null;