Skip to content
This repository has been archived by the owner on Mar 15, 2019. It is now read-only.

Commit

Permalink
Re-Implement all mifos service methods to be asynchronous
Browse files Browse the repository at this point in the history
Fixing bugs on incoming payment request and outgoing payments

Bug fixes in the OutboundController and the data.sql file

Remove out folder from project

Modify a .gitignore file
  • Loading branch information
vladimirfomene committed Jan 26, 2018
1 parent 276a7e7 commit 9c72956
Show file tree
Hide file tree
Showing 65 changed files with 1,507 additions and 540 deletions.
4 changes: 3 additions & 1 deletion mifos-payment/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
/build/
!gradle/wrapper/gradle-wrapper.jar

/out/

### STS ###
.apt_generated
.classpath
Expand All @@ -22,4 +24,4 @@ build/
nbbuild/
dist/
nbdist/
.nb-gradle/
.nb-gradle/
2 changes: 1 addition & 1 deletion mifos-payment/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ dependencies {

compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'

//These dependencies are for jms messaging
//Adding support for amqp support using activemq and jms
compile("org.springframework.boot:spring-boot-starter-activemq")
compile("org.apache.activemq:activemq-broker")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ public class GatewayConstants {

public static final int PAYMENT_STATUS = 3;

public static final int SYSTEM_ERROR_CODE = 500;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class MifosPaymentApplication {

public static ConfigurableApplicationContext context;

public static void main(String[] args) {
SpringApplication.run(MifosPaymentApplication.class, args);
context = SpringApplication.run(MifosPaymentApplication.class, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,37 @@
* Created by vladimirfomene on 8/4/17.
*/
public class TransactionStatus {

public static final String MMP_TRANSACTION_SUCCESS = "Funds is at destination";

public static final Integer MMP_TRANSACTION_SUCCESS_CODE = 2200;

public static final String MMP_TRANSACTION_FAILURE = "Funds did not get to client";

public static final Integer MMP_TRANSACTION_FAILURE_CODE = 4100;

public static final String REVERSE_DISBURSEMENT_SUCCESS = "Funds are back in mifos";

public static final Integer REVERSE_DISBURSEMENT_SUCCESS_CODE = 2400;

public static final String REVERSE_DISBURSEMENT_FAILURE = "Fund are not back in mifos";

public static final Integer REVERSE_DISBURSEMENT_FAILURE_CODE = 4400;

public static final String REVERSE_DISBURSEMENT_NO_ACTION = "Funds already reversed.";

public static final String NO_ACTION = "MMP transaction was successfull";

public static final Integer NO_ACTION_CODE = 0;

public static final String RECURRING_DEPOSIT_SUCCESS = "Recurring deposit was successful.";

public static final Integer RECURRING_DEPOSIT_SUCCESS_CODE = 2300;

public static final String RECURRING_DEPOSIT_FAILURE = "Recurring deposit failed";

public static final Integer RECURRING_DEPOSIT_FAILURE_CODE = 4500;

public static final String REQUEST_RECEPTION_SUCCESS = "Request was received";

public static final Integer REQUEST_RECEPTION_SUCCESS_CODE = 2100;
Expand Down Expand Up @@ -31,4 +62,8 @@ public class TransactionStatus {
public static final String VOLUNTARY_DEPOSIT_SUCCESS = "Deposit successful";

public static final Integer VOLUNTARY_DEPOSIT_SUCCESS_CODE = 2600;

public static final String VOLUNTARY_DEPOSIT_FAILURE = "Deposit failed.";

public static final Integer VOLUNTARY_DEPOSIT_FAILURE_CODE = 4600;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
package org.mifos.mifospaymentbridge.controller;

import org.mifos.mifospaymentbridge.MifosPaymentApplication;
import org.mifos.mifospaymentbridge.Util.StatusCategory;
import org.mifos.mifospaymentbridge.Util.TransactionStatus;
import org.mifos.mifospaymentbridge.integration.OutboundMessageReceiver;
import org.mifos.mifospaymentbridge.mifos.MifosService;
import org.mifos.mifospaymentbridge.mifos.domain.loan.Loan;
import org.mifos.mifospaymentbridge.mifos.domain.loan.LoanAccountRequest;
import org.mifos.mifospaymentbridge.mifos.domain.loan.LoanAccountSearchResult;
import org.mifos.mifospaymentbridge.mifos.domain.savingsaccount.deposit.AccountDepositRequest;
import org.mifos.mifospaymentbridge.mifos.domain.savingsaccount.deposit.RecurringDepositAccount;
import org.mifos.mifospaymentbridge.mifos.domain.savingsaccount.deposit.SavingsAccount;
import org.mifos.mifospaymentbridge.model.InboundRequest;
import org.mifos.mifospaymentbridge.model.Microfinance;
import org.mifos.mifospaymentbridge.model.OutboundRequest;
import org.mifos.mifospaymentbridge.model.Status;
import org.mifos.mifospaymentbridge.services.InboundRequestService;
import org.mifos.mifospaymentbridge.services.MicrofinanceService;
import org.mifos.mifospaymentbridge.services.OutboundRequestService;
import org.mifos.mifospaymentbridge.services.StatusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.ConfigurableApplicationContext;
Expand All @@ -17,15 +30,15 @@
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.web.bind.annotation.*;
import javax.jms.Message;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Session;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import javax.jms.*;
import java.io.IOException;

@RestController
Expand All @@ -38,36 +51,134 @@ public class InboundController {
@Autowired
private ConfigurableApplicationContext context;

@Autowired
private InboundRequestService inboundRequestService;

@Autowired
private OutboundRequestService outboundRequestService;

@Autowired
private StatusService statusService;

@Autowired
private MicrofinanceService mfiService;

private Microfinance mfi;

@Autowired
private OutboundMessageReceiver outboundMessageReceiver;


/**
* Web service to get a recurring deposit account
* @param depositAcc
* @return
*/
@RequestMapping(value = "/recurringDepositAccounts", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<RecurringDepositAccount> getRecurringDepositAccount(@RequestBody AccountDepositRequest depositAcc, @RequestParam(value="tenant") String tenant){
RecurringDepositAccount depositAccount = null;

try {
depositAccount = mifosService.getRecurringDepositAccount(depositAcc.getAccountNumber(), true, tenant);
} catch (IOException e) {
e.printStackTrace();
}

return new ResponseEntity<>(depositAccount, HttpStatus.OK);
}


/**
* Web service to get voluntary savings account from fineract
*/
@RequestMapping(value = "/voluntarySavingAccounts", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<SavingsAccount> getVoluntarySavingsAccount(@RequestBody AccountDepositRequest depositRequest){

SavingsAccount savingsAccount = null;


try {
savingsAccount = mifosService.getSavingsAccount(depositRequest.getAccountNumber(), true, "default" );
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseEntity<>(savingsAccount, HttpStatus.OK);
}


/**
* Web service to get loan account for fineract.
* @param loanAccNo
* Web service to get loan account from fineract.
* @param loanAccRequest
* @return
*/
@RequestMapping(value = "/loans", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Loan> getLoanAccount(@RequestParam(value = "loanAccNo", required=true) String loanAccNo){
public ResponseEntity<Loan> getLoanAccount(@RequestBody LoanAccountRequest loanAccRequest, @RequestParam(value="tenant") String tenant){

Loan loanAccount = null;

try {
loanAccount = mifosService.getLoanAccount(loanAccNo, true, "default");
loanAccount = mifosService.getLoanAccount(loanAccRequest.getLoanAccountNo(), true, tenant);
} catch (IOException e) {
e.printStackTrace();
}

return new ResponseEntity<>(loanAccount, HttpStatus.OK);
}

@RequestMapping(value = "/outbound/payments/status", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> receiveOutboundStatus(@RequestBody Status outboundTransactionStatus,
@RequestParam(value="requestID") Long requestID){
Status reverseStatus = null;
OutboundRequest request = outboundRequestService.findOne(requestID);
Status transactionStatus = statusService.findOne(request.getOutboundStatusId());

transactionStatus.setCode(outboundTransactionStatus.getCode());
transactionStatus.setDescription(outboundTransactionStatus.getDescription());
transactionStatus.setStatusCategory(outboundTransactionStatus.getStatusCategory());

//Save status
statusService.save(transactionStatus);

if(transactionStatus.getCode().equalsIgnoreCase(String.valueOf(TransactionStatus.MMP_TRANSACTION_SUCCESS_CODE))){
//Set reverse status of outboundRequest to NO Action
reverseStatus.setCode(String.valueOf(TransactionStatus.NO_ACTION_CODE));
reverseStatus.setDescription(TransactionStatus.NO_ACTION);
reverseStatus.setStatusCategory(StatusCategory.GATEWAY_CATEGORY);
}else{
outboundMessageReceiver.attemptReverseDisbursal();
}

request.setReverseStatusId(reverseStatus.getId());
outboundRequestService.save(request);

return new ResponseEntity<>("Status Received", HttpStatus.OK);


}

/**
* Web service for receiving inbound request and
* queueing it and sending it to the inbound message
* receiver with jms.
* @param inboundRequest
* @return
*/
@RequestMapping(value = "/inbound/requests", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Status> acceptInboundRequest(@RequestBody InboundRequest inboundRequest){
public ResponseEntity<Status> acceptInboundRequest(@RequestBody InboundRequest inboundRequest, @RequestParam(value="tenant") String tenant){
Status receptionStatus = null;
context = MifosPaymentApplication.context;

System.out.println(inboundRequest.toString());

if(tenant != null){
mfi = mfiService.findMicrofinanceByName(tenant);
System.out.println(mfi.toString());
inboundRequest.setMfiId(mfi.getId());
}

JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);

jmsTemplate.send("inboundAcceptor", new MessageCreator(){
public Message createMessage(Session session) throws JMSException {
return session.createObjectMessage(inboundRequest);
}
});
jmsTemplate.convertAndSend("inboundAcceptor", inboundRequest);

if(inboundRequest != null){
receptionStatus = new Status();
Expand All @@ -90,4 +201,12 @@ public JmsListenerContainerFactory<?> inboundFactory(ConnectionFactory connectio

return factory;
}

@Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.mifos.mifospaymentbridge.controller;


import org.mifos.mifospaymentbridge.Util.StatusCategory;
import org.mifos.mifospaymentbridge.Util.TransactionStatus;
import org.mifos.mifospaymentbridge.integration.OutboundMessageReceiver;
import org.mifos.mifospaymentbridge.model.OutboundRequest;
import org.mifos.mifospaymentbridge.model.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class OutboundController {

@Autowired
private OutboundMessageReceiver receiver;

private Status outboundReceptionStatus;

@RequestMapping(value = "/outbound/requests", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Status> acceptOutboundRequest(@RequestBody OutboundRequest outboundRequest, @RequestParam(value="tenant") String tenant){
System.out.println(outboundRequest.toString());
receiver.receiveRequest(outboundRequest);

if(outboundRequest != null){
outboundReceptionStatus = new Status();
outboundReceptionStatus.setCode(String.valueOf(TransactionStatus.REQUEST_RECEPTION_SUCCESS_CODE));
outboundReceptionStatus.setDescription(TransactionStatus.REQUEST_RECEPTION_SUCCESS);
outboundReceptionStatus.setStatusCategory(StatusCategory.GATEWAY_CATEGORY);
}

return new ResponseEntity<>(outboundReceptionStatus, HttpStatus.OK);
}

}
Loading

0 comments on commit 9c72956

Please sign in to comment.