You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ad...@apache.org on 2025/04/15 13:14:51 UTC

(fineract) branch develop updated: FINERACT-2181: Add customData field to InvestorBusinessEvent

This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 2143d35e29 FINERACT-2181: Add customData field to InvestorBusinessEvent
2143d35e29 is described below

commit 2143d35e29b2552d9dfb01c114099665953764f6
Author: Jose Alberto Hernandez <al...@black-box.local>
AuthorDate: Fri Apr 11 10:38:59 2025 -0500

    FINERACT-2181: Add customData field to InvestorBusinessEvent
---
 .../avro/loan/v1/LoanOwnershipTransferDataV1.avsc  | 11 +++++
 ...tractBusinessEventWithCustomDataSerializer.java |  0
 .../investor/InvestorBusinessEventSerializer.java  | 13 ++++--
 .../InvestorBusinessEventSerializerTest.java       | 53 +++++++++++++++++++++-
 4 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/fineract-avro-schemas/src/main/avro/loan/v1/LoanOwnershipTransferDataV1.avsc b/fineract-avro-schemas/src/main/avro/loan/v1/LoanOwnershipTransferDataV1.avsc
index e2131228c8..985170e4b9 100644
--- a/fineract-avro-schemas/src/main/avro/loan/v1/LoanOwnershipTransferDataV1.avsc
+++ b/fineract-avro-schemas/src/main/avro/loan/v1/LoanOwnershipTransferDataV1.avsc
@@ -161,6 +161,17 @@
                 "null",
                 "string"
             ]
+        },
+        {
+            "default": null,
+            "name": "customData",
+            "type": [
+                "null",
+                {
+                    "values": "bytes",
+                    "type": "map"
+                }
+            ]
         }
     ]
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/AbstractBusinessEventWithCustomDataSerializer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/AbstractBusinessEventWithCustomDataSerializer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/AbstractBusinessEventWithCustomDataSerializer.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/AbstractBusinessEventWithCustomDataSerializer.java
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java
index fc6f090139..9d7fc6db97 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java
@@ -39,7 +39,8 @@ import org.apache.fineract.avro.generic.v1.CurrencyDataV1;
 import org.apache.fineract.avro.loan.v1.LoanOwnershipTransferDataV1;
 import org.apache.fineract.avro.loan.v1.UnpaidChargeDataV1;
 import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
-import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
+import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.AbstractBusinessEventWithCustomDataSerializer;
+import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer;
 import org.apache.fineract.investor.data.ExternalTransferData;
 import org.apache.fineract.investor.data.ExternalTransferStatus;
 import org.apache.fineract.investor.data.ExternalTransferSubStatus;
@@ -52,12 +53,13 @@ import org.springframework.stereotype.Component;
 
 @Component
 @RequiredArgsConstructor
