diff --git a/banking-client/src/main/java/ufrn/imd/utils/MachineState.java b/banking-client/src/main/java/ufrn/imd/utils/MachineState.java index 975d268b2ebda092b909bd8c0bf19ef69a5bb142..4f1834f4fe00066168878d3ae62f93f2c7b19f2e 100644 --- a/banking-client/src/main/java/ufrn/imd/utils/MachineState.java +++ b/banking-client/src/main/java/ufrn/imd/utils/MachineState.java @@ -5,6 +5,7 @@ import ufrn.imd.controller.Controller; import ufrn.imd.domain.Account; import ufrn.imd.domain.Client; import ufrn.imd.utils.message.DepositMessage; +import ufrn.imd.utils.message.TransferMessage; import ufrn.imd.utils.message.WithdrawalMessage; import java.net.MalformedURLException; @@ -13,9 +14,7 @@ import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.util.Scanner; -import static ufrn.imd.utils.NameSpace.HOST_BALANCE_SERVICE; -import static ufrn.imd.utils.NameSpace.HOST_DEPOSIT_SERVICE; -import static ufrn.imd.utils.NameSpace.HOST_WITHDRAWAL_SERVICE; +import static ufrn.imd.utils.NameSpace.*; @Data public class MachineState { @@ -25,6 +24,7 @@ public class MachineState { public static final String DEPOSIT = "DEPOSIT"; public static final String BALANCE = "BALANCE"; public static final String WITHDRAWAL = "WITHDRAWAL"; + public static final String TRANSFER = "TRANSFER"; public static final String START = "START"; public static final String INVALID_INPUT = "INVALID_INPUT"; @@ -59,6 +59,8 @@ public class MachineState { state = START; } else if(state.equals(WITHDRAWAL)) { state = START; + } else if(state.equals(TRANSFER)) { + state = START; } } @@ -69,7 +71,8 @@ public class MachineState { !inputValue.equals(QUIT) && !inputValue.equals(DEPOSIT) && !inputValue.equals(BALANCE) && - !inputValue.equals(WITHDRAWAL)) { + !inputValue.equals(WITHDRAWAL) && + !inputValue.equals(TRANSFER)) { inputValue = INVALID_INPUT; } } else if(state.equals(DEPOSIT)) { @@ -124,6 +127,30 @@ public class MachineState { } catch (InterruptedException e) { throw new RuntimeException(e); } + } else if(state.equals(TRANSFER)) { + String accountNumber = sc.nextLine(); + System.out.println(">>> Please enter with the value that you want transfer"); + String v = sc.nextLine(); + + Client client = new Client(1); + Account account = new Account(null, accountNumber, null); + TransferMessage transferMessage = new TransferMessage(client, account, Double.parseDouble(v)); + Controller server = (Controller) Naming.lookup(HOST_TRANSFER_SERVICE); + ServerResponse response = server.getResponse(transferMessage); + if(response.getStatus() == 200) { + System.out.println( + String.format(">>> Your balance is: %.2f", ((Account)response.getBody()).getBalance()) + ); + } else if(response.getStatus() == 500) { + System.out.println( + String.format(">>> %s", response.getMessage()) + ); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } } @@ -135,9 +162,9 @@ public class MachineState { } else if(state.equals(START)) { System.out.println("These are the avaliable operations"); System.out.println("---------------------------------"); - System.out.println(" - deposit \t - balance"); - System.out.println(" - withdrawal \t - quit"); - + System.out.println(" - deposit \t\t - balance"); + System.out.println(" - withdrawal \t - transfer"); + System.out.println(" - quit"); System.out.println("---------------------------------"); Thread.sleep(1000); } else if(state.equals(READ)) { @@ -151,6 +178,9 @@ public class MachineState { } else if(state.equals(WITHDRAWAL)) { System.out.println(">>> Starting withdrawal operation"); System.out.println(">>> Please enter the value you want to withdraw"); + } else if(state.equals(TRANSFER)) { + System.out.println(">>> Starting transfer operation"); + System.out.println(">>> Please enter with the recipient's account number"); } } catch (InterruptedException e) { throw new RuntimeException(e); diff --git a/banking-client/src/main/java/ufrn/imd/utils/NameSpace.java b/banking-client/src/main/java/ufrn/imd/utils/NameSpace.java index 68378ddd071645b9312f191151677cb136ac9273..3cc1c46f5f9d8cced8686b7065fcf43128a4d6c2 100644 --- a/banking-client/src/main/java/ufrn/imd/utils/NameSpace.java +++ b/banking-client/src/main/java/ufrn/imd/utils/NameSpace.java @@ -4,7 +4,9 @@ public class NameSpace { public final static Integer PORT_WITHDRAWAL_SERVICE = 1906; public static final Integer PORT_DEPOSIT_SERVICE = 1907; public static final Integer PORT_BALANCE_SERVICE = 1908; + public static final Integer PORT_TRANSFER_SERVICE = 1909; public final static String HOST_WITHDRAWAL_SERVICE = String.format("rmi://127.0.0.1:%d/%s", PORT_WITHDRAWAL_SERVICE, "withdrawal"); public static final String HOST_DEPOSIT_SERVICE = String.format("rmi://127.0.0.1:%d/%s", PORT_DEPOSIT_SERVICE, "deposit"); public static final String HOST_BALANCE_SERVICE = String.format("rmi://127.0.0.1:%d/%s", PORT_BALANCE_SERVICE, "balance"); + public final static String HOST_TRANSFER_SERVICE = String.format("rmi://127.0.0.1:%d/%s", PORT_TRANSFER_SERVICE, "transfer"); } diff --git a/banking-client/src/main/java/ufrn/imd/utils/message/TransferMessage.java b/banking-client/src/main/java/ufrn/imd/utils/message/TransferMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..93fb4928759ad4746cd085a548fdcd6bbd28a4fe --- /dev/null +++ b/banking-client/src/main/java/ufrn/imd/utils/message/TransferMessage.java @@ -0,0 +1,18 @@ +package ufrn.imd.utils.message; + +import lombok.AllArgsConstructor; +import lombok.Data; +import ufrn.imd.domain.Account; +import ufrn.imd.domain.Client; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +public class TransferMessage implements Serializable { + private static final long serialVersionUID = 2L; + + private Client from; + private Account to; + private Double value; +} diff --git a/banking-server/src/main/java/ufrn/imd/BankingServerApp.java b/banking-server/src/main/java/ufrn/imd/BankingServerApp.java index 4332c2c16d20ca96e4716a2b290aeb84f9bcc151..24f0ed8baec50747419f805562f02f0a63a2ac7f 100644 --- a/banking-server/src/main/java/ufrn/imd/BankingServerApp.java +++ b/banking-server/src/main/java/ufrn/imd/BankingServerApp.java @@ -3,10 +3,12 @@ package ufrn.imd; import ufrn.imd.controller.Controller; import ufrn.imd.controller.impl.BalanceControllerImpl; import ufrn.imd.controller.impl.DepositControllerImpl; +import ufrn.imd.controller.impl.TransferControllerImpl; import ufrn.imd.controller.impl.WithdrawalControllerImpl; import ufrn.imd.repository.impl.ClientRepository; import ufrn.imd.service.impl.BalanceServiceImpl; import ufrn.imd.service.impl.DepositServiceImpl; +import ufrn.imd.service.impl.TransferServiceImpl; import ufrn.imd.service.impl.WithdrawalServiceImpl; import java.net.MalformedURLException; @@ -19,9 +21,11 @@ public class BankingServerApp { DepositServiceImpl depositService = new DepositServiceImpl(clientRepository); BalanceServiceImpl balanceService = new BalanceServiceImpl(clientRepository); WithdrawalServiceImpl withdrawalService = new WithdrawalServiceImpl(clientRepository); + TransferServiceImpl transferService = new TransferServiceImpl(clientRepository); Controller depositController = new DepositControllerImpl(depositService); Controller balanceController = new BalanceControllerImpl(balanceService); Controller withdrawalController = new WithdrawalControllerImpl(withdrawalService); + Controller transferController = new TransferControllerImpl(transferService); } } diff --git a/banking-server/src/main/java/ufrn/imd/controller/impl/TransferControllerImpl.java b/banking-server/src/main/java/ufrn/imd/controller/impl/TransferControllerImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..9b52159ca6c2040260de3a508ff926e6c83e6cd4 --- /dev/null +++ b/banking-server/src/main/java/ufrn/imd/controller/impl/TransferControllerImpl.java @@ -0,0 +1,50 @@ +package ufrn.imd.controller.impl; + +import lombok.extern.java.Log; +import ufrn.imd.controller.Controller; +import ufrn.imd.service.impl.TransferServiceImpl; +import ufrn.imd.utils.ServerResponse; +import ufrn.imd.utils.message.TransferMessage; + +import java.net.MalformedURLException; +import java.rmi.AlreadyBoundException; +import java.rmi.Naming; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.server.UnicastRemoteObject; +import java.util.Optional; + +import static ufrn.imd.utils.NameSpace.HOST_TRANSFER_SERVICE; +import static ufrn.imd.utils.NameSpace.PORT_TRANSFER_SERVICE; + +@Log +public class TransferControllerImpl extends UnicastRemoteObject implements Controller { + private final TransferServiceImpl service; + + public TransferControllerImpl(TransferServiceImpl service) throws RemoteException, MalformedURLException, AlreadyBoundException { + super(); + log.info("Starting Transfer service!"); + this.service = service; + log.info(String.format("Initializing server in %s", HOST_TRANSFER_SERVICE)); + LocateRegistry.createRegistry(PORT_TRANSFER_SERVICE); + Naming.bind(HOST_TRANSFER_SERVICE, this); + } + + @Override + public ServerResponse getResponse(Object client) throws RemoteException { + TransferMessage transferMessage = (TransferMessage) client; + ServerResponse response; + try { + response = this.service.transfer(transferMessage.getValue(), Optional.of(transferMessage.getFrom()), + Optional.of(transferMessage.getTo())); + } catch (RuntimeException e) { + e.printStackTrace(); + response = ServerResponse.builder() + .status(500) + .message(e.getMessage()) + .body(transferMessage.getFrom()) + .build(); + } + return response; + } +} diff --git a/banking-server/src/main/java/ufrn/imd/repository/impl/ClientRepository.java b/banking-server/src/main/java/ufrn/imd/repository/impl/ClientRepository.java index 83963f78bcbb35365a86888a93c423271c0df4b3..22520da111f7fd8d9af0f94b6845501c69d1c236 100644 --- a/banking-server/src/main/java/ufrn/imd/repository/impl/ClientRepository.java +++ b/banking-server/src/main/java/ufrn/imd/repository/impl/ClientRepository.java @@ -22,4 +22,10 @@ public class ClientRepository implements Repository<Client> { public List<Client> findAll() { return clients; } + + public Optional<Client> findByAccountNumber(String number) { + return clients.stream() + .filter(client -> number.equals(client.getAccount().getNumber())) + .findFirst(); + } } diff --git a/banking-server/src/main/java/ufrn/imd/service/impl/TransferServiceImpl.java b/banking-server/src/main/java/ufrn/imd/service/impl/TransferServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..0df30a9fc3a2b2479c57dcfb9b586bd42452e09e --- /dev/null +++ b/banking-server/src/main/java/ufrn/imd/service/impl/TransferServiceImpl.java @@ -0,0 +1,48 @@ +package ufrn.imd.service.impl; + +import lombok.AllArgsConstructor; +import lombok.extern.java.Log; +import ufrn.imd.domain.Account; +import ufrn.imd.domain.Client; +import ufrn.imd.repository.Repository; +import ufrn.imd.repository.impl.ClientRepository; +import ufrn.imd.service.Service; +import ufrn.imd.utils.ServerResponse; + +import java.rmi.RemoteException; +import java.util.Optional; + +@Log +@AllArgsConstructor +public class TransferServiceImpl implements Service { + + private final Repository<Client> clientRepository; + + public ServerResponse transfer(Double value, Optional<Client> from, Optional<Account> to) throws RemoteException, RuntimeException { + Client fromUser = from.orElseThrow(() -> new RuntimeException("Null user!")); + Client fromClient = clientRepository.find(fromUser.getId()) + .orElseThrow(() -> new RuntimeException("Invalid user!")); + + Account toUserAccount = to.orElseThrow(() -> new RuntimeException("Null account")); + Client toClient = ((ClientRepository) clientRepository).findByAccountNumber(toUserAccount.getNumber()) + .orElseThrow(() -> new RuntimeException( + String.format("Customer not found with account number %s", toUserAccount.getNumber()))); + + if(fromClient.getId().equals(toClient.getId())) + throw new RuntimeException("Invalid account"); + + Account fromAccount = fromClient.getAccount(); + if(value > fromAccount.getBalance()) throw new RuntimeException("Insufficient balance"); + + fromAccount.setBalance(fromAccount.getBalance() - value); + Account toAccount = toClient.getAccount(); + toAccount.setBalance(toAccount.getBalance() + value); + log.info("Transfer concluded!"); + log.info(String.format("Account balance: R$ %.2f", fromClient.getAccount().getBalance())); + return ServerResponse.builder() + .status(200) + .message("Operation sucessed!") + .body(fromClient.getAccount()) + .build(); + } +} diff --git a/banking-server/src/main/java/ufrn/imd/utils/NameSpace.java b/banking-server/src/main/java/ufrn/imd/utils/NameSpace.java index d05657df43ae73e13b75ed8d0830f25e4be9910f..fe82fc880f2ddf63a9c7014be14a81ce89fc9c93 100644 --- a/banking-server/src/main/java/ufrn/imd/utils/NameSpace.java +++ b/banking-server/src/main/java/ufrn/imd/utils/NameSpace.java @@ -1,7 +1,7 @@ package ufrn.imd.utils; public class NameSpace { - + public static final Integer PORT_TRANSFER_SERVICE = 1909; public final static Integer PORT_BALANCE_SERVICE = 1908; public final static Integer PORT_DEPOSIT_SERVICE = 1907; public final static Integer PORT_WITHDRAWAL_SERVICE = 1906; @@ -14,4 +14,7 @@ public class NameSpace { public final static String HOST_WITHDRAWAL_SERVICE = String.format("rmi://127.0.0.1:%d/%s", PORT_WITHDRAWAL_SERVICE, "withdrawal"); + + public final static String HOST_TRANSFER_SERVICE = + String.format("rmi://127.0.0.1:%d/%s", PORT_TRANSFER_SERVICE, "transfer"); } diff --git a/banking-server/src/main/java/ufrn/imd/utils/message/TransferMessage.java b/banking-server/src/main/java/ufrn/imd/utils/message/TransferMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..93fb4928759ad4746cd085a548fdcd6bbd28a4fe --- /dev/null +++ b/banking-server/src/main/java/ufrn/imd/utils/message/TransferMessage.java @@ -0,0 +1,18 @@ +package ufrn.imd.utils.message; + +import lombok.AllArgsConstructor; +import lombok.Data; +import ufrn.imd.domain.Account; +import ufrn.imd.domain.Client; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +public class TransferMessage implements Serializable { + private static final long serialVersionUID = 2L; + + private Client from; + private Account to; + private Double value; +} diff --git a/banking-server/target/classes/ufrn/imd/BankingServerApp.class b/banking-server/target/classes/ufrn/imd/BankingServerApp.class index 84bf69c80fd2cd8f90878db02bd5836285daeaba..8d5ef782c69ac0f87e6afb4dd4b59b1497d69553 100644 Binary files a/banking-server/target/classes/ufrn/imd/BankingServerApp.class and b/banking-server/target/classes/ufrn/imd/BankingServerApp.class differ diff --git a/banking-server/target/classes/ufrn/imd/repository/impl/ClientRepository.class b/banking-server/target/classes/ufrn/imd/repository/impl/ClientRepository.class index 155a44b5c55392b0c43f96fcd159f827359a5777..c6d086468a406fbde73aefe262c8388575fe861e 100644 Binary files a/banking-server/target/classes/ufrn/imd/repository/impl/ClientRepository.class and b/banking-server/target/classes/ufrn/imd/repository/impl/ClientRepository.class differ diff --git a/banking-server/target/classes/ufrn/imd/utils/NameSpace.class b/banking-server/target/classes/ufrn/imd/utils/NameSpace.class index 615ca1f909796027ddf196e31bfa6a831963264c..42a6dfd302b25b75da9780c5ae89421c50754d76 100644 Binary files a/banking-server/target/classes/ufrn/imd/utils/NameSpace.class and b/banking-server/target/classes/ufrn/imd/utils/NameSpace.class differ