You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by av...@apache.org on 2021/08/09 12:01:38 UTC
[fineract-cn-deposit-account-management] branch develop updated:
[FINCN-346] Transaction execution error fix (#26)
This is an automated email from the ASF dual-hosted git repository.
avikg pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-deposit-account-management.git
The following commit(s) were added to refs/heads/develop by this push:
new 9196049 [FINCN-346] Transaction execution error fix (#26)
9196049 is described below
commit 9196049ab508de1f5320b89481b8f1942c258adf
Author: Manoj <56...@users.noreply.github.com>
AuthorDate: Mon Aug 9 17:31:34 2021 +0530
[FINCN-346] Transaction execution error fix (#26)
* AL-52-account-transfer-txn
* balance-api-collection-init
* collections
* transaction-execution-error-fix-by-retry
---
.../fineract/cn/deposit/api/v1/EventConstants.java | 5 ++
.../cn/deposit/api/v1/PermittableGroupIds.java | 3 +
.../deposit/listener/SubTxnTypeEventListener.java | 69 ++++++++++++++++++++++
.../deposit/listener/TransactionEventListener.java | 58 ++++++++++++++++++
.../command/handler/TransactionCommandHandler.java | 11 ++--
.../internal/service/TransactionService.java | 55 ++++++++++-------
.../service/rest/CollectionsRestController.java | 8 +--
.../rest/ProductInstanceRestController.java | 30 +++++++++-
.../service/rest/SubTxnTypeRestController.java | 8 +--
.../service/rest/TransactionRestController.java | 32 ++++++++--
service/src/main/resources/application.yml | 1 +
11 files changed, 236 insertions(+), 44 deletions(-)
diff --git a/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java
index 5bd1063..2c7060f 100644
--- a/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java
+++ b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java
@@ -51,7 +51,12 @@ public interface EventConstants {
String SELECTOR_PUT_PRODUCT_INSTANCE = SELECTOR_NAME + " = '" + PUT_PRODUCT_INSTANCE + "'";
String POST_SUB_TXN_TYPE = "post-sub-txn-type";
+ String SELECTOR_POST_SUB_TXN_TYPE = SELECTOR_NAME + " = '" + POST_SUB_TXN_TYPE + "'";
String PUT_SUB_TXN_TYPE = "put-sub-txn-type";
+ String SELECTOR_PUT_SUB_TXN_TYPE = SELECTOR_NAME + " = '" + PUT_SUB_TXN_TYPE + "'";
+
+ String POST_TXN = "post-txn";
+ String SELECTOR_POST_TXN = SELECTOR_NAME + " = '" + POST_TXN + "'";
String ACTIVATE_PRODUCT_INSTANCE_COMMAND = "ACTIVATE";
String CLOSE_PRODUCT_INSTANCE_COMMAND = "CLOSE";
diff --git a/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/PermittableGroupIds.java b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/PermittableGroupIds.java
index 31c90c4..f558738 100644
--- a/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/PermittableGroupIds.java
+++ b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/PermittableGroupIds.java
@@ -21,5 +21,8 @@ package org.apache.fineract.cn.deposit.api.v1;
@SuppressWarnings("unused")
public interface PermittableGroupIds {
String DEFINITION_MANAGEMENT = "deposit__v1__definition";
+ String DEF_SUB_TXN_MANAGEMENT = "deposit__v1__subtxn";
String INSTANCE_MANAGEMENT = "deposit__v1__instance";
+ String TXN_MANAGEMENT = "deposit__v1__transaction";
+ String COLLECTION_MANAGEMENT = "deposit__v1__collection";
}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/deposit/listener/SubTxnTypeEventListener.java b/component-test/src/main/java/org/apache/fineract/cn/deposit/listener/SubTxnTypeEventListener.java
new file mode 100644
index 0000000..1fa5586
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/deposit/listener/SubTxnTypeEventListener.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ * http://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.
+ */
+
+package org.apache.fineract.cn.deposit.listener;
+
+import org.apache.fineract.cn.deposit.api.v1.EventConstants;
+import org.apache.fineract.cn.deposit.service.ServiceConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+
+/**
+ * @author manoj
+ */
+public class SubTxnTypeEventListener {
+ private final Logger logger;
+ private final EventRecorder eventRecorder;
+
+ @Autowired
+ public SubTxnTypeEventListener(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final EventRecorder eventRecorder) {
+ super();
+ this.logger = logger;
+ this.eventRecorder = eventRecorder;
+ }
+
+ @JmsListener(
+ destination = EventConstants.DESTINATION,
+ selector = EventConstants.SELECTOR_POST_SUB_TXN_TYPE,
+ subscription = EventConstants.DESTINATION
+ )
+ public void onCreateSubTxnType(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+ final String payload) {
+ this.logger.debug("Product definition created.");
+ this.eventRecorder.event(tenant, EventConstants.POST_SUB_TXN_TYPE, payload, String.class);
+ }
+
+
+ @JmsListener(
+ destination = EventConstants.DESTINATION,
+ selector = EventConstants.SELECTOR_PUT_SUB_TXN_TYPE,
+ subscription = EventConstants.DESTINATION
+ )
+ public void onUpdateSubTxnType(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+ final String payload) {
+ this.logger.debug("Product definition created.");
+ this.eventRecorder.event(tenant, EventConstants.PUT_SUB_TXN_TYPE, payload, String.class);
+ }
+
+
+}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/deposit/listener/TransactionEventListener.java b/component-test/src/main/java/org/apache/fineract/cn/deposit/listener/TransactionEventListener.java
new file mode 100644
index 0000000..6738f76
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/deposit/listener/TransactionEventListener.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ * http://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.
+ */
+
+package org.apache.fineract.cn.deposit.listener;
+
+import org.apache.fineract.cn.command.annotation.EventEmitter;
+import org.apache.fineract.cn.deposit.api.v1.EventConstants;
+import org.apache.fineract.cn.deposit.service.ServiceConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+
+/**
+ * @author manoj
+ */
+public class TransactionEventListener {
+
+ private final Logger logger;
+ private final EventRecorder eventRecorder;
+
+ @Autowired
+ public TransactionEventListener(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final EventRecorder eventRecorder) {
+ super();
+ this.logger = logger;
+ this.eventRecorder = eventRecorder;
+ }
+
+ @JmsListener(
+ destination = EventConstants.DESTINATION,
+ selector = EventConstants.SELECTOR_POST_TXN,
+ subscription = EventConstants.DESTINATION
+ )
+ public void onPostTxn(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+ final String payload) {
+ this.logger.debug("Product definition created.");
+ this.eventRecorder.event(tenant, EventConstants.POST_TXN, payload, String.class);
+ }
+
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/TransactionCommandHandler.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/TransactionCommandHandler.java
index d9a4db0..4851a35 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/TransactionCommandHandler.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/TransactionCommandHandler.java
@@ -21,22 +21,19 @@ package org.apache.fineract.cn.deposit.service.internal.command.handler;
import org.apache.fineract.cn.command.annotation.Aggregate;
import org.apache.fineract.cn.command.annotation.CommandHandler;
import org.apache.fineract.cn.command.annotation.CommandLogLevel;
+import org.apache.fineract.cn.command.annotation.EventEmitter;
+import org.apache.fineract.cn.deposit.api.v1.EventConstants;
import org.apache.fineract.cn.deposit.api.v1.transaction.domain.data.TransactionResponseData;
import org.apache.fineract.cn.deposit.service.ServiceConstants;
import org.apache.fineract.cn.deposit.service.internal.command.TransactionCommand;
-import org.apache.fineract.cn.deposit.service.internal.command.TransactionProcessedCommand;
-import org.apache.fineract.cn.deposit.service.internal.repository.ProductInstanceEntity;
import org.apache.fineract.cn.deposit.service.internal.service.TransactionService;
-import org.apache.fineract.cn.lang.ServiceException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotNull;
-import java.time.Clock;
-import java.time.LocalDateTime;
-import java.util.Optional;
@Aggregate
public class TransactionCommandHandler {
@@ -53,7 +50,9 @@ public class TransactionCommandHandler {
@NotNull
@Transactional
@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+ @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_TXN)
public TransactionResponseData performTransfer(@NotNull TransactionCommand command) {
+
switch (command.getAction()) {
case WITHDRAWAL: {
//command = dataValidator.validatePrepareTransfer(command);
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java
index 97a3ac0..7c6753c 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java
@@ -61,7 +61,6 @@ import java.util.stream.Collectors;
public class TransactionService {
private final Logger logger;
private final LedgerManager ledgerManager;
- private final ProductInstanceService productInstanceService;
private final ProductDefinitionService productDefinitionService;
private final ActionService actionService;
private final SubTxnTypesService subTxnTypesService;
@@ -73,12 +72,10 @@ public class TransactionService {
@Autowired
public TransactionService(@Qualifier(ServiceConstants.LOGGER_NAME) Logger logger, LedgerManager ledgerManager,
- ProductInstanceService productInstanceService,
ProductDefinitionService productDefinitionService, ActionService actionService,
SubTxnTypesService subTxnTypesService, TransactionRepository transactionRepository, ProductInstanceRepository productInstanceRepository) {
this.logger = logger;
this.ledgerManager = ledgerManager;
- this.productInstanceService = productInstanceService;
this.productDefinitionService = productDefinitionService;
this.actionService = actionService;
this.subTxnTypesService = subTxnTypesService;
@@ -92,7 +89,7 @@ public class TransactionService {
AccountWrapper accountWrapper = validateAndGetAccount(request, request.getAccountId(), TransactionTypeEnum.WITHDRAWAL);
LocalDateTime transactionDate = getNow();
//get txntype charges
- List<Charge> charges = getCharges(accountWrapper.account.getIdentifier(), TransactionTypeEnum.WITHDRAWAL);
+ List<Charge> charges = getCharges(accountWrapper.productDefinition, TransactionTypeEnum.WITHDRAWAL);
//todo: get subTxnType charges
TransactionEntity txn = doWithdraw(request, accountWrapper, charges, getNow(), request.getAccountId());
@@ -109,7 +106,7 @@ public class TransactionService {
AccountWrapper accountWrapper = validateAndGetAccount(request, request.getAccountId(), TransactionTypeEnum.DEPOSIT);
LocalDateTime transactionDate = getNow();
//get txntype charges
- List<Charge> charges = getCharges(accountWrapper.account.getIdentifier(), TransactionTypeEnum.DEPOSIT);
+ List<Charge> charges = getCharges(accountWrapper.productDefinition, TransactionTypeEnum.DEPOSIT);
//todo: get subTxnType charges
TransactionEntity txn = doDeposit(request, accountWrapper, charges, getNow(), request.getAccountId());
@@ -124,7 +121,7 @@ public class TransactionService {
AccountWrapper toAccountWrapper = validateAndGetAccount(request, request.getToAccountId(), TransactionTypeEnum.DEPOSIT);
LocalDateTime transactionDate = getNow();
//get txntype charges
- List<Charge> charges = getCharges(fromAccountWrapper.account.getIdentifier(), TransactionTypeEnum.ACCOUNT_TRANSFER);
+ List<Charge> charges = getCharges(fromAccountWrapper.productDefinition, TransactionTypeEnum.ACCOUNT_TRANSFER);
//todo: get subTxnType charges
TransactionEntity txn = doWithdraw(request, fromAccountWrapper, charges, getNow(), request.getFromAccountId());
@@ -139,7 +136,9 @@ public class TransactionService {
List<Charge> charges, LocalDateTime transactionDate, String accountId) {
BigDecimal amount = request.getAmount().getAmount();
- TransactionEntity txn = createTransaction(request,TransactionTypeEnum.DEPOSIT, transactionDate, CREDIT, null, accountId);
+ TransactionEntity txn = createTransaction(request,TransactionTypeEnum.DEPOSIT, transactionDate, CREDIT,
+ null, accountId, accountWrapper.instance);
+
String debitAccountIdentifier = accountWrapper.productDefinition.getCashAccountIdentifier();
/* if subtxn is provided and it has an account configured the do debit that account*/
if(StringUtils.isNotBlank(request.getSubTxnId())){
@@ -149,6 +148,8 @@ public class TransactionService {
if (subTxnTypeOpt.get().getLedgerAccount() != null) {
debitAccountIdentifier = subTxnTypeOpt.get().getLedgerAccount();
}
+ }else{
+ throw ServiceException.notFound("Sub Txn Type {0} not found.", request.getSubTxnId());
}
}
final JournalEntry journalEntry = createJournalEntry(txn.getIdentifier(), TransactionTypeEnum.DEPOSIT.getCode(),
@@ -180,7 +181,8 @@ public class TransactionService {
List<Charge> charges, LocalDateTime transactionDate, String accountId) {
BigDecimal amount = request.getAmount().getAmount();
- TransactionEntity txn = createTransaction(request, TransactionTypeEnum.WITHDRAWAL, transactionDate, DEBIT, null, accountId);
+ TransactionEntity txn = createTransaction(request, TransactionTypeEnum.WITHDRAWAL, transactionDate, DEBIT,
+ null, accountId, accountWrapper.instance);
String creditAccountIdentifier = accountWrapper.productDefinition.getCashAccountIdentifier();
/* if subtxn is provided and it has an account configured the do credit that account*/
@@ -191,6 +193,8 @@ public class TransactionService {
if (subTxnTypeOpt.get().getLedgerAccount() != null) {
creditAccountIdentifier = subTxnTypeOpt.get().getLedgerAccount();
}
+ }else{
+ throw ServiceException.notFound("Sub Txn Type {0} not found.", request.getSubTxnId());
}
}
final JournalEntry journalEntry = createJournalEntry(txn.getIdentifier(), TransactionTypeEnum.WITHDRAWAL.getCode(),
@@ -239,7 +243,8 @@ public class TransactionService {
for(Charge charge : charges){
addCreditor(charge.getIncomeAccountIdentifier(), calcChargeAmount(amount, charge).doubleValue(), creditors);
addDebtor(accountWrapper.account.getIdentifier(), calcChargeAmount(amount, charge).doubleValue(), debtors);
- createTransaction(request,TransactionTypeEnum.CHARGES_PAYMENT, getNow(), DEBIT, txn, accountId);
+ createTransaction(request,TransactionTypeEnum.CHARGES_PAYMENT, getNow(), DEBIT, txn,
+ accountId, accountWrapper.instance);
}
}
@@ -250,8 +255,10 @@ public class TransactionService {
Account account = ledgerManager.findAccount(accountId);
validateAccount(request.getAmount(), account);
- ProductInstance product = productInstanceService.findByAccountIdentifier(accountId).get();
- ProductDefinition productDefinition = productDefinitionService.findProductDefinition(product.getProductIdentifier()).get();
+ ProductInstanceEntity instance = productInstanceRepository.findByAccountIdentifier(accountId).orElseThrow(
+ () -> ServiceException.notFound("Account {0} not found", accountId)
+ );
+ ProductDefinition productDefinition = productDefinitionService.findProductDefinition(instance.getProductDefinition().getIdentifier()).get();
Currency currency = productDefinition.getCurrency();
if (!currency.getCode().equals(request.getAmount().getCurrency()))
@@ -263,7 +270,7 @@ public class TransactionService {
if (txnType == TransactionTypeEnum.WITHDRAWAL && withdrawableBalance < request.getAmount().getAmount().doubleValue())
throw new UnsupportedOperationException();
- return new AccountWrapper(account, product, productDefinition, withdrawableBalance);
+ return new AccountWrapper(account, instance, productDefinition, withdrawableBalance);
}
Double getWithdrawableBalance(Account account, ProductDefinition productDefinition) {
@@ -278,8 +285,10 @@ public class TransactionService {
String accountId = account.getIdentifier();
if (account.getHolders() != null) { // customer account
- ProductInstance product = productInstanceService.findByAccountIdentifier(accountId).get();
- ProductDefinition productDefinition = productDefinitionService.findProductDefinition(product.getProductIdentifier()).get();
+ ProductInstanceEntity instance = productInstanceRepository.findByAccountIdentifier(accountId).orElseThrow(
+ () -> ServiceException.notFound("Account {0} not found", accountId)
+ );
+ ProductDefinition productDefinition = productDefinitionService.findProductDefinition(instance.getProductDefinition().getIdentifier()).get();
if (!Boolean.TRUE.equals(productDefinition.getActive()))
throw new UnsupportedOperationException("Product Definition is inactive");
@@ -296,7 +305,7 @@ public class TransactionService {
throw new UnsupportedOperationException("Account is in state " + account.getState());
}
- public List<Charge> getCharges(String accountIdentifier, TransactionTypeEnum transactionType) {
+ public List<Charge> getCharges(ProductDefinition productDefinition, TransactionTypeEnum transactionType) {
List<Action> actions = actionService.fetchActions();
List<String> actionIds = actions
@@ -305,9 +314,6 @@ public class TransactionService {
.map(Action::getIdentifier)
.collect(Collectors.toList());
- ProductInstance product = productInstanceService.findByAccountIdentifier(accountIdentifier).get();
- ProductDefinition productDefinition = productDefinitionService.findProductDefinition(product.getProductIdentifier()).get();
-
return productDefinition.getCharges()
.stream()
.filter(charge -> actionIds.contains(charge.getActionIdentifier()))
@@ -374,7 +380,8 @@ public class TransactionService {
private TransactionEntity createTransaction(TransactionRequestData request, TransactionTypeEnum txnType,
LocalDateTime transactionDate, String tranType,
- TransactionEntity parent, String accountId) {
+ TransactionEntity parent, String accountId,
+ ProductInstanceEntity productInstanceEntity) {
TransactionEntity txn = new TransactionEntity();
UUID uuid=UUID.randomUUID();
@@ -401,6 +408,8 @@ public class TransactionService {
txn.setType(tranType);
txn.setParentTransaction(parent);
transactionRepository.save(txn);
+ productInstanceEntity.setLastTransactionDate(transactionDate);
+ this.productInstanceRepository.save(productInstanceEntity);
return txn;
}
@@ -416,6 +425,7 @@ public class TransactionService {
this.productInstanceRepository.save(productInstanceEntity);
}
+
public List<StatementResponse> fetchStatement(String accountId,
LocalDateTime fromDateTime,
LocalDateTime toDateTime) {
@@ -447,15 +457,16 @@ public class TransactionService {
@NotNull
private final Account account;
@NotNull
- private final ProductInstance product;
+ private final ProductInstanceEntity instance;
@NotNull
private final ProductDefinition productDefinition;
@NotNull
private final Double withdrawableBalance;
- public AccountWrapper(Account account, ProductInstance product, ProductDefinition productDefinition, Double withdrawableBalance) {
+ public AccountWrapper(Account account, ProductInstanceEntity instance,
+ ProductDefinition productDefinition, Double withdrawableBalance) {
this.account = account;
- this.product = product;
+ this.instance = instance;
this.productDefinition = productDefinition;
this.withdrawableBalance = withdrawableBalance;
}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/CollectionsRestController.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/CollectionsRestController.java
index 3c0b30b..e33616b 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/CollectionsRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/CollectionsRestController.java
@@ -50,7 +50,7 @@ public class CollectionsRestController {
this.commandGateway = commandGateway;
this.collectionsService = collectionsService;
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.COLLECTION_MANAGEMENT)
@RequestMapping(
value = "",
method = RequestMethod.POST,
@@ -68,7 +68,7 @@ public class CollectionsRestController {
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.COLLECTION_MANAGEMENT)
@RequestMapping(
value = "/{collectionsReference}",
method = RequestMethod.PUT,
@@ -85,7 +85,7 @@ public class CollectionsRestController {
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.COLLECTION_MANAGEMENT)
@RequestMapping(
value = "/{collectionsReference}",
method = RequestMethod.GET,
@@ -99,6 +99,4 @@ public class CollectionsRestController {
CollectionsResponse result = collectionsService.fetchCollection(collectionsReference);
return ResponseEntity.ok(result);
}
-
-
}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java
index f0cc9fb..135ebf5 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java
@@ -46,6 +46,7 @@ import org.apache.fineract.cn.lang.ServiceException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@@ -68,6 +69,10 @@ public class ProductInstanceRestController {
private final ProductInstanceService productInstanceService;
private final TransactionService transactionService;
+
+ @Value("${config.txnMaxRetry}")
+ private Integer txnMaxRetry;
+
@Autowired
public ProductInstanceRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
final CommandGateway commandGateway,
@@ -88,9 +93,28 @@ public class ProductInstanceRestController {
produces = MediaType.APPLICATION_JSON_VALUE
)
@ResponseBody
- public ResponseEntity<Void> create(@RequestBody @Valid final ProductInstance productInstance) {
- this.commandGateway.process(new CreateProductInstanceCommand(productInstance));
- return ResponseEntity.accepted().build();
+ public ResponseEntity<Void> create(@RequestBody @Valid final ProductInstance productInstance) throws Throwable{
+ int retryCount = 0;
+ Exception e = null;
+ do {
+ retryCount++;
+ logger.info("Try transaction : " + retryCount + " of " + txnMaxRetry);
+ System.out.println("*******Try transaction : " + retryCount + " of " + txnMaxRetry);
+ try {
+ this.commandGateway.process(new CreateProductInstanceCommand(productInstance));
+ return ResponseEntity.accepted().build();
+ } catch (Exception ex) {
+ logger.info(ex.getClass().getCanonicalName());
+ System.out.println(ex.getClass().getCanonicalName());
+ logger.info(ex.getClass().getName());
+ System.out.println(ex.getClass().getName());
+ logger.info(ex.getMessage());
+ System.out.println(ex.getMessage());
+ e=ex;
+ }
+ } while (retryCount < txnMaxRetry);
+ //throw the last exception
+ throw e;
}
@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/SubTxnTypeRestController.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/SubTxnTypeRestController.java
index 8a875f4..53998e2 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/SubTxnTypeRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/SubTxnTypeRestController.java
@@ -57,7 +57,7 @@ public class SubTxnTypeRestController {
this.service = service;
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEF_SUB_TXN_MANAGEMENT)
@RequestMapping(
value = "",
method = RequestMethod.POST,
@@ -78,7 +78,7 @@ public class SubTxnTypeRestController {
return ResponseEntity.accepted().build();
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEF_SUB_TXN_MANAGEMENT)
@RequestMapping(
value = "",
method = RequestMethod.GET,
@@ -92,7 +92,7 @@ public class SubTxnTypeRestController {
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEF_SUB_TXN_MANAGEMENT)
@RequestMapping(
value = "/{identifier}",
method = RequestMethod.GET,
@@ -110,7 +110,7 @@ public class SubTxnTypeRestController {
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEF_SUB_TXN_MANAGEMENT)
@RequestMapping(
value = "/{identifier}",
method = RequestMethod.PUT,
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/TransactionRestController.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/TransactionRestController.java
index 3b6e278..16ae9f0 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/TransactionRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/TransactionRestController.java
@@ -36,6 +36,7 @@ import org.apache.fineract.cn.lang.ServiceException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -50,6 +51,10 @@ public class TransactionRestController {
private final CommandGateway commandGateway;
private final SubTxnTypesService service;
+ @Value("${config.txnMaxRetry}")
+ private Integer txnMaxRetry;
+
+
@Autowired
public TransactionRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
CommandGateway commandGateway,
@@ -59,7 +64,7 @@ public class TransactionRestController {
this.service = service;
}
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.TXN_MANAGEMENT)
@RequestMapping(
value = "",
method = RequestMethod.POST,
@@ -70,10 +75,29 @@ public class TransactionRestController {
@ResponseBody
ResponseEntity<TransactionResponseData> performTxn(@RequestParam("action") String action, @RequestBody TransactionRequestData requestData)
throws Throwable {
- CommandCallback<TransactionResponseData> result = commandGateway.process(new TransactionCommand(requestData, TransactionActionType.valueOf(action)),
- TransactionResponseData.class);
+ int retryCount = 0;
+ Exception e = null;
+ do {
+ retryCount++;
+ logger.info("Try transaction : " + retryCount + " of " + txnMaxRetry);
+ System.out.println("*******Try transaction : " + retryCount + " of " + txnMaxRetry);
+ try {
+ CommandCallback<TransactionResponseData> result = commandGateway.process(new TransactionCommand(requestData, TransactionActionType.valueOf(action)),
+ TransactionResponseData.class);
- return ResponseEntity.ok(result.get());
+ return ResponseEntity.ok(result.get());
+ } catch (Exception ex) {
+ logger.info(ex.getClass().getCanonicalName());
+ System.out.println(ex.getClass().getCanonicalName());
+ logger.info(ex.getClass().getName());
+ System.out.println(ex.getClass().getName());
+ logger.info(ex.getMessage());
+ System.out.println(ex.getMessage());
+ e=ex;
+ }
+ } while (retryCount < txnMaxRetry);
+ //throw the last exception
+ throw e;
}
}
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index 7a6ef48..94b23ec 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -78,5 +78,6 @@ config:
fixedAccountId: true
otpTokenLength: 6
tokenExpiryInSeconds: 172800
+ txnMaxRetry : 5