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 159eff0ad4 FINERACT-2309: Emit external events on document upload and 
delete
159eff0ad4 is described below

commit 159eff0ad4ff90d275a8d5c68a2d91bb7f94a2a3
Author: Abhinav Cillanki <[email protected]>
AuthorDate: Sat Jun 14 13:04:12 2025 +0530

    FINERACT-2309: Emit external events on document upload and delete
---
 .../src/main/avro/document/v1/DocumentDataV1.avsc  |  80 +++++++++++++++++
 ...umentWritePlatformServiceJpaRepositoryImpl.java |   9 +-
 .../domain/document/DocumentBusinessEvent.java     |  41 +++++++++
 .../document/DocumentCreatedBusinessEvent.java     |  35 ++++++++
 .../document/DocumentDeletedBusinessEvent.java     |  35 ++++++++
 .../mapper/document/DocumentDataMapper.java        |  30 +++++++
 .../document/DocumentBusinessEventSerializer.java  |  89 ++++++++++++++++++
 .../db/changelog/tenant/changelog-tenant.xml       |   1 +
 .../0184_add_document_event_configuration.xml      |  35 ++++++++
 ...nalEventConfigurationValidationServiceTest.java |  40 ++++-----
 .../DocumentBusinessEventSerializerTest.java       | 100 +++++++++++++++++++++
 .../common/ExternalEventConfigurationHelper.java   |  10 +++
 12 files changed, 484 insertions(+), 21 deletions(-)

diff --git 
a/fineract-avro-schemas/src/main/avro/document/v1/DocumentDataV1.avsc 
b/fineract-avro-schemas/src/main/avro/document/v1/DocumentDataV1.avsc
new file mode 100644
index 0000000000..6c09870653
--- /dev/null
+++ b/fineract-avro-schemas/src/main/avro/document/v1/DocumentDataV1.avsc
@@ -0,0 +1,80 @@
+{
+    "name": "DocumentDataV1",
+    "namespace": "org.apache.fineract.avro.document.v1",
+    "doc": "Metadata emitted by DocumentCreatedBusinessEvent when a file is 
stored in Fineract.",
+    "type": "record",
+    "fields": [
+        {
+            "default": null,
+            "name": "id",
+            "type": [
+                "null",
+                "long"
+            ]
+        },
+        {
+            "default": null,
+            "name": "parentEntityType",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "parentEntityId",
+            "type": [
+                "null",
+                "long"
+            ]
+        },
+        {
+            "default": null,
+            "name": "name",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "fileName",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "size",
+            "type": [
+                "null",
+                "long"
+            ]
+        },
+        {
+            "default": null,
+            "name": "type",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "description",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "storageType",
+            "type": [
+                "null",
+                "int"
+            ]
+        }
+    ]
+}
diff --git 
a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
index 869de535e3..e87575d658 100644
--- 
a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
@@ -31,6 +31,9 @@ import 
org.apache.fineract.infrastructure.documentmanagement.domain.StorageType;
 import 
org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException;
 import 
org.apache.fineract.infrastructure.documentmanagement.exception.DocumentNotFoundException;
 import 
org.apache.fineract.infrastructure.documentmanagement.exception.InvalidEntityTypeForDocumentManagementException;
+import 
org.apache.fineract.infrastructure.event.business.domain.document.DocumentCreatedBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.document.DocumentDeletedBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
 import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,13 +51,15 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl 
implements DocumentWr
     private final PlatformSecurityContext context;
     private final DocumentRepository documentRepository;
     private final ContentRepositoryFactory contentRepositoryFactory;
+    private final BusinessEventNotifierService businessEventNotifierService;
 
     @Autowired
     public DocumentWritePlatformServiceJpaRepositoryImpl(final 
PlatformSecurityContext context, final DocumentRepository documentRepository,
-            final ContentRepositoryFactory documentStoreFactory) {
+            final ContentRepositoryFactory documentStoreFactory, 
BusinessEventNotifierService businessEventNotifierService) {
         this.context = context;
         this.documentRepository = documentRepository;
         this.contentRepositoryFactory = documentStoreFactory;
+        this.businessEventNotifierService = businessEventNotifierService;
     }
 
     @Transactional
