Skip to content

Commit 2cf9981

Browse files
oleksii-novikov-onixadamsaghy
authored andcommitted
FINERACT-2181: Introduce customData field for Loan and LoanTransaction business events
1 parent ccf213a commit 2cf9981

10 files changed

Lines changed: 412 additions & 9 deletions

File tree

fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,17 @@
823823
"null",
824824
"boolean"
825825
]
826+
},
827+
{
828+
"default": null,
829+
"name": "customData",
830+
"type": [
831+
"null",
832+
{
833+
"values": "bytes",
834+
"type": "map"
835+
}
836+
]
826837
}
827838
]
828839
}

fineract-avro-schemas/src/main/avro/loan/v1/LoanTransactionDataV1.avsc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,17 @@
244244
"null",
245245
"string"
246246
]
247+
},
248+
{
249+
"default": null,
250+
"name": "customData",
251+
"type": [
252+
"null",
253+
{
254+
"values": "bytes",
255+
"type": "map"
256+
}
257+
]
247258
}
248259
]
249260
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.infrastructure.event.external.service.serialization.serializer;
20+
21+
import java.nio.ByteBuffer;
22+
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
23+
24+
public interface ExternalEventCustomDataSerializer<T extends BusinessEvent<?>> {
25+
26+
/**
27+
* Serializes the custom data from a business event into a byte buffer
28+
*
29+
* @param event
30+
* The business event containing the data to serialize
31+
* @return The serialized data as a ByteBuffer
32+
*/
33+
ByteBuffer serialize(T event);
34+
35+
/**
36+
* Returns the key used to identify this serializer's data in the custom data map
37+
*
38+
* @return The key string
39+
*/
40+
String key();
41+
42+
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public interface LoanAccountDataMapper {
3737
@Mapping(target = "settlementDate", ignore = true)
3838
@Mapping(target = "purchasePriceRatio", ignore = true)
3939
@Mapping(target = "delinquent.installmentDelinquencyBuckets", ignore = true)
40+
@Mapping(target = "customData", ignore = true)
4041
LoanAccountDataV1 map(LoanAccountData source);
4142

4243
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanTransactionDataMapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ public interface LoanTransactionDataMapper {
3030
// unpaidCharges are calculated and set explicitly based on if needed (only for charge-off transaction yet)
3131
@Mapping(target = "unpaidCharges", ignore = true)
3232
@Mapping(target = "externalOwnerId", ignore = true)
33+
@Mapping(target = "customData", ignore = true)
3334
LoanTransactionDataV1 map(LoanTransactionData source);
3435
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
*/
1919
package org.apache.fineract.infrastructure.event.external.service.serialization.serializer.loan;
2020

21+
import java.nio.ByteBuffer;
2122
import java.util.Collection;
2223
import java.util.List;
24+
import java.util.Map;
25+
import java.util.stream.Collectors;
2326
import lombok.RequiredArgsConstructor;
2427
import org.apache.avro.generic.GenericContainer;
2528
import org.apache.commons.collections4.CollectionUtils;
@@ -30,6 +33,7 @@
3033
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanBusinessEvent;
3134
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanAccountDataMapper;
3235
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
36+
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer;
3337
import org.apache.fineract.portfolio.delinquency.service.DelinquencyReadPlatformService;
3438
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
3539
import org.apache.fineract.portfolio.loanaccount.data.CollectionData;
@@ -56,6 +60,7 @@ public class LoanBusinessEventSerializer implements BusinessEventSerializer {
5660
private final LoanSummaryBalancesRepository loanSummaryBalancesRepository;
5761
@Lazy
5862
private final LoanSummaryProviderDelegate loanSummaryProviderDelegate;
63+
private final List<ExternalEventCustomDataSerializer<LoanBusinessEvent>> externalEventCustomDataSerializers;
5964

6065
@Override
6166
public <T> boolean canSerialize(BusinessEvent<T> event) {
@@ -98,13 +103,22 @@ public <T> ByteBufferSerializable toAvroDTO(BusinessEvent<T> rawEvent) {
98103
data.setLoanTermVariations(activeLoanTermVariations.stream().map(LoanTermVariations::toData).toList());
99104
}
100105

101-
LoanAccountDataV1 result = mapper.map(data);
106+
final LoanAccountDataV1 result = mapper.map(data);
102107
result.getDelinquent().setInstallmentDelinquencyBuckets(installmentsDelinquencyData);
108+
109+
result.setCustomData(collectCustomData(event));
110+
103111
return result;
104112
}
105113

106114
@Override
107115
public Class<? extends GenericContainer> getSupportedSchema() {
108116
return LoanAccountDataV1.class;
109117
}
118+
119+
private Map<String, ByteBuffer> collectCustomData(final LoanBusinessEvent event) {
120+
return externalEventCustomDataSerializers.stream().collect(Collectors.toMap(ExternalEventCustomDataSerializer::key,
121+
serializer -> serializer.serialize(event), (existing, replacement) -> replacement));
122+
}
123+
110124
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanChargeOffBusinessEventSerializer.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
package org.apache.fineract.infrastructure.event.external.service.serialization.serializer.loan;
2020

2121
import java.util.List;
22-
import org.apache.avro.generic.GenericContainer;
2322
import org.apache.fineract.avro.generator.ByteBufferSerializable;
2423
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
2524
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
2625
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargeOffPostBusinessEvent;
2726
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
2827
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanTransactionDataMapper;
2928
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.UnpaidChargeDataMapper;
29+
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer;
3030
import org.apache.fineract.portfolio.loanaccount.data.UnpaidChargeData;
3131
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
3232
import org.apache.fineract.portfolio.loanaccount.service.LoanChargePaidByReadService;
@@ -44,8 +44,9 @@ public class LoanChargeOffBusinessEventSerializer extends LoanTransactionBusines
4444

4545
public LoanChargeOffBusinessEventSerializer(LoanReadPlatformService loanReadPlatformService,
4646
LoanTransactionDataMapper loanTransactionMapper, LoanChargePaidByReadService loanChargePaidByReadService,
47-
UnpaidChargeDataMapper unpaidChargeDataMapper, LoanTransactionRepository loanTransactionRepository) {
48-
super(loanReadPlatformService, loanTransactionMapper, loanChargePaidByReadService);
47+
UnpaidChargeDataMapper unpaidChargeDataMapper, LoanTransactionRepository loanTransactionRepository,
48+
List<ExternalEventCustomDataSerializer<LoanTransactionBusinessEvent>> externalEventCustomDataSerializers) {
49+
super(loanReadPlatformService, loanTransactionMapper, loanChargePaidByReadService, externalEventCustomDataSerializers);
4950
this.unpaidChargeDataMapper = unpaidChargeDataMapper;
5051
this.loanTransactionRepository = loanTransactionRepository;
5152
}
@@ -61,11 +62,8 @@ public <T> ByteBufferSerializable toAvroDTO(BusinessEvent<T> rawEvent) {
6162
LoanTransactionBusinessEvent event = (LoanTransactionBusinessEvent) rawEvent;
6263
List<UnpaidChargeData> unpaidChargeDataList = loanTransactionRepository.fetchTotalUnpaidChargesForLoan(event.get().getLoan());
6364
transactionDataV1.setUnpaidCharges(unpaidChargeDataMapper.map(unpaidChargeDataList));
65+
transactionDataV1.setCustomData(collectCustomData(event));
6466
return transactionDataV1;
6567
}
6668

67-
@Override
68-
public Class<? extends GenericContainer> getSupportedSchema() {
69-
return LoanTransactionDataV1.class;
70-
}
7169
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanTransactionBusinessEventSerializer.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
*/
1919
package org.apache.fineract.infrastructure.event.external.service.serialization.serializer.loan;
2020

21+
import java.nio.ByteBuffer;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.stream.Collectors;
2125
import lombok.RequiredArgsConstructor;
2226
import org.apache.avro.generic.GenericContainer;
2327
import org.apache.fineract.avro.generator.ByteBufferSerializable;
@@ -26,6 +30,7 @@
2630
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
2731
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanTransactionDataMapper;
2832
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
33+
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer;
2934
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
3035
import org.apache.fineract.portfolio.loanaccount.service.LoanChargePaidByReadService;
3136
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
@@ -38,6 +43,7 @@ public class LoanTransactionBusinessEventSerializer implements BusinessEventSeri
3843
private final LoanReadPlatformService service;
3944
private final LoanTransactionDataMapper loanTransactionMapper;
4045
private final LoanChargePaidByReadService loanChargePaidByReadService;
46+
private final List<ExternalEventCustomDataSerializer<LoanTransactionBusinessEvent>> externalEventCustomDataSerializers;
4147

4248
@Override
4349
public <T> boolean canSerialize(BusinessEvent<T> event) {
@@ -51,11 +57,21 @@ public <T> ByteBufferSerializable toAvroDTO(BusinessEvent<T> rawEvent) {
5157
Long loanTransactionId = event.get().getId();
5258
LoanTransactionData transactionData = service.retrieveLoanTransaction(loanId, loanTransactionId);
5359
transactionData.setLoanChargePaidByList(loanChargePaidByReadService.fetchLoanChargesPaidByDataTransactionId(loanTransactionId));
54-
return loanTransactionMapper.map(transactionData);
60+
61+
final LoanTransactionDataV1 result = loanTransactionMapper.map(transactionData);
62+
result.setCustomData(collectCustomData(event));
63+
64+
return result;
5565
}
5666

5767
@Override
5868
public Class<? extends GenericContainer> getSupportedSchema() {
5969
return LoanTransactionDataV1.class;
6070
}
71+
72+
protected Map<String, ByteBuffer> collectCustomData(final LoanTransactionBusinessEvent event) {
73+
return externalEventCustomDataSerializers.stream().collect(Collectors.toMap(ExternalEventCustomDataSerializer::key,
74+
serializer -> serializer.serialize(event), (existing, replacement) -> replacement));
75+
}
76+
6177
}

0 commit comments

Comments
 (0)