From ba06234f2624e642b36cafc16dc0b4888785079e Mon Sep 17 00:00:00 2001 From: viktorpavlenko Date: Thu, 26 Jun 2025 09:26:18 +0300 Subject: [PATCH] FINERACT-2242: New command processing - External Event Configuration (org.apache.fineract.infrastructure.event.external) --- ...ExternalEventConfigurationApiResource.java | 50 +++++++------- .../InternalExternalEventsApiResource.java | 40 ++++------- ... ExternalConfigurationsUpdateCommand.java} | 16 ++--- ...ternalEventConfigurationItemResponse.java} | 9 ++- .../ExternalEventConfigurationResponse.java | 40 +++++++++++ ...ernalEventConfigurationUpdateRequest.java} | 32 ++++----- ...rnalEventConfigurationUpdateResponse.java} | 15 ++++- .../external/data/ExternalEventResponse.java | 48 ++++++++++++++ ...ternalEventConfigurationUpdateHandler.java | 15 +++-- ...urationCommandFromApiJsonDeserializer.java | 55 ---------------- ...EventConfigurationReadPlatformService.java | 4 +- ...tConfigurationReadPlatformServiceImpl.java | 6 +- ...ventConfigurationWritePlatformService.java | 6 +- ...ConfigurationWritePlatformServiceImpl.java | 30 ++++----- .../service/ExternalEventService.java | 16 ++--- .../ExternalEventsConfigurationMapper.java | 4 +- .../service/InternalExternalEventService.java | 56 ++++++++-------- .../ExternalEventSuiteInitializerStep.java | 15 +++-- .../core/config/SecurityConfig.java | 11 +++- ...tConfigurationReadPlatformServiceTest.java | 14 ++-- ...ConfigurationWritePlatformServiceTest.java | 22 ++----- .../fineract/validation/messages.properties | 4 ++ .../validation/messages_en.properties | 4 ++ .../BaseLoanIntegrationTest.java | 8 +-- .../CustomSnapshotEventIntegrationTest.java | 12 ++-- .../ExternalBusinessEventTest.java | 66 +++++++++---------- ...ementToSavingsWithAutoDownPaymentTest.java | 10 +-- .../common/BusinessStepHelper.java | 8 +-- .../common/externalevents/BusinessEvent.java | 4 +- .../externalevents/ExternalEventHelper.java | 20 +++--- .../LoanAdjustTransactionBusinessEvent.java | 4 +- .../externalevents/LoanBusinessEvent.java | 4 +- .../LoanTransactionBusinessEvent.java | 4 +- ...nitiateExternalAssetOwnerTransferTest.java | 4 +- 34 files changed, 340 insertions(+), 316 deletions(-) rename fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/{ExternalEventConfigurationCommand.java => ExternalConfigurationsUpdateCommand.java} (70%) rename fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/{ExternalEventConfigurationItemData.java => ExternalEventConfigurationItemResponse.java} (82%) create mode 100644 fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationResponse.java rename fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/{service/validation/ExternalEventDTO.java => data/ExternalEventConfigurationUpdateRequest.java} (60%) rename fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/{ExternalEventConfigurationData.java => ExternalEventConfigurationUpdateResponse.java} (72%) create mode 100644 fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventResponse.java delete mode 100644 fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java index f61b3e461..204c6b3de 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java @@ -19,27 +19,25 @@ package org.apache.fineract.infrastructure.event.external.api; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; +import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; +import java.util.UUID; +import java.util.function.Supplier; import lombok.RequiredArgsConstructor; -import org.apache.fineract.commands.domain.CommandWrapper; -import org.apache.fineract.commands.service.CommandWrapperBuilder; -import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; -import org.apache.fineract.infrastructure.event.external.command.ExternalEventConfigurationCommand; -import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationData; +import org.apache.fineract.command.core.CommandPipeline; +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.infrastructure.event.external.command.ExternalConfigurationsUpdateCommand; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationResponse; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateRequest; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateResponse; import org.apache.fineract.infrastructure.event.external.service.ExternalEventConfigurationReadPlatformService; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.springframework.stereotype.Component; @RequiredArgsConstructor @@ -48,19 +46,14 @@ import org.springframework.stereotype.Component; @Tag(name = "External event configuration", description = "External event configuration enables user to enable/disable event posting to downstream message channel") public class ExternalEventConfigurationApiResource { - private static final String RESOURCE_NAME_FOR_PERMISSIONS = "EXTERNAL_EVENT_CONFIGURATION"; - - private final PlatformSecurityContext context; - private final PortfolioCommandSourceWritePlatformService commandWritePlatformService; - private final DefaultToApiJsonSerializer jsonSerializer; private final ExternalEventConfigurationReadPlatformService readPlatformService; + private final CommandPipeline commandPipeline; @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) @Operation(summary = "List all external event configurations", description = "") - public ExternalEventConfigurationData retrieveExternalEventConfiguration() { - context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); + public ExternalEventConfigurationResponse getExternalEventConfigurations() { return readPlatformService.findAllExternalEventConfigurations(); } @@ -68,12 +61,17 @@ public class ExternalEventConfigurationApiResource { @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) @Operation(summary = "Enable/Disable external events posting", description = "") - @RequestBody(required = true, content = @Content(schema = @Schema(implementation = ExternalEventConfigurationCommand.class))) - public CommandProcessingResult updateExternalEventConfigurationsDetails( - @Parameter(hidden = true) ExternalEventConfigurationCommand command) { - context.authenticatedUser().validateHasUpdatePermission(RESOURCE_NAME_FOR_PERMISSIONS); - final CommandWrapper commandRequest = new CommandWrapperBuilder().updateExternalEventConfigurations() - .withJson(jsonSerializer.serialize(command)).build(); - return commandWritePlatformService.logCommandSource(commandRequest); + public ExternalEventConfigurationUpdateResponse updateExternalEventConfigurations(@HeaderParam("Idempotency-Key") String idempotencyKey, + @Valid ExternalEventConfigurationUpdateRequest request) { + final var command = new ExternalConfigurationsUpdateCommand(); + + command.setId(UUID.randomUUID()); + command.setIdempotencyKey(idempotencyKey); + command.setCreatedAt(DateUtils.getAuditOffsetDateTime()); + command.setPayload(request); + + final Supplier response = commandPipeline.send(command); + + return response.get(); } } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/InternalExternalEventsApiResource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/InternalExternalEventsApiResource.java index 31b84f99d..a26bdd001 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/InternalExternalEventsApiResource.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/InternalExternalEventsApiResource.java @@ -18,7 +18,6 @@ */ package org.apache.fineract.infrastructure.event.external.api; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DELETE; import jakarta.ws.rs.GET; @@ -30,51 +29,36 @@ import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.fineract.infrastructure.core.boot.FineractProfiles; -import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.infrastructure.event.external.service.InternalExternalEventService; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; -import org.springframework.beans.factory.InitializingBean; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; +@Slf4j +// TODO: can't we test this differently without creating boilerplate code that's only available during testing? @Profile(FineractProfiles.TEST) @Component @Path("/v1/internal/externalevents") @RequiredArgsConstructor -@Slf4j -public class InternalExternalEventsApiResource implements InitializingBean { +public class InternalExternalEventsApiResource { private final InternalExternalEventService internalExternalEventService; - private final DefaultToApiJsonSerializer> jsonSerializer; - - @Override - @SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT") - public void afterPropertiesSet() throws Exception { - log.warn("------------------------------------------------------------"); - log.warn(" "); - log.warn("DO NOT USE THIS IN PRODUCTION!"); - log.warn("Internal client services mode is enabled"); - log.warn("DO NOT USE THIS IN PRODUCTION!"); - log.warn(" "); - log.warn("------------------------------------------------------------"); - } @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String getAllExternalEvents(@QueryParam("idempotencyKey") final String idempotencyKey, @QueryParam("type") final String type, - @QueryParam("category") final String category, @QueryParam("aggregateRootId") final Long aggregateRootId) { - log.debug("getAllExternalEvents called with params idempotencyKey:{}, type:{}, category:{}, aggregateRootId:{} ", idempotencyKey, - type, category, aggregateRootId); - List allExternalEvents = internalExternalEventService.getAllExternalEvents(idempotencyKey, type, category, - aggregateRootId); - return jsonSerializer.serialize(allExternalEvents); + public List getAllExternalEvents(@QueryParam("idempotencyKey") final String idempotencyKey, + @QueryParam("type") final String type, @QueryParam("category") final String category, + @QueryParam("aggregateRootId") final Long aggregateRootId) { + // TODO: authorization constraints? + return internalExternalEventService.getAllExternalEvents(idempotencyKey, type, category, aggregateRootId); } @DELETE + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) public void deleteAllExternalEvents() { - log.debug("deleteAllExternalEvents called"); + // TODO: authorization constraints? internalExternalEventService.deleteAllExternalEvents(); } - } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalEventConfigurationCommand.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalConfigurationsUpdateCommand.java similarity index 70% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalEventConfigurationCommand.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalConfigurationsUpdateCommand.java index ddb566eea..c42d79b2e 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalEventConfigurationCommand.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalConfigurationsUpdateCommand.java @@ -18,13 +18,11 @@ */ package org.apache.fineract.infrastructure.event.external.command; -import java.io.Serial; -import java.io.Serializable; -import java.util.Map; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateRequest; -public record ExternalEventConfigurationCommand(Map externalEventConfigurations) implements Serializable { - - @Serial - private static final long serialVersionUID = 1L; - -} +@Data +@EqualsAndHashCode(callSuper = true) +public class ExternalConfigurationsUpdateCommand extends Command {} diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemResponse.java similarity index 82% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemData.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemResponse.java index 7b62d9621..ace42edae 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemData.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemResponse.java @@ -18,14 +18,21 @@ */ package org.apache.fineract.infrastructure.event.external.data; +import java.io.Serial; +import java.io.Serializable; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +@Builder @Data @NoArgsConstructor @AllArgsConstructor -public class ExternalEventConfigurationItemData { +public class ExternalEventConfigurationItemResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; private String type; private boolean enabled; diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationResponse.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationResponse.java new file mode 100644 index 000000000..f2a9dbbbd --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationResponse.java @@ -0,0 +1,40 @@ +/** + * 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.data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ExternalEventConfigurationResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + // TODO: why wrap things in this useless class?!? Just more boilerplate! Keeping for compatibility... + private List externalEventConfiguration; +} diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventDTO.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationUpdateRequest.java similarity index 60% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventDTO.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationUpdateRequest.java index dec70373e..613bb7a37 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventDTO.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationUpdateRequest.java @@ -16,26 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.infrastructure.event.external.service.validation; +package org.apache.fineract.infrastructure.event.external.data; -import java.time.LocalDate; -import java.time.OffsetDateTime; +import jakarta.validation.constraints.NotNull; +import java.io.Serial; +import java.io.Serializable; import java.util.Map; import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; -@Getter +@Builder +@Data +@NoArgsConstructor @AllArgsConstructor -@ToString -public class ExternalEventDTO { +public class ExternalEventConfigurationUpdateRequest implements Serializable { - private final Long eventId; - private final String type; - private final String category; - private final OffsetDateTime createdAt; - private final Map payLoad; - private final LocalDate businessDate; - private final String schema; - private final Long aggregateRootId; + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "{org.apache.fineract.externalevent.configurations.not-null}") + private Map externalEventConfigurations; } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationUpdateResponse.java similarity index 72% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationData.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationUpdateResponse.java index a9612c219..a4d5ae4a1 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationData.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationUpdateResponse.java @@ -18,13 +18,22 @@ */ package org.apache.fineract.infrastructure.event.external.data; -import java.util.List; +import java.io.Serial; +import java.io.Serializable; +import java.util.HashMap; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +@Builder @Data @NoArgsConstructor -public class ExternalEventConfigurationData { +@AllArgsConstructor +public class ExternalEventConfigurationUpdateResponse implements Serializable { - private List externalEventConfiguration; + @Serial + private static final long serialVersionUID = 1L; + + private HashMap changes; } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventResponse.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventResponse.java new file mode 100644 index 000000000..6f258b736 --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventResponse.java @@ -0,0 +1,48 @@ +/** + * 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.data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ExternalEventResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long eventId; + private String type; + private String category; + private OffsetDateTime createdAt; + private Map payLoad; + private LocalDate businessDate; + private String schema; + private Long aggregateRootId; +} diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java index ac0cd13ae..43e2dcc07 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java @@ -18,12 +18,12 @@ */ package org.apache.fineract.infrastructure.event.external.handler; -import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.command.core.CommandHandler; import org.apache.fineract.commands.annotation.CommandType; -import org.apache.fineract.commands.handler.NewCommandSourceHandler; -import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateRequest; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateResponse; import org.apache.fineract.infrastructure.event.external.service.ExternalEventConfigurationWritePlatformService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,13 +31,14 @@ import org.springframework.transaction.annotation.Transactional; @RequiredArgsConstructor @Service @CommandType(entity = "EXTERNAL_EVENT_CONFIGURATION", action = "UPDATE") -public class ExternalEventConfigurationUpdateHandler implements NewCommandSourceHandler { +public class ExternalEventConfigurationUpdateHandler + implements CommandHandler { private final ExternalEventConfigurationWritePlatformService writePlatformService; @Transactional @Override - public CommandProcessingResult processCommand(@NotNull final JsonCommand command) { - return writePlatformService.updateConfigurations(command); + public ExternalEventConfigurationUpdateResponse handle(Command command) { + return writePlatformService.updateConfigurations(command.getPayload()); } } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java deleted file mode 100644 index 24b2b1317..000000000 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * 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.serialization; - -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import lombok.AllArgsConstructor; -import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.core.exception.InvalidJsonException; -import org.apache.fineract.infrastructure.core.serialization.AbstractFromApiJsonDeserializer; -import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; -import org.apache.fineract.infrastructure.event.external.command.ExternalEventConfigurationCommand; -import org.springframework.stereotype.Component; - -@Component -@AllArgsConstructor -public class ExternalEventConfigurationCommandFromApiJsonDeserializer - extends AbstractFromApiJsonDeserializer { - - private static final String EXTERNAL_EVENT_CONFIGURATIONS = "externalEventConfigurations"; - private final Set supportedParameters = new HashSet<>(Arrays.asList(EXTERNAL_EVENT_CONFIGURATIONS)); - private final FromJsonHelper fromApiJsonHelper; - - @Override - public ExternalEventConfigurationCommand commandFromApiJson(String json) { - if (StringUtils.isBlank(json)) { - throw new InvalidJsonException(); - } - - final Type typeOfMap = new TypeToken>() {}.getType(); - fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); - - return fromApiJsonHelper.fromJson(json, ExternalEventConfigurationCommand.class); - } -} diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java index 82ee6697a..b9bbc5b5e 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java @@ -18,9 +18,9 @@ */ package org.apache.fineract.infrastructure.event.external.service; -import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationData; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationResponse; public interface ExternalEventConfigurationReadPlatformService { - ExternalEventConfigurationData findAllExternalEventConfigurations(); + ExternalEventConfigurationResponse findAllExternalEventConfigurations(); } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java index a7c6eca5e..b1b6b1e8a 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java @@ -20,7 +20,7 @@ package org.apache.fineract.infrastructure.event.external.service; import java.util.List; import lombok.RequiredArgsConstructor; -import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationData; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationResponse; import org.apache.fineract.infrastructure.event.external.repository.ExternalEventConfigurationRepository; import org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEventConfiguration; import org.springframework.stereotype.Service; @@ -33,8 +33,8 @@ public class ExternalEventConfigurationReadPlatformServiceImpl implements Extern private final ExternalEventsConfigurationMapper mapper; @Override - public ExternalEventConfigurationData findAllExternalEventConfigurations() { - ExternalEventConfigurationData configurationData = new ExternalEventConfigurationData(); + public ExternalEventConfigurationResponse findAllExternalEventConfigurations() { + ExternalEventConfigurationResponse configurationData = new ExternalEventConfigurationResponse(); List eventConfigurations = repository.findAll(); configurationData.setExternalEventConfiguration(mapper.map(eventConfigurations)); return configurationData; diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java index 9724cd1ee..22c7c9d2d 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java @@ -18,10 +18,10 @@ */ package org.apache.fineract.infrastructure.event.external.service; -import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateRequest; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateResponse; public interface ExternalEventConfigurationWritePlatformService { - CommandProcessingResult updateConfigurations(JsonCommand command); + ExternalEventConfigurationUpdateResponse updateConfigurations(ExternalEventConfigurationUpdateRequest request); } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java index ed86d7ead..bb9971ddf 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java @@ -20,16 +20,11 @@ package org.apache.fineract.infrastructure.event.external.service; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; -import java.util.Map; import lombok.AllArgsConstructor; -import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; -import org.apache.fineract.infrastructure.event.external.command.ExternalEventConfigurationCommand; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateRequest; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateResponse; import org.apache.fineract.infrastructure.event.external.repository.ExternalEventConfigurationRepository; import org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEventConfiguration; -import org.apache.fineract.infrastructure.event.external.serialization.ExternalEventConfigurationCommandFromApiJsonDeserializer; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -38,33 +33,30 @@ import org.springframework.transaction.annotation.Transactional; public class ExternalEventConfigurationWritePlatformServiceImpl implements ExternalEventConfigurationWritePlatformService { private final ExternalEventConfigurationRepository repository; - private final ExternalEventConfigurationCommandFromApiJsonDeserializer fromApiJsonDeserializer; @Transactional @Override - public CommandProcessingResult updateConfigurations(final JsonCommand command) { - final ExternalEventConfigurationCommand configurationCommand = fromApiJsonDeserializer.commandFromApiJson(command.json()); - final Map commandConfigurations = configurationCommand.externalEventConfigurations(); - final Map changes = new HashMap<>(); - final Map changedConfigurations = new HashMap<>(); - final List modifiedConfigurations = new ArrayList<>(); + public ExternalEventConfigurationUpdateResponse updateConfigurations(final ExternalEventConfigurationUpdateRequest request) { + final var commandConfigurations = request.getExternalEventConfigurations(); + final var changes = new HashMap(); + final var changedConfigurations = new HashMap(); + final var modifiedConfigurations = new ArrayList(); - for (Map.Entry entry : commandConfigurations.entrySet()) { - final ExternalEventConfiguration configuration = repository - .findExternalEventConfigurationByTypeWithNotFoundDetection(entry.getKey()); + for (var entry : commandConfigurations.entrySet()) { + final var configuration = repository.findExternalEventConfigurationByTypeWithNotFoundDetection(entry.getKey()); configuration.setEnabled(entry.getValue()); changedConfigurations.put(entry.getKey(), entry.getValue()); modifiedConfigurations.add(configuration); } if (!modifiedConfigurations.isEmpty()) { - this.repository.saveAll(modifiedConfigurations); + repository.saveAll(modifiedConfigurations); } if (!changedConfigurations.isEmpty()) { changes.put("externalEventConfigurations", changedConfigurations); } - return new CommandProcessingResultBuilder().withCommandId(command.commandId()).with(changes).build(); + return ExternalEventConfigurationUpdateResponse.builder().changes(changes).build(); } } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java index cd8a62086..544cb88de 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java @@ -63,7 +63,7 @@ public class ExternalEventService { } try { - flushChangesBeforeSerialization(); + entityManager.flush(); ExternalEvent externalEvent; if (event instanceof BulkBusinessEvent) { externalEvent = handleBulkBusinessEvent((BulkBusinessEvent) event); @@ -79,6 +79,11 @@ public class ExternalEventService { } + @PersistenceContext + public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } + private ExternalEvent handleBulkBusinessEvent(BulkBusinessEvent bulkBusinessEvent) throws IOException { List messages = new ArrayList<>(); List> events = bulkBusinessEvent.get(); @@ -109,13 +114,4 @@ public class ExternalEventService { return new ExternalEvent(eventType, eventCategory, schema, data, idempotencyKey, aggregateRootId); } - - private void flushChangesBeforeSerialization() { - entityManager.flush(); - } - - @PersistenceContext - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java index c6dd4b705..2e741bb32 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java @@ -20,12 +20,12 @@ package org.apache.fineract.infrastructure.event.external.service; import java.util.List; import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig; -import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationItemData; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationItemResponse; import org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEventConfiguration; import org.mapstruct.Mapper; @Mapper(config = MapstructMapperConfig.class) public interface ExternalEventsConfigurationMapper { - List map(List source); + List map(List source); } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/InternalExternalEventService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/InternalExternalEventService.java index b044b3d33..ec156cbd0 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/InternalExternalEventService.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/InternalExternalEventService.java @@ -22,7 +22,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -32,9 +31,9 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.fineract.avro.BulkMessageItemV1; import org.apache.fineract.infrastructure.core.boot.FineractProfiles; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.infrastructure.event.external.repository.ExternalEventRepository; import org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEvent; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; import org.springframework.context.annotation.Profile; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; @@ -45,14 +44,15 @@ import org.springframework.stereotype.Service; @AllArgsConstructor public class InternalExternalEventService { + private final ObjectMapper mapper; private final ExternalEventRepository externalEventRepository; public void deleteAllExternalEvents() { externalEventRepository.deleteAll(); } - public List getAllExternalEvents(String idempotencyKey, String type, String category, Long aggregateRootId) { - List> specifications = new ArrayList<>(); + public List getAllExternalEvents(String idempotencyKey, String type, String category, Long aggregateRootId) { + var specifications = new ArrayList>(); if (StringUtils.isNotEmpty(idempotencyKey)) { specifications.add(hasIdempotencyKey(idempotencyKey)); @@ -70,9 +70,9 @@ public class InternalExternalEventService { specifications.add(hasAggregateRootId(aggregateRootId)); } - Specification reducedSpecification = specifications.stream().reduce(Specification::and) + var reducedSpecification = specifications.stream().reduce(Specification::and) .orElse((Specification) (root, query, criteriaBuilder) -> null); - List externalEvents = externalEventRepository.findAll(reducedSpecification); + var externalEvents = externalEventRepository.findAll(reducedSpecification); try { return convertToReadableFormat(externalEvents); @@ -98,29 +98,29 @@ public class InternalExternalEventService { return (root, query, cb) -> cb.equal(root.get("aggregateRootId"), aggregateRootId); } - private List convertToReadableFormat(List externalEvents) throws ClassNotFoundException, + private List convertToReadableFormat(List externalEvents) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, JsonProcessingException { - List eventMessages = new ArrayList<>(); - for (ExternalEvent externalEvent : externalEvents) { - Class payLoadClass = Class.forName(externalEvent.getSchema()); - ByteBuffer byteBuffer = ByteBuffer.wrap(externalEvent.getData()); - Method method = payLoadClass.getMethod("fromByteBuffer", ByteBuffer.class); - Object payLoad = method.invoke(null, byteBuffer); + var eventMessages = new ArrayList(); + for (var externalEvent : externalEvents) { + var payLoadClass = Class.forName(externalEvent.getSchema()); + var byteBuffer = ByteBuffer.wrap(externalEvent.getData()); + var method = payLoadClass.getMethod("fromByteBuffer", ByteBuffer.class); + var payLoad = method.invoke(null, byteBuffer); if (externalEvent.getType().equalsIgnoreCase("BulkBusinessEvent")) { - Method methodToGetDatas = payLoad.getClass().getMethod("getDatas", (Class) null); - List bulkMessages = (List) methodToGetDatas.invoke(payLoad); - StringBuilder bulkMessagePayload = new StringBuilder(); - for (BulkMessageItemV1 bulkMessage : bulkMessages) { - ExternalEventDTO bulkMessageData = retrieveBulkMessage(bulkMessage, externalEvent); + var methodToGetDatas = payLoad.getClass().getMethod("getDatas", (Class) null); + var bulkMessages = (List) methodToGetDatas.invoke(payLoad); + var bulkMessagePayload = new StringBuilder(); + for (var bulkMessage : bulkMessages) { + var bulkMessageData = retrieveBulkMessage(bulkMessage, externalEvent); bulkMessagePayload.append(bulkMessageData); bulkMessagePayload.append(System.lineSeparator()); } - eventMessages.add(new ExternalEventDTO(externalEvent.getId(), externalEvent.getType(), externalEvent.getCategory(), + eventMessages.add(new ExternalEventResponse(externalEvent.getId(), externalEvent.getType(), externalEvent.getCategory(), externalEvent.getCreatedAt(), toJsonMap(bulkMessagePayload.toString()), externalEvent.getBusinessDate(), externalEvent.getSchema(), externalEvent.getAggregateRootId())); } else { - eventMessages.add(new ExternalEventDTO(externalEvent.getId(), externalEvent.getType(), externalEvent.getCategory(), + eventMessages.add(new ExternalEventResponse(externalEvent.getId(), externalEvent.getType(), externalEvent.getCategory(), externalEvent.getCreatedAt(), toJsonMap(payLoad.toString()), externalEvent.getBusinessDate(), externalEvent.getSchema(), externalEvent.getAggregateRootId())); } @@ -129,19 +129,19 @@ public class InternalExternalEventService { return eventMessages; } - private ExternalEventDTO retrieveBulkMessage(BulkMessageItemV1 messageItem, ExternalEvent externalEvent) throws ClassNotFoundException, - InvocationTargetException, IllegalAccessException, NoSuchMethodException, JsonProcessingException { - Class messageBulkMessagePayLoad = Class.forName(messageItem.getDataschema()); - Method methodForPayLoad = messageBulkMessagePayLoad.getMethod("fromByteBuffer", ByteBuffer.class); - Object payLoadBulkItem = methodForPayLoad.invoke(null, messageItem.getData()); - return new ExternalEventDTO((long) messageItem.getId(), messageItem.getType(), messageItem.getCategory(), + private ExternalEventResponse retrieveBulkMessage(BulkMessageItemV1 messageItem, ExternalEvent externalEvent) + throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, + JsonProcessingException { + var messageBulkMessagePayLoad = Class.forName(messageItem.getDataschema()); + var methodForPayLoad = messageBulkMessagePayLoad.getMethod("fromByteBuffer", ByteBuffer.class); + var payLoadBulkItem = methodForPayLoad.invoke(null, messageItem.getData()); + return new ExternalEventResponse(messageItem.getId(), messageItem.getType(), messageItem.getCategory(), externalEvent.getCreatedAt(), toJsonMap(payLoadBulkItem.toString()), externalEvent.getBusinessDate(), externalEvent.getSchema(), externalEvent.getAggregateRootId()); } private Map toJsonMap(String json) throws JsonProcessingException { - ObjectMapper objectMapper = new ObjectMapper(); - return objectMapper.readValue(json, new TypeReference<>() {}); + return mapper.readValue(json, new TypeReference<>() {}); } } diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/suite/ExternalEventSuiteInitializerStep.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/suite/ExternalEventSuiteInitializerStep.java index 0ee6438d4..edde8c6db 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/suite/ExternalEventSuiteInitializerStep.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/suite/ExternalEventSuiteInitializerStep.java @@ -24,9 +24,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; -import org.apache.fineract.client.models.ExternalEventConfigurationCommand; -import org.apache.fineract.client.models.ExternalEventConfigurationData; -import org.apache.fineract.client.models.ExternalEventConfigurationItemData; +import org.apache.fineract.client.models.ExternalEventConfigurationItemResponse; +import org.apache.fineract.client.models.ExternalEventConfigurationResponse; +import org.apache.fineract.client.models.ExternalEventConfigurationUpdateRequest; import org.apache.fineract.client.services.ExternalEventConfigurationApi; import org.springframework.stereotype.Component; import retrofit2.Response; @@ -41,19 +41,20 @@ public class ExternalEventSuiteInitializerStep implements FineractSuiteInitializ public void initializeForSuite() throws Exception { Map eventConfigMap = new HashMap<>(); - Response response = eventConfigurationApi.retrieveExternalEventConfiguration().execute(); + Response response = eventConfigurationApi.getExternalEventConfigurations().execute(); if (!response.isSuccessful()) { String responseBody = response.errorBody().string(); throw new RuntimeException("Cannot configure external events due to " + lineSeparator() + responseBody); } - List externalEventConfiguration = response.body().getExternalEventConfiguration(); + List externalEventConfiguration = response.body().getExternalEventConfiguration(); externalEventConfiguration.forEach(e -> { eventConfigMap.put(e.getType(), true); }); - ExternalEventConfigurationCommand request = new ExternalEventConfigurationCommand().externalEventConfigurations(eventConfigMap); + ExternalEventConfigurationUpdateRequest request = new ExternalEventConfigurationUpdateRequest() + .externalEventConfigurations(eventConfigMap); - eventConfigurationApi.updateExternalEventConfigurationsDetails(request).execute(); + eventConfigurationApi.updateExternalEventConfigurations("", request).execute(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java index 380acdb09..30f98464e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java @@ -134,10 +134,15 @@ public class SecurityConfig { .requestMatchers(antMatcher(HttpMethod.PUT, "/api/*/instance-mode")).permitAll() // // businessdate .requestMatchers(antMatcher(HttpMethod.GET, "/api/*/businessdate/*")) - .hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_BUSINESS_DATE") // + .hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_BUSINESS_DATE") .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/businessdate")) - .hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_WRITE", "UPDATE_BUSINESS_DATE") // - // + .hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_WRITE", "UPDATE_BUSINESS_DATE") + // external + .requestMatchers(antMatcher(HttpMethod.GET, "/api/*/externalevents/configuration")) + .hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_EXTERNAL_EVENT_CONFIGURATION") + .requestMatchers(antMatcher(HttpMethod.PUT, "/api/*/externalevents/configuration")) + .hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_WRITE", "UPDATE_EXTERNAL_EVENT_CONFIGURATION") + // ... .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/twofactor/validate")).fullyAuthenticated() // .requestMatchers(antMatcher("/api/*/twofactor")).fullyAuthenticated() // .requestMatchers(antMatcher("/api/**")) diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceTest.java index 4c1d45310..56a0b1f2c 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceTest.java @@ -27,8 +27,8 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationData; -import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationItemData; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationItemResponse; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationResponse; import org.apache.fineract.infrastructure.event.external.repository.ExternalEventConfigurationRepository; import org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEventConfiguration; import org.junit.jupiter.api.BeforeEach; @@ -59,16 +59,16 @@ public class ExternalEventConfigurationReadPlatformServiceTest { // given List configurations = Arrays.asList(new ExternalEventConfiguration("aType", true), new ExternalEventConfiguration("bType", false)); - List configurationDataItems = Arrays - .asList(new ExternalEventConfigurationItemData("aType", true), new ExternalEventConfigurationItemData("bType", false)); + List configurationDataItems = Arrays.asList( + new ExternalEventConfigurationItemResponse("aType", true), new ExternalEventConfigurationItemResponse("bType", false)); when(repository.findAll()).thenReturn(configurations); when(mapper.map(Mockito.anyList())).thenReturn(configurationDataItems); // when - ExternalEventConfigurationData actualConfiguration = underTest.findAllExternalEventConfigurations(); + ExternalEventConfigurationResponse actualConfiguration = underTest.findAllExternalEventConfigurations(); // then assertThat(actualConfiguration.getExternalEventConfiguration(), hasSize(2)); - assertThat(actualConfiguration.getExternalEventConfiguration().get(0), any(ExternalEventConfigurationItemData.class)); + assertThat(actualConfiguration.getExternalEventConfiguration().get(0), any(ExternalEventConfigurationItemResponse.class)); assertThat(actualConfiguration.getExternalEventConfiguration().get(0).getType(), equalTo("aType")); assertThat(actualConfiguration.getExternalEventConfiguration().get(0).isEnabled(), equalTo(true)); } @@ -79,7 +79,7 @@ public class ExternalEventConfigurationReadPlatformServiceTest { List emptyConfiguration = new ArrayList<>(); when(repository.findAll()).thenReturn(emptyConfiguration); // when - ExternalEventConfigurationData actualConfiguration = underTest.findAllExternalEventConfigurations(); + ExternalEventConfigurationResponse actualConfiguration = underTest.findAllExternalEventConfigurations(); // then assertThat(actualConfiguration.getExternalEventConfiguration(), hasSize(0)); diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceTest.java index 5025715b7..e1c04345c 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceTest.java @@ -22,13 +22,10 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.HashMap; import java.util.Map; -import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.apache.fineract.infrastructure.event.external.command.ExternalEventConfigurationCommand; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventConfigurationUpdateRequest; import org.apache.fineract.infrastructure.event.external.repository.ExternalEventConfigurationRepository; import org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEventConfiguration; -import org.apache.fineract.infrastructure.event.external.serialization.ExternalEventConfigurationCommandFromApiJsonDeserializer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,31 +38,26 @@ public class ExternalEventConfigurationWritePlatformServiceTest { @Mock private ExternalEventConfigurationRepository repository; - @Mock - private ExternalEventConfigurationCommandFromApiJsonDeserializer fromApiJsonDeserializer; private ExternalEventConfigurationWritePlatformServiceImpl underTest; @BeforeEach public void setUp() { - underTest = new ExternalEventConfigurationWritePlatformServiceImpl(repository, fromApiJsonDeserializer); + underTest = new ExternalEventConfigurationWritePlatformServiceImpl(repository); } @Test public void givenExternalEventConfigurationsWithChangeWhenUpdateConfigurationThenConfigurationIsUpdated() { // given - final JsonCommand jsonCommand = Mockito.mock(JsonCommand.class); - Map mapOfConfigurationsForUpdate = new HashMap<>(); - mapOfConfigurationsForUpdate.put("aType", Boolean.TRUE); - ExternalEventConfigurationCommand command = new ExternalEventConfigurationCommand(mapOfConfigurationsForUpdate); - when(jsonCommand.json()).thenReturn(""); - when(fromApiJsonDeserializer.commandFromApiJson(Mockito.anyString())).thenReturn(command); + var configurations = Map.of("aType", Boolean.TRUE); + var request = new ExternalEventConfigurationUpdateRequest(configurations); + when(repository.findExternalEventConfigurationByTypeWithNotFoundDetection(Mockito.anyString())) .thenReturn(new ExternalEventConfiguration("aType", false)); + // when - underTest.updateConfigurations(jsonCommand); + underTest.updateConfigurations(request); // then verify(repository, times(1)).saveAll(Mockito.anyCollection()); } - } diff --git a/fineract-validation/src/main/resources/fineract/validation/messages.properties b/fineract-validation/src/main/resources/fineract/validation/messages.properties index 25c7f718b..8508fdd06 100644 --- a/fineract-validation/src/main/resources/fineract/validation/messages.properties +++ b/fineract-validation/src/main/resources/fineract/validation/messages.properties @@ -28,3 +28,7 @@ org.apache.fineract.businessdate.date-format.not-blank=The parameter 'dateFormat org.apache.fineract.businessdate.type.not-null=The parameter 'type' is mandatory: '${validatedValue}'. org.apache.fineract.businessdate.date.not-blank=The parameter 'date' is mandatory: '${validatedValue}'. org.apache.fineract.businessdate.locale.not-blank=The parameter 'locale' is mandatory: '${validatedValue}'. + +# External Events + +org.apache.fineract.externalevent.configurations.not-null=The parameter 'externalEventConfigurations' is mandatory: '${validatedValue}'. diff --git a/fineract-validation/src/main/resources/fineract/validation/messages_en.properties b/fineract-validation/src/main/resources/fineract/validation/messages_en.properties index 25c7f718b..8508fdd06 100644 --- a/fineract-validation/src/main/resources/fineract/validation/messages_en.properties +++ b/fineract-validation/src/main/resources/fineract/validation/messages_en.properties @@ -28,3 +28,7 @@ org.apache.fineract.businessdate.date-format.not-blank=The parameter 'dateFormat org.apache.fineract.businessdate.type.not-null=The parameter 'type' is mandatory: '${validatedValue}'. org.apache.fineract.businessdate.date.not-blank=The parameter 'date' is mandatory: '${validatedValue}'. org.apache.fineract.businessdate.locale.not-blank=The parameter 'locale' is mandatory: '${validatedValue}'. + +# External Events + +org.apache.fineract.externalevent.configurations.not-null=The parameter 'externalEventConfigurations' is mandatory: '${validatedValue}'. diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java index 22c26834f..6bb511131 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java @@ -86,7 +86,7 @@ import org.apache.fineract.client.models.RetrieveLoansPointInTimeRequest; import org.apache.fineract.client.util.CallFailedRuntimeException; import org.apache.fineract.client.util.Calls; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.integrationtests.client.IntegrationTest; import org.apache.fineract.integrationtests.common.BatchHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper; @@ -1275,7 +1275,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest { } protected void verifyBusinessEvents(BusinessEvent... businessEvents) { - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); logBusinessEvents(allExternalEvents); Assertions.assertNotNull(businessEvents); Assertions.assertNotNull(allExternalEvents); @@ -1289,7 +1289,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest { } } - protected void logBusinessEvents(List allExternalEvents) { + protected void logBusinessEvents(List allExternalEvents) { allExternalEvents.forEach(externalEventDTO -> { Object amount = externalEventDTO.getPayLoad().get("amount"); Object outstandingLoanBalance = externalEventDTO.getPayLoad().get("outstandingLoanBalance"); @@ -1306,7 +1306,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest { protected void deleteAllExternalEvents() { ExternalEventHelper.deleteAllExternalEvents(requestSpec, createResponseSpecification(Matchers.is(204))); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); Assertions.assertEquals(0, allExternalEvents.size()); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java index 07e99d127..41e3487eb 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java @@ -27,7 +27,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.fineract.client.models.BusinessDateUpdateRequest; import org.apache.fineract.client.models.PostLoanProductsRequest; import org.apache.fineract.client.models.PostLoanProductsResponse; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.integrationtests.common.BusinessStepHelper; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ExternalEventConfigurationHelper; @@ -85,7 +85,7 @@ public class CustomSnapshotEventIntegrationTest extends BaseLoanIntegrationTest updateBusinessDateAndExecuteCOBJob("01 February 2023"); // verify external events - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); Assertions.assertEquals(1, allExternalEvents.size()); Assertions.assertEquals("LoanAccountCustomSnapshotBusinessEvent", allExternalEvents.get(0).getType()); Assertions.assertEquals(loanId, allExternalEvents.get(0).getAggregateRootId()); @@ -163,7 +163,7 @@ public class CustomSnapshotEventIntegrationTest extends BaseLoanIntegrationTest updateBusinessDateAndExecuteCOBJob("01 February 2023"); // verify external events - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); Assertions.assertEquals(0, allExternalEvents.size()); }); } @@ -208,7 +208,7 @@ public class CustomSnapshotEventIntegrationTest extends BaseLoanIntegrationTest updateBusinessDateAndExecuteCOBJob("01 February 2023"); // verify external events - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); Assertions.assertEquals(0, allExternalEvents.size()); }); } @@ -252,7 +252,7 @@ public class CustomSnapshotEventIntegrationTest extends BaseLoanIntegrationTest updateBusinessDateAndExecuteCOBJob("31 January 2023"); // verify external events - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); Assertions.assertEquals(0, allExternalEvents.size()); }); } @@ -297,7 +297,7 @@ public class CustomSnapshotEventIntegrationTest extends BaseLoanIntegrationTest updateBusinessDateAndExecuteCOBJob("01 February 2023"); // verify external events - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); Assertions.assertEquals(0, allExternalEvents.size()); }); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ExternalBusinessEventTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ExternalBusinessEventTest.java index 10988e91c..223b71e85 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ExternalBusinessEventTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ExternalBusinessEventTest.java @@ -47,7 +47,7 @@ import org.apache.fineract.client.models.PostLoansRequest; import org.apache.fineract.client.models.PostLoansResponse; import org.apache.fineract.client.models.PostUpdateRescheduleLoansRequest; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.integrationtests.common.BusinessStepHelper; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.LoanRescheduleRequestHelper; @@ -182,11 +182,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { .chargeAdjustment(loanId, chargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(111.0).locale("en")) .getSubResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanChargeAdjustmentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertInstanceOf(List.class, loanChargePaidByList); Assertions.assertEquals(1, ((List) loanChargePaidByList).size()); @@ -224,11 +224,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { .chargeAdjustment(loanId, chargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(69.0).locale("en")) .getSubResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanChargeAdjustmentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertInstanceOf(List.class, loanChargePaidByList); Assertions.assertEquals(1, ((List) loanChargePaidByList).size()); @@ -289,11 +289,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { deleteAllExternalEvents(); Long transactionId = loanTransactionHelper.makeLoanRepayment("01 January 2021", 300.0F, loanId.intValue()).getResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanTransactionMakeRepaymentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); log.info(event.toString()); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertEquals(111.0D, event.getPayLoad().get("feeChargesPortion")); @@ -367,11 +367,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { .chargeAdjustment(loanId, chargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(111.0).locale("en")) .getSubResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanChargeAdjustmentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertInstanceOf(List.class, loanChargePaidByList); Assertions.assertEquals(1, ((List) loanChargePaidByList).size()); @@ -410,11 +410,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { .chargeAdjustment(loanId, chargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(69.0).locale("en")) .getSubResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanChargeAdjustmentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertInstanceOf(List.class, loanChargePaidByList); Assertions.assertEquals(1, ((List) loanChargePaidByList).size()); @@ -475,11 +475,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { deleteAllExternalEvents(); Long transactionId = loanTransactionHelper.makeLoanRepayment("01 January 2021", 300.0F, loanId.intValue()).getResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanTransactionMakeRepaymentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); log.info(event.toString()); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertEquals(111.0D, event.getPayLoad().get("feeChargesPortion")); @@ -552,11 +552,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { .chargeAdjustment(loanId, chargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(111.0).locale("en")) .getSubResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanChargeAdjustmentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertInstanceOf(List.class, loanChargePaidByList); Assertions.assertEquals(1, ((List) loanChargePaidByList).size()); @@ -594,11 +594,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { .chargeAdjustment(loanId, chargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(69.0).locale("en")) .getSubResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanChargeAdjustmentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertInstanceOf(List.class, loanChargePaidByList); Assertions.assertEquals(1, ((List) loanChargePaidByList).size()); @@ -658,11 +658,11 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { deleteAllExternalEvents(); Long transactionId = loanTransactionHelper.makeLoanRepayment("01 January 2021", 300.0F, loanId.intValue()).getResourceId(); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List list = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List list = allExternalEvents.stream() .filter(x -> "LoanTransactionMakeRepaymentPostBusinessEvent".equals(x.getType())).toList(); Assertions.assertEquals(1, list.size()); - ExternalEventDTO event = list.get(0); + ExternalEventResponse event = list.get(0); log.info(event.toString()); Object loanChargePaidByList = event.getPayLoad().get("loanChargePaidByList"); Assertions.assertEquals(111.0D, event.getPayLoad().get("feeChargesPortion")); @@ -756,9 +756,9 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { deleteAllExternalEvents(); loanTransactionHelper.reverseRepayment(loanId.intValue(), repaymentId.intValue(), "17 January 2025"); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); // Verify that there were no reverse-replay event - List list = allExternalEvents.stream() // + List list = allExternalEvents.stream() // .filter(x -> "LoanAdjustTransactionBusinessEvent".equals(x.getType()) // && x.getPayLoad().get("newTransactionDetail") != null // && x.getPayLoad().get("transactionToAdjust") != null) // @@ -886,7 +886,7 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { loanTransactionHelper.reverseLoanTransaction(loanId, repaymentTransactionIdRef.get(), "01 February 2025"); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); // Verify no BulkEvent was created Assertions.assertEquals(0, allExternalEvents.stream().filter(e -> e.getType().equals("BulkBusinessEvent")).count()); verifyBusinessEvents(// @@ -969,8 +969,8 @@ public class ExternalBusinessEventTest extends BaseLoanIntegrationTest { PostLoansLoanIdTransactionsResponse interestPaymentWaiverResponse = loanTransactionHelper.makeLoanRepayment(loanId, "InterestPaymentWaiver", "17 January 2025", 10.0); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); - List adjustments = allExternalEvents.stream() + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List adjustments = allExternalEvents.stream() .filter(e -> "LoanAdjustTransactionBusinessEvent".equals(e.getType())).toList(); Assertions.assertEquals(0, adjustments.size()); Assertions.assertNotNull(interestPaymentWaiverResponse); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java index ba3348dde..7d6b48130 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java @@ -39,7 +39,7 @@ import org.apache.fineract.client.models.PostLoansLoanIdRequest; import org.apache.fineract.client.models.PostLoansLoanIdResponse; import org.apache.fineract.client.models.SavingsAccountTransactionsSearchResponse; import org.apache.fineract.infrastructure.core.service.MathUtil; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.CommonConstants; import org.apache.fineract.integrationtests.common.ExternalEventConfigurationHelper; @@ -263,14 +263,14 @@ public class LoanAccountDisbursementToSavingsWithAutoDownPaymentTest extends Bas } private void verifyBusinessEvent() { - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec); String type = "LoanBalanceChangedBusinessEvent"; - final Optional optionalExternalEventDTO = allExternalEvents.stream().filter(event -> event.getType().equals(type)) - .findFirst(); + final Optional optionalExternalEventDTO = allExternalEvents.stream() + .filter(event -> event.getType().equals(type)).findFirst(); Assertions.assertTrue(optionalExternalEventDTO.isPresent()); - final ExternalEventDTO externalEventDTO = optionalExternalEventDTO.get(); + final ExternalEventResponse externalEventDTO = optionalExternalEventDTO.get(); Assertions.assertEquals(externalEventDTO.getPayLoad().get("enableDownPayment"), Boolean.TRUE); Assertions.assertEquals(externalEventDTO.getPayLoad().get("enableAutoRepaymentForDownPayment"), Boolean.TRUE); Assertions.assertEquals(externalEventDTO.getPayLoad().get("disbursedAmountPercentageForDownPayment"), diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessStepHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessStepHelper.java index 1b23fd6f2..36efc63f2 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessStepHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessStepHelper.java @@ -24,6 +24,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import org.apache.fineract.client.models.BusinessStep; import org.apache.fineract.client.models.BusinessStepRequest; +import org.apache.fineract.client.models.JobBusinessStepConfigData; import org.apache.fineract.client.util.Calls; public class BusinessStepHelper { @@ -31,10 +32,9 @@ public class BusinessStepHelper { public BusinessStepHelper() {} public BusinessStepsSnapshot getConfigurationSnapshot(String jobName) { - List businessSteps = Calls - .ok(FineractClientHelper.getFineractClient().businessStepConfiguration.retrieveAllConfiguredBusinessStep(jobName)) - .getBusinessSteps(); - return new BusinessStepsSnapshot(jobName, businessSteps); + JobBusinessStepConfigData businessConfig = Calls + .ok(FineractClientHelper.getFineractClient().businessStepConfiguration.retrieveAllConfiguredBusinessStep(jobName)); + return new BusinessStepsSnapshot(jobName, businessConfig.getBusinessSteps()); } public void updateSteps(String jobName, String... steps) { diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/BusinessEvent.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/BusinessEvent.java index 340648b13..f6fb439cf 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/BusinessEvent.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/BusinessEvent.java @@ -25,7 +25,7 @@ import java.util.Objects; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; @Data @AllArgsConstructor @@ -35,7 +35,7 @@ public class BusinessEvent { protected String type; protected String businessDate; - public boolean verify(@NotNull ExternalEventDTO externalEvent, DateTimeFormatter formatter) { + public boolean verify(@NotNull ExternalEventResponse externalEvent, DateTimeFormatter formatter) { var businessDate = LocalDate.parse(getBusinessDate(), formatter); return Objects.equals(externalEvent.getType(), getType()) && Objects.equals(externalEvent.getBusinessDate(), businessDate); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/ExternalEventHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/ExternalEventHelper.java index 6d81d6409..41666a5ab 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/ExternalEventHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/ExternalEventHelper.java @@ -26,11 +26,11 @@ import java.util.List; import java.util.Map; import lombok.Builder; import lombok.extern.slf4j.Slf4j; -import org.apache.fineract.client.models.CommandProcessingResult; -import org.apache.fineract.client.models.ExternalEventConfigurationCommand; +import org.apache.fineract.client.models.ExternalEventConfigurationUpdateRequest; +import org.apache.fineract.client.models.ExternalEventConfigurationUpdateResponse; import org.apache.fineract.client.util.Calls; import org.apache.fineract.client.util.JSON; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.integrationtests.common.ExternalEventConfigurationHelper; import org.apache.fineract.integrationtests.common.FineractClientHelper; import org.apache.fineract.integrationtests.common.Utils; @@ -78,24 +78,24 @@ public final class ExternalEventHelper { // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, // org.apache.fineract.client.models.PostLoansLoanIdRequest) @Deprecated(forRemoval = true) - public static List getAllExternalEvents(final RequestSpecification requestSpec, + public static List getAllExternalEvents(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { final String url = "/fineract-provider/api/v1/internal/externalevents?" + Utils.TENANT_IDENTIFIER; log.info("---------------------------------GETTING ALL EXTERNAL EVENTS---------------------------------------------"); String response = Utils.performServerGet(requestSpec, responseSpec, url); - return GSON.fromJson(response, new TypeToken>() {}.getType()); + return GSON.fromJson(response, new TypeToken>() {}.getType()); } // TODO: Rewrite to use fineract-client instead! // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, // org.apache.fineract.client.models.PostLoansLoanIdRequest) @Deprecated(forRemoval = true) - public static List getAllExternalEvents(final RequestSpecification requestSpec, + public static List getAllExternalEvents(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, Filter filter) { final String url = "/fineract-provider/api/v1/internal/externalevents?" + filter.toQueryParams() + Utils.TENANT_IDENTIFIER; log.info("---------------------------------GETTING ALL EXTERNAL EVENTS---------------------------------------------"); String response = Utils.performServerGet(requestSpec, responseSpec, url); - return GSON.fromJson(response, new TypeToken>() {}.getType()); + return GSON.fromJson(response, new TypeToken>() {}.getType()); } // TODO: Rewrite to use fineract-client instead! @@ -122,9 +122,9 @@ public final class ExternalEventHelper { } public void configureBusinessEvent(String eventName, boolean enabled) { - CommandProcessingResult result = Calls - .ok(FineractClientHelper.getFineractClient().externalEventConfigurationApi.updateExternalEventConfigurationsDetails( - new ExternalEventConfigurationCommand().putExternalEventConfigurationsItem(eventName, enabled))); + ExternalEventConfigurationUpdateResponse result = Calls + .ok(FineractClientHelper.getFineractClient().externalEventConfigurationApi.updateExternalEventConfigurations("", + new ExternalEventConfigurationUpdateRequest().externalEventConfigurations(Map.of(eventName, enabled)))); Map changes = result.getChanges(); Assertions.assertNotNull(changes); Assertions.assertInstanceOf(Map.class, changes); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanAdjustTransactionBusinessEvent.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanAdjustTransactionBusinessEvent.java index 2d725b1a8..05c40accd 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanAdjustTransactionBusinessEvent.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanAdjustTransactionBusinessEvent.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.Objects; import lombok.Data; import lombok.EqualsAndHashCode; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; @EqualsAndHashCode(callSuper = true) @Data @@ -79,7 +79,7 @@ public class LoanAdjustTransactionBusinessEvent extends BusinessEvent { } @Override - public boolean verify(ExternalEventDTO externalEvent, DateTimeFormatter formatter) { + public boolean verify(ExternalEventResponse externalEvent, DateTimeFormatter formatter) { final Object transactionToAdjust = externalEvent.getPayLoad().get("transactionToAdjust"); final Map transActionToAdjustMap = transactionToAdjust instanceof Map ? (Map) transactionToAdjust : Collections.emptyMap(); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanBusinessEvent.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanBusinessEvent.java index da683f2c1..49a52db96 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanBusinessEvent.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanBusinessEvent.java @@ -26,7 +26,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; @EqualsAndHashCode(callSuper = true) @Data @@ -54,7 +54,7 @@ public class LoanBusinessEvent extends BusinessEvent { } @Override - public boolean verify(ExternalEventDTO externalEvent, DateTimeFormatter formatter) { + public boolean verify(ExternalEventResponse externalEvent, DateTimeFormatter formatter) { Object summaryRes = externalEvent.getPayLoad().get("summary"); Object statusRes = externalEvent.getPayLoad().get("status"); Map summary = summaryRes instanceof Map ? (Map) summaryRes : Map.of(); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanTransactionBusinessEvent.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanTransactionBusinessEvent.java index c2c061d83..f878e0117 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanTransactionBusinessEvent.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/externalevents/LoanTransactionBusinessEvent.java @@ -22,7 +22,7 @@ import java.time.format.DateTimeFormatter; import java.util.Objects; import lombok.Data; import lombok.EqualsAndHashCode; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; @EqualsAndHashCode(callSuper = true) @Data @@ -47,7 +47,7 @@ public class LoanTransactionBusinessEvent extends BusinessEvent { } @Override - public boolean verify(ExternalEventDTO externalEvent, DateTimeFormatter formatter) { + public boolean verify(ExternalEventResponse externalEvent, DateTimeFormatter formatter) { Object amount = externalEvent.getPayLoad().get("amount"); Object outstandingLoanBalance = externalEvent.getPayLoad().get("outstandingLoanBalance"); Object principalPortion = externalEvent.getPayLoad().get("principalPortion"); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java index c733d696e..327d2a695 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java @@ -67,7 +67,7 @@ import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.util.CallFailedRuntimeException; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; -import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; +import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse; import org.apache.fineract.integrationtests.BaseLoanIntegrationTest; import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessStepHelper; @@ -227,7 +227,7 @@ public class InitiateExternalAssetOwnerTransferTest extends BaseLoanIntegrationT new BigDecimal("757.420000"), new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000"))); - List allExternalEvents = ExternalEventHelper.getAllExternalEvents(REQUEST_SPEC, RESPONSE_SPEC); + List allExternalEvents = ExternalEventHelper.getAllExternalEvents(REQUEST_SPEC, RESPONSE_SPEC); Assertions.assertEquals(1, allExternalEvents.size()); Assertions.assertEquals("LoanOwnershipTransferBusinessEvent", allExternalEvents.get(0).getType()); Assertions.assertEquals(Long.valueOf(loanID), allExternalEvents.get(0).getAggregateRootId());