@@ -78,6 +83,7 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl 
implements DocumentWr
                     documentCommand.getDescription(), fileLocation, 
contentRepository.getStorageType());
 
             this.documentRepository.saveAndFlush(document);
+            businessEventNotifierService.notifyPostBusinessEvent(new 
DocumentCreatedBusinessEvent(document));
 
             return document.getId();
         } catch (final JpaSystemException | DataIntegrityViolationException 
dve) {
@@ -158,6 +164,7 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl 
implements DocumentWr
 
         final ContentRepository contentRepository = 
this.contentRepositoryFactory.getRepository(document.storageType());
         contentRepository.deleteFile(document.getLocation());
+        businessEventNotifierService.notifyPostBusinessEvent(new 
DocumentDeletedBusinessEvent(document));
         return CommandProcessingResult.resourceResult(document.getId());
     }
 
diff --git 
a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentBusinessEvent.java
 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentBusinessEvent.java
new file mode 100644
index 0000000000..dc0aca7d43
--- /dev/null
+++ 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentBusinessEvent.java
@@ -0,0 +1,41 @@
+/**
+ * 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.infrastructure.event.business.domain.document;
+
+import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
+import 
org.apache.fineract.infrastructure.event.business.domain.AbstractBusinessEvent;
+
+public abstract class DocumentBusinessEvent extends 
AbstractBusinessEvent<Document> {
+
+    private static final String CATEGORY = "Document";
+
+    protected DocumentBusinessEvent(Document value) {
+        super(value);
+    }
+
+    @Override
+    public String getCategory() {
+        return CATEGORY; // e.g. will appear as “Document”
+    }
+
+    @Override
+    public Long getAggregateRootId() {
+        return get().getId(); // primary-key of the uploaded doc
+    }
+}
diff --git 
a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentCreatedBusinessEvent.java
 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentCreatedBusinessEvent.java
new file mode 100644
index 0000000000..b323857e7a
--- /dev/null
+++ 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentCreatedBusinessEvent.java
@@ -0,0 +1,35 @@
+/**
+ * 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.infrastructure.event.business.domain.document;
+
+import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
+
+public class DocumentCreatedBusinessEvent extends DocumentBusinessEvent {
+
+    private static final String TYPE = "DocumentCreatedBusinessEvent";
+
+    public DocumentCreatedBusinessEvent(Document value) {
+        super(value);
+    }
+
+    @Override
+    public String getType() {
+        return TYPE;
+    }
+}
diff --git 
a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentDeletedBusinessEvent.java
 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentDeletedBusinessEvent.java
new file mode 100644
index 0000000000..14184b59e2
--- /dev/null
+++ 
b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentDeletedBusinessEvent.java
@@ -0,0 +1,35 @@
+/**
+ * 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.infrastructure.event.business.domain.document;
+
+import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
+
+public class DocumentDeletedBusinessEvent extends DocumentBusinessEvent {
+
+    private static final String TYPE = "DocumentDeletedBusinessEvent";
+
+    public DocumentDeletedBusinessEvent(Document value) {
+        super(value);
+    }
+
+    @Override
+    public String getType() {
+        return TYPE;
+    }
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/document/DocumentDataMapper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/document/DocumentDataMapper.java
new file mode 100644
index 0000000000..04a8093bdc
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/document/DocumentDataMapper.java
@@ -0,0 +1,30 @@
+/**
+ * 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.infrastructure.event.external.service.serialization.mapper.document;
+
+import org.apache.fineract.avro.document.v1.DocumentDataV1;
+import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData;
+import 
org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroMapperConfig;
+import org.mapstruct.Mapper;
+
+@Mapper(config = AvroMapperConfig.class)
+public interface DocumentDataMapper {
+
+    DocumentDataV1 map(DocumentData source);
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/document/DocumentBusinessEventSerializer.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/document/DocumentBusinessEventSerializer.java
new file mode 100644
index 0000000000..a2b68d1cfb
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/document/DocumentBusinessEventSerializer.java
@@ -0,0 +1,89 @@
+/**
+ * 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.infrastructure.event.external.service.serialization.serializer.document;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.avro.generic.GenericContainer;
+import org.apache.fineract.avro.document.v1.DocumentDataV1;
+import org.apache.fineract.avro.generator.ByteBufferSerializable;
+import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData;
+import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
+import 
org.apache.fineract.infrastructure.documentmanagement.service.DocumentReadPlatformService;
+import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.document.DocumentBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.document.DocumentCreatedBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.document.DocumentDeletedBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.external.service.serialization.mapper.document.DocumentDataMapper;
+import 
org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class DocumentBusinessEventSerializer implements 
BusinessEventSerializer {
+
+    private static final Logger log = 
LoggerFactory.getLogger(DocumentBusinessEventSerializer.class);
+    private final DocumentReadPlatformService service;
+    private final DocumentDataMapper mapper;
+
+    @Override
+    public <T> boolean canSerialize(BusinessEvent<T> event) {
+        return event instanceof DocumentCreatedBusinessEvent || event 
instanceof DocumentDeletedBusinessEvent;
+    }
+
+    @Override
+    public <T> ByteBufferSerializable toAvroDTO(BusinessEvent<T> rawEvent) {
+
+        DocumentBusinessEvent event = (DocumentBusinessEvent) rawEvent;
+        Document entity = event.get(); // domain entity
+
+        DocumentData dto = null;
+        if (rawEvent instanceof DocumentCreatedBusinessEvent) {
+            try {
+                dto = service.retrieveDocument(entity.getParentEntityType(), 
entity.getParentEntityId(), entity.getId());
+            } catch (Exception ex) {
+                // log at DEBUG and fall back to entity mapping
+                log.debug("DocumentData not found, falling back to entity", 
ex);
+            }
+        }
+
+        // If we have the DTO, let MapStruct do the work. Otherwise, build 
from the entity
+
+        DocumentDataV1 avro;
+        if (dto != null) {
+            avro = mapper.map(dto);
+        } else {
+            avro = 
DocumentDataV1.newBuilder().setId(entity.getId()).setParentEntityType(entity.getParentEntityType())
+                    
.setParentEntityId(entity.getParentEntityId()).setName(entity.getName()).setFileName(entity.getFileName())
+                    
.setSize(entity.getSize()).setType(entity.getType()).setDescription(entity.getDescription()).build();
+        }
+
+        Integer storageTypeCode = (dto != null && dto.getStorageType() != null 
&& dto.storageType() != null) ? dto.getStorageType()
+                : (entity.storageType() != null ? 
entity.storageType().getValue() : null);
+        avro.setStorageType(storageTypeCode);
+
+        return avro;
+    }
+
+    @Override
+    public Class<? extends GenericContainer> getSupportedSchema() {
+        return DocumentDataV1.class;
+    }
+}
diff --git 
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml 
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
index 50b68a01f9..a66325bad0 100644
--- 
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
+++ 
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
@@ -202,4 +202,5 @@
     <include 
file="parts/0181_add_capitalized_income_amortization_adjustment_transaction.xml"
 relativeToChangelogFile="true" />
     <include 
file="parts/0182_transaction_summary_with_asset_owner_report_fix_charge_reason_and_add_buyback_intermediate.xml"
 relativeToChangelogFile="true" />
     <include 
file="parts/0183_add_LoanCapitalizedIncomeTransactionCreatedBusinessEvent.xml" 
relativeToChangelogFile="true" />
+    <include file="parts/0184_add_document_event_configuration.xml" 
relativeToChangelogFile="true" />
 </databaseChangeLog>
diff --git 
a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0184_add_document_event_configuration.xml
 
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0184_add_document_event_configuration.xml
new file mode 100644
index 0000000000..096b403282
--- /dev/null
+++ 
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0184_add_document_event_configuration.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog";
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+                   
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog 
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd";>
+    <changeSet id="1" author="fineract">
+        <insert tableName="m_external_event_configuration">
+            <column name="type" value="DocumentCreatedBusinessEvent"/>
+            <column name="enabled" valueBoolean="false"/>
+        </insert>
+        <insert tableName="m_external_event_configuration">
+            <column name="type" value="DocumentDeletedBusinessEvent"/>
+            <column name="enabled" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+</databaseChangeLog>
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
index 5d5e47edde..6e56c097f1 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
@@ -67,20 +67,20 @@ public class 
ExternalEventConfigurationValidationServiceTest {
 
         // given
         List<String> configurations = 
Arrays.asList("CentersCreateBusinessEvent", "ClientActivateBusinessEvent",
-                "ClientCreateBusinessEvent", "ClientRejectBusinessEvent", 
"FixedDepositAccountCreateBusinessEvent",
-                "GroupsCreateBusinessEvent", 
"LoanAcceptTransferBusinessEvent", "LoanAddChargeBusinessEvent",
-                "LoanAdjustTransactionBusinessEvent", 
"LoanApplyOverdueChargeBusinessEvent", "LoanApprovedBusinessEvent",
-                "LoanBalanceChangedBusinessEvent", 
"LoanChargebackTransactionBusinessEvent", "LoanChargePaymentPostBusinessEvent",
-                "LoanChargePaymentPreBusinessEvent", 
"LoanChargeRefundBusinessEvent", "LoanCloseAsRescheduleBusinessEvent",
-                "LoanCloseBusinessEvent", "LoanCreatedBusinessEvent", 
"LoanCreditBalanceRefundPostBusinessEvent",
-                "LoanCreditBalanceRefundPreBusinessEvent", 
"LoanDeleteChargeBusinessEvent", "LoanDisbursalBusinessEvent",
-                "LoanDisbursalTransactionBusinessEvent", 
"LoanForeClosurePostBusinessEvent", "LoanForeClosurePreBusinessEvent",
-                "LoanInitiateTransferBusinessEvent", 
"LoanInterestRecalculationBusinessEvent", "LoanProductCreateBusinessEvent",
-                "LoanReassignOfficerBusinessEvent", 
"LoanRefundPostBusinessEvent", "LoanRefundPreBusinessEvent",
-                "LoanRejectedBusinessEvent", 
"LoanRejectTransferBusinessEvent", "LoanRemoveOfficerBusinessEvent",
-                "LoanRepaymentDueBusinessEvent", 
"LoanRepaymentOverdueBusinessEvent", 
"LoanRescheduledDueCalendarChangeBusinessEvent",
-                "LoanRescheduledDueHolidayBusinessEvent", 
"LoanScheduleVariationsAddedBusinessEvent",
-                "LoanScheduleVariationsDeletedBusinessEvent", 
"LoanStatusChangedBusinessEvent",
+                "ClientCreateBusinessEvent", "ClientRejectBusinessEvent", 
"DocumentCreatedBusinessEvent", "DocumentDeletedBusinessEvent",
+                "FixedDepositAccountCreateBusinessEvent", 
"GroupsCreateBusinessEvent", "LoanAcceptTransferBusinessEvent",
+                "LoanAddChargeBusinessEvent", 
"LoanAdjustTransactionBusinessEvent", "LoanApplyOverdueChargeBusinessEvent",
+                "LoanApprovedBusinessEvent", 
"LoanBalanceChangedBusinessEvent", "LoanChargebackTransactionBusinessEvent",
+                "LoanChargePaymentPostBusinessEvent", 
"LoanChargePaymentPreBusinessEvent", "LoanChargeRefundBusinessEvent",
+                "LoanCloseAsRescheduleBusinessEvent", 
"LoanCloseBusinessEvent", "LoanCreatedBusinessEvent",
+                "LoanCreditBalanceRefundPostBusinessEvent", 
"LoanCreditBalanceRefundPreBusinessEvent", "LoanDeleteChargeBusinessEvent",
+                "LoanDisbursalBusinessEvent", 
"LoanDisbursalTransactionBusinessEvent", "LoanForeClosurePostBusinessEvent",
+                "LoanForeClosurePreBusinessEvent", 
"LoanInitiateTransferBusinessEvent", "LoanInterestRecalculationBusinessEvent",
+                "LoanProductCreateBusinessEvent", 
"LoanReassignOfficerBusinessEvent", "LoanRefundPostBusinessEvent",
+                "LoanRefundPreBusinessEvent", "LoanRejectedBusinessEvent", 
"LoanRejectTransferBusinessEvent",
+                "LoanRemoveOfficerBusinessEvent", 
"LoanRepaymentDueBusinessEvent", "LoanRepaymentOverdueBusinessEvent",
+                "LoanRescheduledDueCalendarChangeBusinessEvent", 
"LoanRescheduledDueHolidayBusinessEvent",
+                "LoanScheduleVariationsAddedBusinessEvent", 
"LoanScheduleVariationsDeletedBusinessEvent", "LoanStatusChangedBusinessEvent",
                 "LoanTransactionGoodwillCreditPostBusinessEvent", 
"LoanTransactionGoodwillCreditPreBusinessEvent",
                 "LoanTransactionMakeRepaymentPostBusinessEvent", 
"LoanTransactionMakeRepaymentPreBusinessEvent",
                 "LoanTransactionMerchantIssuedRefundPostBusinessEvent", 
"LoanTransactionMerchantIssuedRefundPreBusinessEvent",
@@ -157,12 +157,12 @@ public class 
ExternalEventConfigurationValidationServiceTest {
 
         // given
         List<String> configurationWithMissingCentersCreateBusinessEvent = 
Arrays.asList("MockBusinessEvent", "MockBusinessEvent",
-                "ClientActivateBusinessEvent", "ClientCreateBusinessEvent", 
"ClientRejectBusinessEvent",
-                "FixedDepositAccountCreateBusinessEvent", 
"GroupsCreateBusinessEvent", "LoanAcceptTransferBusinessEvent",
-                "LoanAddChargeBusinessEvent", 
"LoanAdjustTransactionBusinessEvent", "LoanApplyOverdueChargeBusinessEvent",
-                "LoanApprovedBusinessEvent", 
"LoanBalanceChangedBusinessEvent", "LoanChargebackTransactionBusinessEvent",
-                "LoanChargePaymentPostBusinessEvent", 
"LoanChargePaymentPreBusinessEvent", "LoanChargeRefundBusinessEvent",
-                "LoanCloseAsRescheduleBusinessEvent", 
"LoanCloseBusinessEvent", "LoanCreatedBusinessEvent",
+                "ClientActivateBusinessEvent", "ClientCreateBusinessEvent", 
"ClientRejectBusinessEvent", "DocumentCreatedBusinessEvent",
+                "DocumentDeletedBusinessEvent", 
"FixedDepositAccountCreateBusinessEvent", "GroupsCreateBusinessEvent",
+                "LoanAcceptTransferBusinessEvent", 
"LoanAddChargeBusinessEvent", "LoanAdjustTransactionBusinessEvent",
+                "LoanApplyOverdueChargeBusinessEvent", 
"LoanApprovedBusinessEvent", "LoanBalanceChangedBusinessEvent",
+                "LoanChargebackTransactionBusinessEvent", 
"LoanChargePaymentPostBusinessEvent", "LoanChargePaymentPreBusinessEvent",
+                "LoanChargeRefundBusinessEvent", 
"LoanCloseAsRescheduleBusinessEvent", "LoanCloseBusinessEvent", 
"LoanCreatedBusinessEvent",
                 "LoanCreditBalanceRefundPostBusinessEvent", 
"LoanCreditBalanceRefundPreBusinessEvent", "LoanDeleteChargeBusinessEvent",
                 "LoanDisbursalBusinessEvent", 
"LoanDisbursalTransactionBusinessEvent", "LoanForeClosurePostBusinessEvent",
                 "LoanForeClosurePreBusinessEvent", 
"LoanInitiateTransferBusinessEvent", "LoanInterestRecalculationBusinessEvent",
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/document/DocumentBusinessEventSerializerTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/document/DocumentBusinessEventSerializerTest.java
new file mode 100644
index 0000000000..8bf5bf31d6
--- /dev/null
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/document/DocumentBusinessEventSerializerTest.java
@@ -0,0 +1,100 @@
+/**
+ * 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.infrastructure.event.external.service.serialization.serializer.document;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.fineract.avro.document.v1.DocumentDataV1;
+import org.apache.fineract.avro.generator.ByteBufferSerializable;
+import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData;
+import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
+import 
org.apache.fineract.infrastructure.documentmanagement.domain.StorageType;
+import 
org.apache.fineract.infrastructure.documentmanagement.service.DocumentReadPlatformService;
+import 
org.apache.fineract.infrastructure.event.business.domain.document.DocumentCreatedBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.external.service.serialization.mapper.document.DocumentDataMapper;
+import 
org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+@MockitoSettings(strictness = Strictness.LENIENT)
+@ExtendWith(MockitoExtension.class)
+class DocumentBusinessEventSerializerTest {
+
+    @Mock
+    private DocumentReadPlatformService readService;
+    @Mock
+    private DocumentDataMapper mapper;
+
+    private BusinessEventSerializer serializer;
+
+    @BeforeEach
+    void setUp() {
+        serializer = new DocumentBusinessEventSerializer(readService, mapper);
+    }
+
+    @Test
+    void documentStorageTypeIsPatchedIntoAvro() {
+
+        long docId = 42L;
+        String parentEntity = "loans";
+        long parentEntityId = 979L;
+        String name = "test_document";
+        String fileName = "test_document.pdf";
+        String fileType = "application/pdf";
+        String description = "Test document description";
+        Integer storageTypeInt = StorageType.FILE_SYSTEM.getValue();
+
+        Document document = mock(Document.class);
+        when(document.getId()).thenReturn(docId);
+        when(document.getParentEntityType()).thenReturn(parentEntity);
+        when(document.getParentEntityId()).thenReturn(parentEntityId);
+        when(document.getName()).thenReturn(name);
+        when(document.getFileName()).thenReturn(fileName);
+        when(document.getType()).thenReturn(fileType);
+        when(document.getDescription()).thenReturn(description);
+        
when(document.storageType()).thenReturn(StorageType.fromInt(storageTypeInt));
+
+        DocumentCreatedBusinessEvent event = new 
DocumentCreatedBusinessEvent(document);
+
+        DocumentData dtoFromReadService = mock(DocumentData.class);
+        when(readService.retrieveDocument(parentEntity, parentEntityId, 
docId)).thenReturn(dtoFromReadService);
+
+        DocumentDataV1 avroFromMapper = 
DocumentDataV1.newBuilder().setId(docId).setParentEntityType(parentEntity)
+                
.setParentEntityId(parentEntityId).setName(name).setFileName(fileName).setType(fileType).setDescription(description)
+                .build();
+        when(mapper.map(any(DocumentData.class))).thenReturn(avroFromMapper);
+
+        ByteBufferSerializable serialised = serializer.toAvroDTO(event);
+        assertNotNull(serialised);
+
+        DocumentDataV1 avro = (DocumentDataV1) serialised;
+
+        assertEquals(storageTypeInt, avro.getStorageType(), "Serializer must 
patch storageType taken from the domain entity");
+    }
+}
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
index acbadd414d..5a993bbf7f 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
@@ -73,6 +73,16 @@ public class ExternalEventConfigurationHelper {
         clientRejectBusinessEvent.put("enabled", false);
         defaults.add(clientRejectBusinessEvent);
 
+        Map<String, Object> documentCreatedBusinessEvent = new HashMap<>();
+        documentCreatedBusinessEvent.put("type", 
"DocumentCreatedBusinessEvent");
+        documentCreatedBusinessEvent.put("enabled", false);
+        defaults.add(documentCreatedBusinessEvent);
+
+        Map<String, Object> documentDeletedBusinessEvent = new HashMap<>();
+        documentDeletedBusinessEvent.put("type", 
"DocumentDeletedBusinessEvent");
+        documentDeletedBusinessEvent.put("enabled", false);
+        defaults.add(documentDeletedBusinessEvent);
+
         Map<String, Object> fixedDepositAccountCreateBusinessEvent = new 
HashMap<>();
         fixedDepositAccountCreateBusinessEvent.put("type", 
"FixedDepositAccountCreateBusinessEvent");
         fixedDepositAccountCreateBusinessEvent.put("enabled", false);


Reply via email to