FINERACT-2169: Apply DTO instead String json in NotesApiResource

This commit is contained in:
oleksandr.masliuk
2025-03-14 18:12:37 +00:00
committed by Adam Saghy
parent c236ee04ef
commit b698d7247b
9 changed files with 70 additions and 131 deletions
@@ -18,7 +18,7 @@
*/
package com.acme.fineract.portfolio.note.service;
import java.util.Collection;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.portfolio.note.data.NoteData;
import org.apache.fineract.portfolio.note.service.NoteReadPlatformService;
@@ -42,7 +42,7 @@ public class AcmeNoteReadPlatformService implements NoteReadPlatformService, Ini
}
@Override
public Collection<NoteData> retrieveNotesByResource(Long resourceId, Integer noteTypeId) {
public List<NoteData> retrieveNotesByResource(Long resourceId, Integer noteTypeId) {
return null;
}
}
@@ -18,12 +18,12 @@
*/
package org.apache.fineract.portfolio.note.service;
import java.util.Collection;
import java.util.List;
import org.apache.fineract.portfolio.note.data.NoteData;
public interface NoteReadPlatformService {
NoteData retrieveNote(Long noteId, Long resourceId, Integer noteTypeId);
Collection<NoteData> retrieveNotesByResource(Long resourceId, Integer noteTypeId);
List<NoteData> retrieveNotesByResource(Long resourceId, Integer noteTypeId);
}
@@ -23,7 +23,7 @@ import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import org.apache.fineract.organisation.monetary.api.CurrenciesApiResourceSwagger.CurrencyItem;
import org.apache.fineract.portfolio.note.api.NotesApiResourceSwagger.GetResourceTypeResourceIdNotesResponse;
import org.apache.fineract.portfolio.note.data.NoteData;
import org.apache.fineract.portfolio.paymenttype.api.PaymentTypeApiResourceSwagger.GetPaymentTypesResponse;
/**
@@ -111,7 +111,7 @@ final class JournalEntriesApiResourceSwagger {
@Schema(example = "2")
public Long transactionId;
public EnumOptionType transactionType;
public GetResourceTypeResourceIdNotesResponse noteData;
public NoteData noteData;
public PaymentDetailData paymentDetails;
}
@@ -20,7 +20,6 @@ package org.apache.fineract.portfolio.note.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
@@ -35,12 +34,10 @@ import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.commands.domain.CommandWrapper;
@@ -48,10 +45,10 @@ import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.note.data.NoteData;
import org.apache.fineract.portfolio.note.data.NoteRequest;
import org.apache.fineract.portfolio.note.domain.NoteType;
import org.apache.fineract.portfolio.note.exception.NoteResourceNotSupportedException;
import org.apache.fineract.portfolio.note.service.NoteReadPlatformService;
@@ -84,10 +81,9 @@ public class NotesApiResource {
@Operation(summary = "Retrieve a Resource's description", description = "Retrieves a Resource's Notes\n\n"
+ "Note: Notes are returned in descending createOn order.\n" + "\n" + "Example Requests:\n" + "\n" + "clients/2/notes\n" + "\n"
+ "\n" + "groups/2/notes?fields=note,createdOn,createdByUsername")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = NotesApiResourceSwagger.GetResourceTypeResourceIdNotesResponse.class)))) })
public String retrieveNotesByResource(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
@PathParam("resourceId") @Parameter(description = "resourceId") final Long resourceId, @Context final UriInfo uriInfo) {
public List<NoteData> retrieveNotesByResource(
@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
@PathParam("resourceId") @Parameter(description = "resourceId") final Long resourceId) {
final NoteType noteType = NoteType.fromApiUrl(resourceType);
@@ -99,10 +95,7 @@ public class NotesApiResource {
final Integer noteTypeId = noteType.getValue();
final Collection<NoteData> notes = this.readPlatformService.retrieveNotesByResource(resourceId, noteTypeId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, notes, NOTE_DATA_PARAMETERS);
return readPlatformService.retrieveNotesByResource(resourceId, noteTypeId);
}
@GET
@@ -113,11 +106,9 @@ public class NotesApiResource {
+ "clients/1/notes/76\n" + "\n" + "\n" + "groups/1/notes/20\n" + "\n" + "\n"
+ "clients/1/notes/76?fields=note,createdOn,createdByUsername\n" + "\n" + "\n"
+ "groups/1/notes/20?fields=note,createdOn,createdByUsername")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = NotesApiResourceSwagger.GetResourceTypeResourceIdNotesNoteIdResponse.class))) })
public String retrieveNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
public NoteData retrieveNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
@PathParam("resourceId") @Parameter(description = "resourceId") final Long resourceId,
@PathParam("noteId") @Parameter(description = "noteId") final Long noteId, @Context final UriInfo uriInfo) {
@PathParam("noteId") @Parameter(description = "noteId") final Long noteId) {
final NoteType noteType = NoteType.fromApiUrl(resourceType);
@@ -130,9 +121,7 @@ public class NotesApiResource {
final Integer noteTypeId = noteType.getValue();
final NoteData note = this.readPlatformService.retrieveNote(noteId, resourceId, noteTypeId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, note, NOTE_DATA_PARAMETERS);
return note;
}
@POST
@@ -140,12 +129,12 @@ public class NotesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Add a Resource Note", description = "Adds a new note to a supported resource.\n\n" + "Example Requests:\n" + "\n"
+ "clients/1/notes\n" + "\n" + "\n" + "groups/1/notes")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = NotesApiResourceSwagger.PostResourceTypeResourceIdNotesRequest.class)))
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = NoteRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = NotesApiResourceSwagger.PostResourceTypeResourceIdNotesResponse.class))) })
public String addNewNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
public CommandProcessingResult addNewNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
@PathParam("resourceId") @Parameter(description = "resourceId") final Long resourceId,
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
@Parameter(hidden = true) final NoteRequest noteRequest) {
final NoteType noteType = NoteType.fromApiUrl(resourceType);
@@ -155,11 +144,9 @@ public class NotesApiResource {
final CommandWrapper resourceDetails = getResourceDetails(noteType, resourceId);
final CommandWrapper commandRequest = new CommandWrapperBuilder().createNote(resourceDetails, resourceType, resourceId)
.withJson(apiRequestBodyAsJson).build();
.withJson(toApiJsonSerializer.serialize(noteRequest)).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
@PUT
@@ -167,13 +154,13 @@ public class NotesApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Update a Resource Note", description = "Updates a Resource Note")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = NotesApiResourceSwagger.PutResourceTypeResourceIdNotesNoteIdRequest.class)))
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = NoteRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = NotesApiResourceSwagger.PutResourceTypeResourceIdNotesNoteIdResponse.class))) })
public String updateNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
public CommandProcessingResult updateNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
@PathParam("resourceId") @Parameter(description = "resourceId") final Long resourceId,
@PathParam("noteId") @Parameter(description = "noteId") final Long noteId,
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
@Parameter(hidden = true) final NoteRequest noteRequest) {
final NoteType noteType = NoteType.fromApiUrl(resourceType);
@@ -184,11 +171,9 @@ public class NotesApiResource {
final CommandWrapper resourceDetails = getResourceDetails(noteType, resourceId);
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateNote(resourceDetails, resourceType, resourceId, noteId)
.withJson(apiRequestBodyAsJson).build();
.withJson(toApiJsonSerializer.serialize(noteRequest)).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
@DELETE
@@ -198,7 +183,7 @@ public class NotesApiResource {
@Operation(summary = "Delete a Resource Note", description = "Deletes a Resource Note")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = NotesApiResourceSwagger.DeleteResourceTypeResourceIdNotesNoteIdResponse.class))) })
public String deleteNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
public CommandProcessingResult deleteNote(@PathParam("resourceType") @Parameter(description = "resourceType") final String resourceType,
@PathParam("resourceId") @Parameter(description = "resourceId") final Long resourceId,
@PathParam("noteId") @Parameter(description = "noteId") final Long noteId) {
@@ -213,9 +198,7 @@ public class NotesApiResource {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteNote(resourceDetails, resourceType, resourceId, noteId)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
private CommandWrapper getResourceDetails(final NoteType type, final Long resourceId) {
@@ -19,7 +19,6 @@
package org.apache.fineract.portfolio.note.api;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.ZonedDateTime;
/**
* Created by Chirag Gupta on 12/29/17.
@@ -28,70 +27,6 @@ public final class NotesApiResourceSwagger {
private NotesApiResourceSwagger() {}
@Schema(description = "GetResourceTypeResourceIdNotesResponse")
public static final class GetResourceTypeResourceIdNotesResponse {
private GetResourceTypeResourceIdNotesResponse() {}
static final class GetNotesNoteType {
private GetNotesNoteType() {}
@Schema(example = "100")
public Long id;
@Schema(example = "noteType.client")
public String code;
@Schema(example = "Client note")
public String description;
}
@Schema(example = "2")
public Long id;
@Schema(example = "1")
public Long clientId;
public GetNotesNoteType noteType;
@Schema(example = "First note edited")
public String note;
@Schema(example = "1")
public Long createdById;
@Schema(example = "mifos")
public String createdByUsername;
@Schema(example = "1342498505000")
public ZonedDateTime createdOn;
@Schema(example = "1")
public Long updatedById;
@Schema(example = "mifos")
public String updatedByUsername;
@Schema(example = "1342498517000")
public ZonedDateTime updatedOn;
}
@Schema(description = "GetResourceTypeResourceIdNotesNoteIdResponse")
public static final class GetResourceTypeResourceIdNotesNoteIdResponse {
private GetResourceTypeResourceIdNotesNoteIdResponse() {}
@Schema(example = "76")
public Long id;
@Schema(example = "1")
public Long clientId;
public GetResourceTypeResourceIdNotesResponse.GetNotesNoteType noteType;
@Schema(example = "a note about the client")
public String note;
@Schema(example = "1")
public Long createdById;
@Schema(example = "mifos")
public String createdByUsername;
@Schema(example = "1359463135000")
public ZonedDateTime createdOn;
@Schema(example = "1")
public Long updatedById;
@Schema(example = "mifos")
public String updatedByUsername;
@Schema(example = "1359463135000")
public ZonedDateTime updatedOn;
}
@Schema(description = "PostResourceTypeResourceIdNotesRequest")
public static final class PostResourceTypeResourceIdNotesRequest {
@@ -114,15 +49,6 @@ public final class NotesApiResourceSwagger {
public Integer resourceId;
}
@Schema(description = "PutResourceTypeResourceIdNotesNoteIdRequest")
public static final class PutResourceTypeResourceIdNotesNoteIdRequest {
private PutResourceTypeResourceIdNotesNoteIdRequest() {}
@Schema(example = "a note about the client")
public String note;
}
@Schema(description = "PutResourceTypeResourceIdNotesNoteIdResponse")
public static final class PutResourceTypeResourceIdNotesNoteIdResponse {
@@ -0,0 +1,36 @@
/**
* 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.portfolio.note.data;
import java.io.Serial;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NoteRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String note;
}
@@ -23,7 +23,6 @@ import java.sql.SQLException;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
@@ -101,7 +100,7 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
}
@Override
public Collection<NoteData> retrieveNotesByResource(final Long resourceId, final Integer noteTypeId) {
public List<NoteData> retrieveNotesByResource(final Long resourceId, final Integer noteTypeId) {
final NoteType noteType = NoteType.fromInt(noteTypeId);
final NoteMapper rm = new NoteMapper();
List<Object> paramList = new ArrayList<>(Arrays.asList(resourceId));
@@ -28,7 +28,7 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.fineract.client.models.GetResourceTypeResourceIdNotesNoteIdResponse;
import org.apache.fineract.client.models.NoteData;
import org.apache.fineract.client.models.PostResourceTypeResourceIdNotesResponse;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
@@ -222,8 +222,7 @@ public class NotesTest {
Assertions.assertNotNull(postNoteResponse);
Assertions.assertNotNull(postNoteResponse.getResourceId());
final GetResourceTypeResourceIdNotesNoteIdResponse getNoteResponse = NotesHelper.getSavingsNote(requestSpec, responseSpec,
savingsId, postNoteResponse.getResourceId());
NoteData getNoteResponse = NotesHelper.retrieveSavingsNote(requestSpec, responseSpec, savingsId, postNoteResponse.getResourceId());
Assertions.assertNotNull(getNoteResponse);
Assertions.assertEquals(noteText, getNoteResponse.getNote());
}
@@ -21,7 +21,7 @@ package org.apache.fineract.integrationtests.common;
import com.google.gson.Gson;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import org.apache.fineract.client.models.GetResourceTypeResourceIdNotesNoteIdResponse;
import org.apache.fineract.client.models.NoteData;
import org.apache.fineract.client.models.PostResourceTypeResourceIdNotesResponse;
import org.apache.fineract.client.util.JSON;
@@ -217,15 +217,11 @@ public final class NotesHelper {
return GSON.fromJson(response, PostResourceTypeResourceIdNotesResponse.class);
}
// 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 GetResourceTypeResourceIdNotesNoteIdResponse getSavingsNote(RequestSpecification requestSpec,
ResponseSpecification responseSpec, Integer savingsId, Integer noteId) {
public static NoteData retrieveSavingsNote(RequestSpecification requestSpec, ResponseSpecification responseSpec, Integer savingsId,
Integer noteId) {
final String noteURL = SAVINGS_URL + "/" + savingsId + "/notes/" + noteId + "?" + Utils.TENANT_IDENTIFIER;
final String response = Utils.performServerGet(requestSpec, responseSpec, noteURL);
return GSON.fromJson(response, GetResourceTypeResourceIdNotesNoteIdResponse.class);
return GSON.fromJson(response, NoteData.class);
}
}