-public class InvestorBusinessEventSerializer implements BusinessEventSerializer {
+public class InvestorBusinessEventSerializer extends AbstractBusinessEventWithCustomDataSerializer<InvestorBusinessEvent> {
 
     private static final Set<ExternalTransferStatus> EXECUTED_TRANSFER_STATUSES = Set.of(ACTIVE, ACTIVE_INTERMEDIATE, BUYBACK,
             BUYBACK_INTERMEDIATE);
 
     private final ExternalAssetOwnersReadService externalAssetOwnersReadService;
+    private final List<ExternalEventCustomDataSerializer<InvestorBusinessEvent>> externalEventCustomDataSerializers;
 
     private static CurrencyDataV1 getCurrencyFromEvent(InvestorBusinessEvent event) {
         MonetaryCurrency loanCurrency = event.getLoan().getCurrency();
@@ -76,6 +78,11 @@ public class InvestorBusinessEventSerializer implements BusinessEventSerializer
         return LoanOwnershipTransferDataV1.class;
     }
 
+    @Override
+    protected List<ExternalEventCustomDataSerializer<InvestorBusinessEvent>> getExternalEventCustomDataSerializers() {
+        return externalEventCustomDataSerializers;
+    }
+
     @Override
     public <T> ByteBufferSerializable toAvroDTO(BusinessEvent<T> rawEvent) {
         InvestorBusinessEvent event = (InvestorBusinessEvent) rawEvent;
@@ -95,7 +102,7 @@ public class InvestorBusinessEventSerializer implements BusinessEventSerializer
                 .setSettlementDate(transferData.getSettlementDate().format(DEFAULT_DATE_FORMATTER))
                 .setSubmittedDate(transferData.getSettlementDate().format(DEFAULT_DATE_FORMATTER)).setType(transferType)
                 .setTransferStatus(getStatus(transferData.getStatus()))
-                .setTransferStatusReason(getTransferStatusReason(transferData.getSubStatus()));
+                .setTransferStatusReason(getTransferStatusReason(transferData.getSubStatus())).setCustomData(collectCustomData(event));
 
         if (transferData.getDetails() != null) {
             builder.setTotalOutstandingBalanceAmount(transferData.getDetails().getTotalOutstanding())
diff --git a/fineract-investor/src/test/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializerTest.java b/fineract-investor/src/test/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializerTest.java
index 19e5bdfee4..8783e9251d 100644
--- a/fineract-investor/src/test/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializerTest.java
+++ b/fineract-investor/src/test/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializerTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.investor.service.serialization.serializer.investor;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.fineract.investor.data.ExternalTransferStatus.ACTIVE;
 import static org.apache.fineract.investor.data.ExternalTransferStatus.ACTIVE_INTERMEDIATE;
 import static org.apache.fineract.investor.data.ExternalTransferStatus.BUYBACK;
@@ -30,12 +31,14 @@ import static org.apache.fineract.investor.data.ExternalTransferSubStatus.BALANC
 import static org.apache.fineract.investor.data.ExternalTransferSubStatus.BALANCE_ZERO;
 import static org.apache.fineract.investor.data.ExternalTransferSubStatus.SAMEDAY_TRANSFERS;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.math.BigDecimal;
+import java.nio.ByteBuffer;
 import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.List;
@@ -46,6 +49,7 @@ import org.apache.fineract.avro.generator.ByteBufferSerializable;
 import org.apache.fineract.avro.loan.v1.LoanOwnershipTransferDataV1;
 import org.apache.fineract.avro.loan.v1.UnpaidChargeDataV1;
 import org.apache.fineract.infrastructure.core.domain.ExternalId;
+import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer;
 import org.apache.fineract.investor.data.ExternalTransferData;
 import org.apache.fineract.investor.data.ExternalTransferDataDetails;
 import org.apache.fineract.investor.data.ExternalTransferLoanData;
@@ -53,6 +57,7 @@ import org.apache.fineract.investor.data.ExternalTransferOwnerData;
 import org.apache.fineract.investor.data.ExternalTransferStatus;
 import org.apache.fineract.investor.data.ExternalTransferSubStatus;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
+import org.apache.fineract.investor.domain.InvestorBusinessEvent;
 import org.apache.fineract.investor.domain.LoanOwnershipTransferBusinessEvent;
 import org.apache.fineract.investor.service.ExternalAssetOwnersReadService;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
@@ -69,6 +74,8 @@ public class InvestorBusinessEventSerializerTest {
     public static final String LOAN_EXTERNAL_ID = "29641fe0-0ac6-409a-bb8b-24fdf08d2891";
     public static final ExternalId TRANSFER_EXTERNAL_ID = new ExternalId("ac303982-46a5-4cea-9f71-67b69063a2b7");
 
+    private static final String CUSTOM_DATA_PREFIX = "test_data_invertor_business_event";
+
     @Test
     public void testSerializationSellOK() {
         doTest(ACTIVE, null, null, "SALE", "EXECUTED", null);
@@ -134,11 +141,16 @@ public class InvestorBusinessEventSerializerTest {
                 createExternalAssetOwnerTransfer(status, subStatus), loan);
 
         // when
-        InvestorBusinessEventSerializer serializer = new InvestorBusinessEventSerializer(mockReadService);
-        ByteBufferSerializable byteBufferSerializable = serializer.toAvroDTO(loanOwnershipTransferBusinessEvent);
+        InvestorBusinessEventSerializer serializer = new InvestorBusinessEventSerializer(mockReadService, createCustomDataForEvents());
+        final ByteBufferSerializable byteBufferSerializable = serializer.toAvroDTO(loanOwnershipTransferBusinessEvent);
+        final LoanOwnershipTransferDataV1 result = (LoanOwnershipTransferDataV1) byteBufferSerializable;
 
         // then
         verifyFields(byteBufferSerializable, expectedType, expectedStatus, expectedReason);
+        assertNotNull(result.getCustomData());
+        final Map<String, ByteBuffer> customData = result.getCustomData();
+        assertEquals(CUSTOM_DATA_PREFIX + "_1", new String(customData.get("test_key_1").array(), UTF_8));
+        assertEquals(CUSTOM_DATA_PREFIX + "_2", new String(customData.get("test_key_2").array(), UTF_8));
     }
 
     private List<LoanCharge> createMockCharges() {
@@ -232,4 +244,41 @@ public class InvestorBusinessEventSerializerTest {
         return data;
     }
 
+    private List<ExternalEventCustomDataSerializer<InvestorBusinessEvent>> createCustomDataForEvents() {
+        return List.of(new ExternalEventCustomDataSerializer<>() {
+
+            @Override
+            public ByteBuffer serialize(final InvestorBusinessEvent event) {
+                return ByteBuffer.wrap(CUSTOM_DATA_PREFIX.getBytes(UTF_8));
+            }
+
+            @Override
+            public String key() {
+                return "test_key_1";
+            }
+        }, new ExternalEventCustomDataSerializer<>() {
+
+            @Override
+            public ByteBuffer serialize(final InvestorBusinessEvent event) {
+                return ByteBuffer.wrap((CUSTOM_DATA_PREFIX + "_1").getBytes(UTF_8));
+            }
+
+            @Override
+            public String key() {
+                return "test_key_1";
+            }
+        }, new ExternalEventCustomDataSerializer<>() {
+
+            @Override
+            public ByteBuffer serialize(final InvestorBusinessEvent event) {
+                return ByteBuffer.wrap((CUSTOM_DATA_PREFIX + "_2").getBytes(UTF_8));
+            }
+
+            @Override
+            public String key() {
+                return "test_key_2";
+            }
+        });
+    }
+
 }