Skip to content

Commit b3f434b

Browse files
FINERACT-2238: New command processing - Business Date Management (org.apache.fineract.infrastructure.businessdate)
1 parent d5958f3 commit b3f434b

File tree

91 files changed

+1554
-1003
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1554
-1003
lines changed

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ buildscript {
2828
[
2929
'fineract-api',
3030
'fineract-core',
31+
'fineract-validation',
3132
'fineract-command',
3233
'fineract-accounting',
3334
'fineract-provider',
@@ -426,6 +427,9 @@ configure(project.fineractJavaProjects) {
426427
tasks.withType(Copy) {
427428
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
428429
}
430+
tasks.withType(Jar) {
431+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
432+
}
429433
tasks.withType(JavaCompile) {
430434
options.compilerArgs += [
431435
"-Xlint:cast",

buildSrc/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import static org.slf4j.LoggerFactory.*
2121

2222
plugins {
23-
id 'io.spring.dependency-management' version '1.1.6'
23+
id 'io.spring.dependency-management' version '1.1.7'
2424
id 'groovy'
2525
id 'java-gradle-plugin'
2626
id 'groovy-gradle-plugin'

buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencyManagement {
3838
mavenBom 'software.amazon.awssdk:bom:2.29.9'
3939
mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0'
4040
mavenBom 'org.testcontainers:testcontainers-bom:1.20.4'
41+
mavenBom 'org.glassfish.jersey:jersey-bom:3.1.10'
4142
}
4243

4344
dependencies {
@@ -117,7 +118,6 @@ dependencyManagement {
117118
dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
118119
dependency 'jakarta.jms:jakarta.jms-api:3.1.0'
119120
dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
120-
dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.10'
121121
dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version
122122
dependency 'org.apache.bval:org.apache.bval.bundle:3.0.2'
123123
dependency 'joda-time:joda-time:2.13.1'
@@ -195,6 +195,8 @@ dependencyManagement {
195195
dependency ('jakarta.xml.bind:jakarta.xml.bind-api:4.0.2') {
196196
exclude 'jakarta.activation:jakarta.activation-api'
197197
}
198+
dependency 'jakarta.validation:jakarta.validation-api:3.1.1'
199+
dependency 'org.hibernate.validator:hibernate-validator:8.0.2.Final'
198200

199201
dependency ('org.liquibase:liquibase-core:4.31.1') {
200202
exclude 'javax.xml.bind:jaxb-api'
@@ -243,6 +245,7 @@ dependencyManagement {
243245
dependency 'org.assertj:assertj-core:3.26.3'
244246

245247
dependency 'org.apache.commons:commons-math3:3.6.1'
248+
dependency 'commons-beanutils:commons-beanutils:1.11.0'
246249

247250
dependency 'org.mockito:mockito-inline:5.2.0'
248251

fineract-accounting/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencies {
3838
'org.springframework.batch:spring-batch-integration',
3939
'jakarta.ws.rs:jakarta.ws.rs-api',
4040
'org.glassfish.jersey.media:jersey-media-multipart',
41+
'org.glassfish.jersey.ext:jersey-bean-validation',
4142

4243
'com.google.guava:guava',
4344
'com.google.code.gson:gson',

fineract-branch/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies {
3232
'org.springframework.boot:spring-boot-starter-security',
3333
'jakarta.ws.rs:jakarta.ws.rs-api',
3434
'org.glassfish.jersey.media:jersey-media-multipart',
35+
'org.glassfish.jersey.ext:jersey-bean-validation',
3536

3637
'com.google.guava:guava',
3738
'com.google.code.gson:gson',

fineract-charge/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies {
3232
'org.springframework.boot:spring-boot-starter-security',
3333
'jakarta.ws.rs:jakarta.ws.rs-api',
3434
'org.glassfish.jersey.media:jersey-media-multipart',
35+
'org.glassfish.jersey.ext:jersey-bean-validation',
3536

3637
'com.google.guava:guava',
3738
'com.google.code.gson:gson',

fineract-command/dependencies.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ dependencies {
3939
'org.mapstruct:mapstruct',
4040
'com.lmax:disruptor',
4141
'com.ibm.icu:icu4j',
42-
'org.yakworks:spring-icu4j',
42+
'org.yakworks:spring-icu4j'
4343
)
4444
implementation('org.eclipse.persistence:org.eclipse.persistence.jpa') {
4545
exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence'

fineract-command/src/main/java/org/apache/fineract/command/core/Command.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class Command<T> implements Serializable {
3434

3535
private UUID id;
3636

37+
private String idempotencyKey;
38+
3739
private OffsetDateTime createdAt;
3840

3941
private String tenantId;

fineract-core/dependencies.gradle

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ dependencies {
2323
// Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library.
2424
// We also (normally should have) no need to ever use 'compileOnly'.
2525

26-
implementation(
27-
project(path: ':fineract-avro-schemas')
28-
)
26+
implementation(project(path: ':fineract-avro-schemas'))
27+
implementation(project(path: ':fineract-command'))
28+
implementation(project(path: ':fineract-validation'))
29+
2930

3031
// implementation dependencies are directly used (compiled against) in src/main (and src/test)
3132
implementation(
@@ -36,6 +37,7 @@ dependencies {
3637
'org.springframework.batch:spring-batch-integration',
3738
'jakarta.ws.rs:jakarta.ws.rs-api',
3839
'org.glassfish.jersey.media:jersey-media-multipart',
40+
'org.glassfish.jersey.ext:jersey-bean-validation',
3941
'org.apache.avro:avro',
4042

4143
'com.google.guava:guava',

fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResource.java

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,26 @@
2020

2121
import io.swagger.v3.oas.annotations.Operation;
2222
import io.swagger.v3.oas.annotations.Parameter;
23-
import io.swagger.v3.oas.annotations.media.Content;
24-
import io.swagger.v3.oas.annotations.media.Schema;
25-
import io.swagger.v3.oas.annotations.parameters.RequestBody;
26-
import io.swagger.v3.oas.annotations.responses.ApiResponse;
27-
import io.swagger.v3.oas.annotations.responses.ApiResponses;
2823
import io.swagger.v3.oas.annotations.tags.Tag;
24+
import jakarta.validation.Valid;
2925
import jakarta.ws.rs.Consumes;
3026
import jakarta.ws.rs.GET;
27+
import jakarta.ws.rs.HeaderParam;
3128
import jakarta.ws.rs.POST;
3229
import jakarta.ws.rs.Path;
3330
import jakarta.ws.rs.PathParam;
3431
import jakarta.ws.rs.Produces;
3532
import jakarta.ws.rs.core.MediaType;
3633
import java.util.List;
34+
import java.util.UUID;
35+
import java.util.function.Supplier;
3736
import lombok.RequiredArgsConstructor;
38-
import org.apache.fineract.commands.domain.CommandWrapper;
39-
import org.apache.fineract.commands.service.CommandWrapperBuilder;
40-
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
41-
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
42-
import org.apache.fineract.infrastructure.businessdate.data.request.BusinessDateRequest;
37+
import org.apache.fineract.command.core.CommandPipeline;
38+
import org.apache.fineract.infrastructure.businessdate.command.BusinessDateCommand;
39+
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
40+
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
4341
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
44-
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
45-
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
46-
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
42+
import org.apache.fineract.infrastructure.core.service.DateUtils;
4743
import org.springframework.stereotype.Component;
4844

4945
@RequiredArgsConstructor
@@ -52,19 +48,14 @@
5248
@Tag(name = "Business Date Management", description = "Business date management enables you to set up, fetch and adjust organisation business dates")
5349
public class BusinessDateApiResource {
5450

55-
private static final String BUSINESS_DATE = "BUSINESS_DATE";
56-
57-
private final PlatformSecurityContext securityContext;
58-
private final DefaultToApiJsonSerializer<BusinessDateData> jsonSerializer;
5951
private final BusinessDateReadPlatformService readPlatformService;
60-
private final PortfolioCommandSourceWritePlatformService commandWritePlatformService;
52+
private final CommandPipeline commandPipeline;
6153

6254
@GET
6355
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
6456
@Produces(MediaType.APPLICATION_JSON)
6557
@Operation(summary = "List all business dates", description = "")
66-
public List<BusinessDateData> getBusinessDates() {
67-
securityContext.authenticatedUser().validateHasReadPermission(BUSINESS_DATE);
58+
public List<BusinessDateResponse> getBusinessDates() {
6859
return this.readPlatformService.findAll();
6960
}
7061

@@ -73,23 +64,27 @@ public List<BusinessDateData> getBusinessDates() {
7364
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
7465
@Produces(MediaType.APPLICATION_JSON)
7566
@Operation(summary = "Retrieve a specific Business date", description = "")
76-
public BusinessDateData getBusinessDate(@PathParam("type") @Parameter(description = "type") final String type) {
77-
securityContext.authenticatedUser().validateHasReadPermission(BUSINESS_DATE);
67+
public BusinessDateResponse getBusinessDate(@PathParam("type") @Parameter(description = "type") final String type) {
7868
return this.readPlatformService.findByType(type);
7969
}
8070

8171
@POST
8272
@Consumes({ MediaType.APPLICATION_JSON })
8373
@Produces({ MediaType.APPLICATION_JSON })
8474
@Operation(summary = "Update Business Date", description = "")
85-
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = BusinessDateRequest.class)))
86-
@ApiResponses({
87-
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = BusinessDateApiResourceSwagger.BusinessDateResponse.class))) })
88-
public CommandProcessingResult updateBusinessDate(BusinessDateRequest businessDateRequest) {
89-
securityContext.authenticatedUser().validateHasUpdatePermission(BUSINESS_DATE);
90-
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateBusinessDate()
91-
.withJson(jsonSerializer.serialize(businessDateRequest)).build();
92-
return commandWritePlatformService.logCommandSource(commandRequest);
75+
public BusinessDateResponse updateBusinessDate(@HeaderParam("Idempotency-Key") String idempotencyKey,
76+
@Valid BusinessDateUpdateRequest request) {
77+
78+
final var command = new BusinessDateCommand();
79+
80+
command.setId(UUID.randomUUID());
81+
command.setIdempotencyKey(idempotencyKey);
82+
command.setCreatedAt(DateUtils.getAuditOffsetDateTime());
83+
command.setPayload(request);
84+
85+
final Supplier<BusinessDateResponse> response = commandPipeline.send(command);
86+
87+
return response.get();
9388
}
9489

9590
}

0 commit comments

Comments
 (0)