FINERACT-2181: Split Datatable service
This commit is contained in:
committed by
Adam Saghy
parent
123899eac1
commit
1d569d9ecf
+55
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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.dataqueries.service;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.apache.fineract.infrastructure.core.service.PagedLocalRequest;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface DatatableReadService {
|
||||
|
||||
List<DatatableData> retrieveDatatableNames(String appTable);
|
||||
|
||||
DatatableData retrieveDatatable(String datatable);
|
||||
|
||||
List<JsonObject> queryDataTable(@NotNull String datatable, @NotNull String columnName, String columnValue,
|
||||
@NotNull String resultColumns);
|
||||
|
||||
Page<JsonObject> queryDataTableAdvanced(@NotNull String datatable, @NotNull PagedLocalRequest<AdvancedQueryData> pagedRequest);
|
||||
|
||||
boolean buildDataQueryEmbedded(@NotNull EntityTables entityTable, @NotNull String datatable, @NotNull AdvancedQueryData request,
|
||||
@NotNull List<String> selectColumns, @NotNull StringBuilder select, @NotNull StringBuilder from, @NotNull StringBuilder where,
|
||||
@NotNull List<Object> params, String mainAlias, String alias, String dateFormat, String dateTimeFormat, Locale locale);
|
||||
|
||||
GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id);
|
||||
|
||||
Long countDatatableEntries(String datatableName, Long appTableId, String foreignKeyColumn);
|
||||
|
||||
String getTableName(String Url);
|
||||
|
||||
String getDataTableName(String Url);
|
||||
|
||||
}
|
||||
+2
-32
@@ -18,25 +18,11 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.service;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.service.PagedLocalRequest;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
public interface ReadWriteNonCoreDataService {
|
||||
|
||||
List<DatatableData> retrieveDatatableNames(String appTable);
|
||||
|
||||
DatatableData retrieveDatatable(String datatable);
|
||||
public interface DatatableWriteService {
|
||||
|
||||
@PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'REGISTER_DATATABLE')")
|
||||
void registerDatatable(JsonCommand command);
|
||||
@@ -50,8 +36,6 @@ public interface ReadWriteNonCoreDataService {
|
||||
@PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'DEREGISTER_DATATABLE')")
|
||||
void deregisterDatatable(String datatable);
|
||||
|
||||
GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id);
|
||||
|
||||
CommandProcessingResult createDatatable(JsonCommand command);
|
||||
|
||||
void updateDatatable(String datatableName, JsonCommand command);
|
||||
@@ -62,8 +46,6 @@ public interface ReadWriteNonCoreDataService {
|
||||
|
||||
CommandProcessingResult createNewDatatableEntry(String datatable, Long appTableId, String json);
|
||||
|
||||
CommandProcessingResult createPPIEntry(String datatable, Long appTableId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateDatatableEntryOneToMany(String datatable, Long appTableId, Long datatableId, JsonCommand command);
|
||||
@@ -72,18 +54,6 @@ public interface ReadWriteNonCoreDataService {
|
||||
|
||||
CommandProcessingResult deleteDatatableEntry(String datatable, Long appTableId, Long datatableId, JsonCommand command);
|
||||
|
||||
String getTableName(String Url);
|
||||
CommandProcessingResult createPPIEntry(String datatable, Long appTableId, JsonCommand command);
|
||||
|
||||
String getDataTableName(String Url);
|
||||
|
||||
Long countDatatableEntries(String datatableName, Long appTableId, String foreignKeyColumn);
|
||||
|
||||
List<JsonObject> queryDataTable(@NotNull String datatable, @NotNull String columnName, String columnValue,
|
||||
@NotNull String resultColumns);
|
||||
|
||||
Page<JsonObject> queryDataTableAdvanced(@NotNull String datatable, @NotNull PagedLocalRequest<AdvancedQueryData> pagedRequest);
|
||||
|
||||
boolean buildDataQueryEmbedded(@NotNull EntityTables entityTable, @NotNull String datatable, @NotNull AdvancedQueryData request,
|
||||
@NotNull List<String> selectColumns, @NotNull StringBuilder select, @NotNull StringBuilder from, @NotNull StringBuilder where,
|
||||
@NotNull List<Object> params, String mainAlias, String alias, String dateFormat, String dateTimeFormat, Locale locale);
|
||||
}
|
||||
+13
-12
@@ -55,8 +55,9 @@ import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer
|
||||
import org.apache.fineract.infrastructure.core.service.PagedLocalRequest;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -72,7 +73,8 @@ public class DatatablesApiResource {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final GenericDataService genericDataService;
|
||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
private final DatatableReadService datatableReadService;
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
private final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@@ -87,7 +89,7 @@ public class DatatablesApiResource {
|
||||
public String getDatatables(@QueryParam("apptable") @Parameter(description = "apptable") final String apptable,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
final List<DatatableData> result = this.readWriteNonCoreDataService.retrieveDatatableNames(apptable);
|
||||
final List<DatatableData> result = this.datatableReadService.retrieveDatatableNames(apptable);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
@@ -184,7 +186,7 @@ public class DatatablesApiResource {
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DatatablesApiResourceSwagger.PutDataTablesResponse.class))) })
|
||||
public String deregisterDatatable(@PathParam("datatable") @Parameter(description = "datatable") final String datatable) {
|
||||
this.readWriteNonCoreDataService.deregisterDatatable(datatable);
|
||||
this.datatableWriteService.deregisterDatatable(datatable);
|
||||
final CommandProcessingResult result = new CommandProcessingResultBuilder().withResourceIdAsString(datatable).build();
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
@@ -199,7 +201,7 @@ public class DatatablesApiResource {
|
||||
public String getDatatable(@PathParam("datatable") @Parameter(description = "datatable") final String datatable,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
final DatatableData result = this.readWriteNonCoreDataService.retrieveDatatable(datatable);
|
||||
final DatatableData result = this.datatableReadService.retrieveDatatable(datatable);
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@@ -216,8 +218,7 @@ public class DatatablesApiResource {
|
||||
@Context final UriInfo uriInfo) {
|
||||
this.context.authenticatedUser().validateHasDatatableReadPermission(datatable);
|
||||
|
||||
final List<JsonObject> result = this.readWriteNonCoreDataService.queryDataTable(datatable, columnFilter, valueFilter,
|
||||
resultColumns);
|
||||
final List<JsonObject> result = this.datatableReadService.queryDataTable(datatable, columnFilter, valueFilter, resultColumns);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
@@ -231,7 +232,7 @@ public class DatatablesApiResource {
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = List.class))) })
|
||||
public String advancedQuery(@PathParam("datatable") @Parameter(description = "datatable") final String datatable,
|
||||
PagedLocalRequest<AdvancedQueryData> queryRequest, @Context final UriInfo uriInfo) {
|
||||
final Page<JsonObject> result = this.readWriteNonCoreDataService.queryDataTableAdvanced(datatable, queryRequest);
|
||||
final Page<JsonObject> result = this.datatableReadService.queryDataTableAdvanced(datatable, queryRequest);
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@@ -254,8 +255,8 @@ public class DatatablesApiResource {
|
||||
|
||||
this.context.authenticatedUser().validateHasDatatableReadPermission(datatable);
|
||||
|
||||
final GenericResultsetData results = this.readWriteNonCoreDataService.retrieveDataTableGenericResultSet(datatable, apptableId,
|
||||
order, null);
|
||||
final GenericResultsetData results = this.datatableReadService.retrieveDataTableGenericResultSet(datatable, apptableId, order,
|
||||
null);
|
||||
|
||||
String json = "";
|
||||
final boolean genericResultSet = ApiParameterHelper.genericResultSet(uriInfo.getQueryParameters());
|
||||
@@ -280,8 +281,8 @@ public class DatatablesApiResource {
|
||||
|
||||
this.context.authenticatedUser().validateHasDatatableReadPermission(datatable);
|
||||
|
||||
final GenericResultsetData results = this.readWriteNonCoreDataService.retrieveDataTableGenericResultSet(datatable, apptableId,
|
||||
order, datatableId);
|
||||
final GenericResultsetData results = this.datatableReadService.retrieveDataTableGenericResultSet(datatable, apptableId, order,
|
||||
datatableId);
|
||||
|
||||
String json = "";
|
||||
if (genericResultSet) {
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ import lombok.RequiredArgsConstructor;
|
||||
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.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -30,12 +30,12 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@RequiredArgsConstructor
|
||||
public class CreateDatatableCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return writePlatformService.createDatatable(command);
|
||||
return datatableWriteService.createDatatable(command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ import lombok.RequiredArgsConstructor;
|
||||
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.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -30,12 +30,12 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@RequiredArgsConstructor
|
||||
public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return writePlatformService.createNewDatatableEntry(command.getEntityName(), command.entityId(), command);
|
||||
return datatableWriteService.createNewDatatableEntry(command.getEntityName(), command.entityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-9
@@ -18,30 +18,27 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DeleteDatatableCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteDatatableCommandHandler(final ReadWriteNonCoreDataService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
final String datatableName = command.getUrl().replaceAll("/datatables/", "");
|
||||
this.writePlatformService.deleteDatatable(datatableName);
|
||||
datatableWriteService.deleteDatatable(datatableName);
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withResourceIdAsString(datatableName).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-9
@@ -18,27 +18,24 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DeleteOneToManyDatatableEntryCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteOneToManyDatatableEntryCommandHandler(final ReadWriteNonCoreDataService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.deleteDatatableEntry(command.getEntityName(), command.entityId(), command.subentityId(), command);
|
||||
return datatableWriteService.deleteDatatableEntry(command.getEntityName(), command.entityId(), command.subentityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-9
@@ -18,27 +18,24 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DeleteOneToOneDatatableEntryCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteOneToOneDatatableEntryCommandHandler(final ReadWriteNonCoreDataService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.deleteDatatableEntries(command.getEntityName(), command.entityId(), command);
|
||||
return datatableWriteService.deleteDatatableEntries(command.getEntityName(), command.entityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-12
@@ -18,32 +18,28 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RegisterDatatableCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public RegisterDatatableCommandHandler(final ReadWriteNonCoreDataService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
private final DatatableReadService datatableReadService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
datatableWriteService.registerDatatable(command);
|
||||
|
||||
this.writePlatformService.registerDatatable(command);
|
||||
|
||||
return new CommandProcessingResultBuilder().withResourceIdAsString(this.writePlatformService.getDataTableName(command.getUrl()))
|
||||
.build();
|
||||
return new CommandProcessingResultBuilder().withResourceIdAsString(datatableReadService.getDataTableName(command.getUrl())).build();
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -23,7 +23,7 @@ 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.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -31,16 +31,16 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@RequiredArgsConstructor
|
||||
public class UpdateDatatableCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
final String datatableName = command.getUrl().replaceAll("/datatables/", "");
|
||||
|
||||
this.writePlatformService.updateDatatable(datatableName, command);
|
||||
datatableWriteService.updateDatatable(datatableName, command);
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withResourceIdAsString(datatableName).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-10
@@ -18,30 +18,26 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UpdateOneToManyDatatableEntryCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateOneToManyDatatableEntryCommandHandler(final ReadWriteNonCoreDataService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.updateDatatableEntryOneToMany(command.getEntityName(), command.entityId(), command.subentityId(),
|
||||
return this.datatableWriteService.updateDatatableEntryOneToMany(command.getEntityName(), command.entityId(), command.subentityId(),
|
||||
command);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-10
@@ -18,30 +18,25 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UpdateOneToOneDatatableEntryCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ReadWriteNonCoreDataService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateOneToOneDatatableEntryCommandHandler(final ReadWriteNonCoreDataService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
final CommandProcessingResult commandProcessingResult = this.writePlatformService
|
||||
final CommandProcessingResult commandProcessingResult = this.datatableWriteService
|
||||
.updateDatatableEntryOneToOne(command.getEntityName(), command.entityId(), command);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -55,4 +50,5 @@ public class UpdateOneToOneDatatableEntryCommandHandler implements NewCommandSou
|
||||
.with(commandProcessingResult.getChanges()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
/**
|
||||
* 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.dataqueries.service;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.apache.fineract.infrastructure.core.service.database.SqlOperator.EQ;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.gson.JsonObject;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.core.service.PagedLocalRequest;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DataTableValidator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
||||
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
|
||||
import org.apache.fineract.portfolio.search.data.ColumnFilterData;
|
||||
import org.apache.fineract.portfolio.search.service.SearchUtil;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.support.PageableExecutionUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class DatatableReadServiceImpl implements DatatableReadService {
|
||||
|
||||
private static final String APPLICATION_TABLE_NAME = "application_table_name";
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
private final PlatformSecurityContext context;
|
||||
private final GenericDataService genericDataService;
|
||||
private final DataTableValidator dataTableValidator;
|
||||
private final SqlValidator sqlValidator;
|
||||
private final SearchUtil searchUtil;
|
||||
private final DatatableUtil datatableUtil;
|
||||
|
||||
@Override
|
||||
public List<DatatableData> retrieveDatatableNames(final String appTable) {
|
||||
// PERMITTED datatables
|
||||
String sql = "select application_table_name, registered_table_name, entity_subtype from x_registered_table where exists"
|
||||
+ " (select 'f' from m_appuser_role ur join m_role r on r.id = ur.role_id"
|
||||
+ " left join m_role_permission rp on rp.role_id = r.id left join m_permission p on p.id = rp.permission_id"
|
||||
+ " where ur.appuser_id = ? and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat"
|
||||
+ "('READ_', registered_table_name))) ";
|
||||
|
||||
Object[] params;
|
||||
if (appTable != null) {
|
||||
sql = sql + " and application_table_name like ? ";
|
||||
params = new Object[] { this.context.authenticatedUser().getId(), appTable };
|
||||
} else {
|
||||
params = new Object[] { this.context.authenticatedUser().getId() };
|
||||
}
|
||||
sql = sql + " order by application_table_name, registered_table_name";
|
||||
|
||||
final List<DatatableData> datatables = new ArrayList<>();
|
||||
|
||||
final SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql, params); // NOSONAR
|
||||
while (rowSet.next()) {
|
||||
final String appTableName = rowSet.getString(APPLICATION_TABLE_NAME);
|
||||
final String registeredDatatableName = rowSet.getString("registered_table_name");
|
||||
final String entitySubType = rowSet.getString("entity_subtype");
|
||||
final List<ResultsetColumnHeaderData> columnHeaderData = genericDataService.fillResultsetColumnHeaders(registeredDatatableName);
|
||||
|
||||
datatables.add(DatatableData.create(appTableName, registeredDatatableName, entitySubType, columnHeaderData));
|
||||
}
|
||||
|
||||
return datatables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatatableData retrieveDatatable(final String datatable) {
|
||||
// PERMITTED datatables
|
||||
sqlValidator.validate(datatable);
|
||||
final String sql = "select application_table_name, registered_table_name, entity_subtype from x_registered_table "
|
||||
+ " where exists (select 'f' from m_appuser_role ur join m_role r on r.id = ur.role_id"
|
||||
+ " left join m_role_permission rp on rp.role_id = r.id left join m_permission p on p.id = rp.permission_id"
|
||||
+ " where ur.appuser_id = ? and registered_table_name=? and (p.code in ('ALL_FUNCTIONS', "
|
||||
+ "'ALL_FUNCTIONS_READ') or p.code = concat('READ_', registered_table_name))) "
|
||||
+ " order by application_table_name, registered_table_name";
|
||||
|
||||
DatatableData datatableData = null;
|
||||
|
||||
final SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql, new Object[] { this.context.authenticatedUser().getId(), datatable }); // NOSONAR
|
||||
if (rowSet.next()) {
|
||||
final String appTableName = rowSet.getString(APPLICATION_TABLE_NAME);
|
||||
final String registeredDatatableName = rowSet.getString("registered_table_name");
|
||||
final String entitySubType = rowSet.getString("entity_subtype");
|
||||
final List<ResultsetColumnHeaderData> columnHeaderData = this.genericDataService
|
||||
.fillResultsetColumnHeaders(registeredDatatableName);
|
||||
|
||||
datatableData = DatatableData.create(appTableName, registeredDatatableName, entitySubType, columnHeaderData);
|
||||
}
|
||||
|
||||
return datatableData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> queryDataTable(@NotNull String datatable, @NotNull String columnName, String columnValueString,
|
||||
@NotNull String resultColumnsString) {
|
||||
datatable = datatableUtil.validateDatatableRegistered(datatable);
|
||||
Map<String, ResultsetColumnHeaderData> headersByName = searchUtil
|
||||
.mapHeadersToName(genericDataService.fillResultsetColumnHeaders(datatable));
|
||||
|
||||
List<String> resultColumns = asList(resultColumnsString.split(","));
|
||||
List<String> selectColumns = searchUtil.validateToJdbcColumnNames(resultColumns, headersByName, false);
|
||||
ResultsetColumnHeaderData column = searchUtil.validateToJdbcColumn(columnName, headersByName, false);
|
||||
|
||||
Object columnValue = searchUtil.parseJdbcColumnValue(column, columnValueString, null, null, null, false, sqlGenerator);
|
||||
String sql = sqlGenerator.buildSelect(selectColumns, null, false) + " " + sqlGenerator.buildFrom(datatable, null, false) + " WHERE "
|
||||
+ EQ.formatPlaceholder(sqlGenerator, column.getColumnName(), 1, null);
|
||||
SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql, columnValue); // NOSONAR
|
||||
|
||||
List<JsonObject> results = new ArrayList<>();
|
||||
while (rowSet.next()) {
|
||||
searchUtil.extractJsonResult(rowSet, selectColumns, resultColumns, results);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<JsonObject> queryDataTableAdvanced(@NotNull String datatable, @NotNull PagedLocalRequest<AdvancedQueryData> pagedRequest) {
|
||||
datatable = datatableUtil.validateDatatableRegistered(datatable);
|
||||
context.authenticatedUser().validateHasDatatableReadPermission(datatable);
|
||||
|
||||
AdvancedQueryData request = pagedRequest.getRequest().orElseThrow();
|
||||
dataTableValidator.validateTableSearch(request);
|
||||
|
||||
Map<String, ResultsetColumnHeaderData> headersByName = searchUtil
|
||||
.mapHeadersToName(genericDataService.fillResultsetColumnHeaders(datatable));
|
||||
String pkColumn = searchUtil.getFiltered(headersByName.values(), ResultsetColumnHeaderData::getIsColumnPrimaryKey).getColumnName();
|
||||
|
||||
List<ColumnFilterData> columnFilters = request.getNonNullFilters();
|
||||
columnFilters.forEach(e -> e.setColumn(searchUtil.validateToJdbcColumnName(e.getColumn(), headersByName, false)));
|
||||
|
||||
List<String> resultColumns = request.getNonNullResultColumns();
|
||||
List<String> selectColumns;
|
||||
if (resultColumns.isEmpty()) {
|
||||
resultColumns.add(pkColumn);
|
||||
selectColumns = new ArrayList<>();
|
||||
selectColumns.add(pkColumn);
|
||||
} else {
|
||||
selectColumns = searchUtil.validateToJdbcColumnNames(resultColumns, headersByName, false);
|
||||
}
|
||||
PageRequest pageable = pagedRequest.toPageable();
|
||||
PageRequest sortPageable;
|
||||
if (pageable.getSort().isSorted()) {
|
||||
List<Sort.Order> orders = pageable.getSort().toList();
|
||||
sortPageable = pageable.withSort(Sort.by(orders.stream()
|
||||
.map(e -> e.withProperty(searchUtil.validateToJdbcColumnName(e.getProperty(), headersByName, false))).toList()));
|
||||
} else {
|
||||
pageable = pageable.withSort(Sort.Direction.DESC, pkColumn);
|
||||
sortPageable = pageable;
|
||||
}
|
||||
|
||||
String dateFormat = pagedRequest.getDateFormat();
|
||||
String dateTimeFormat = pagedRequest.getDateTimeFormat();
|
||||
Locale locale = pagedRequest.getLocaleObject();
|
||||
|
||||
String select = sqlGenerator.buildSelect(selectColumns, null, false);
|
||||
String from = " " + sqlGenerator.buildFrom(datatable, null, false);
|
||||
StringBuilder where = new StringBuilder();
|
||||
ArrayList<Object> params = new ArrayList<>();
|
||||
searchUtil.buildQueryCondition(columnFilters, where, params, null, headersByName, dateFormat, dateTimeFormat, locale, false,
|
||||
sqlGenerator);
|
||||
|
||||
List<JsonObject> results = new ArrayList<>();
|
||||
Object[] args = params.toArray();
|
||||
|
||||
// Execute the count Query
|
||||
String countQuery = "SELECT COUNT(*)" + from + where;
|
||||
Integer totalElements = jdbcTemplate.queryForObject(countQuery, Integer.class, args); // NOSONAR
|
||||
if (totalElements == null || totalElements == 0) {
|
||||
return PageableExecutionUtils.getPage(results, pageable, () -> 0);
|
||||
}
|
||||
|
||||
StringBuilder query = new StringBuilder().append(select).append(from).append(where);
|
||||
query.append(" ").append(sqlGenerator.buildOrderBy(sortPageable.getSort().toList(), null, false));
|
||||
if (pageable.isPaged()) {
|
||||
query.append(" ").append(sqlGenerator.limit(pageable.getPageSize(), (int) pageable.getOffset()));
|
||||
}
|
||||
|
||||
SqlRowSet rowSet = jdbcTemplate.queryForRowSet(query.toString(), args);
|
||||
|
||||
while (rowSet.next()) {
|
||||
searchUtil.extractJsonResult(rowSet, selectColumns, resultColumns, results);
|
||||
}
|
||||
return PageableExecutionUtils.getPage(results, pageable, () -> totalElements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean buildDataQueryEmbedded(@NotNull EntityTables entityTable, @NotNull String datatable, @NotNull AdvancedQueryData request,
|
||||
@NotNull List<String> selectColumns, @NotNull StringBuilder select, @NotNull StringBuilder from, @NotNull StringBuilder where,
|
||||
@NotNull List<Object> params, String mainAlias, String alias, String dateFormat, String dateTimeFormat, Locale locale) {
|
||||
List<String> resultColumns = request.getResultColumns();
|
||||
List<ColumnFilterData> columnFilters = request.getColumnFilters();
|
||||
if ((resultColumns == null || resultColumns.isEmpty()) && (columnFilters == null || columnFilters.isEmpty())) {
|
||||
return false;
|
||||
}
|
||||
datatable = datatableUtil.validateDatatableRegistered(datatable);
|
||||
context.authenticatedUser().validateHasDatatableReadPermission(datatable);
|
||||
|
||||
Map<String, ResultsetColumnHeaderData> headersByName = searchUtil
|
||||
.mapHeadersToName(genericDataService.fillResultsetColumnHeaders(datatable));
|
||||
|
||||
List<String> thisSelectColumns = searchUtil.validateToJdbcColumnNames(resultColumns, headersByName, true);
|
||||
if (columnFilters != null) {
|
||||
columnFilters.forEach(e -> e.setColumn(searchUtil.validateToJdbcColumnName(e.getColumn(), headersByName, false)));
|
||||
}
|
||||
|
||||
select.append(sqlGenerator.buildSelect(thisSelectColumns, alias, true));
|
||||
selectColumns.addAll(thisSelectColumns);
|
||||
|
||||
String joinType = "LEFT";
|
||||
if (searchUtil.buildQueryCondition(columnFilters, where, params, alias, headersByName, dateFormat, dateTimeFormat, locale, true,
|
||||
sqlGenerator)) {
|
||||
joinType = null; // INNER
|
||||
}
|
||||
from.append(sqlGenerator.buildJoin(datatable, alias, entityTable.getForeignKeyColumnNameOnDatatable(), mainAlias,
|
||||
entityTable.getRefColumn(), joinType));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public GenericResultsetData retrieveDataTableGenericResultSet(final String dataTableName, final Long appTableId, final String order,
|
||||
final Long id) {
|
||||
final EntityTables entityTable = datatableUtil.queryForApplicationEntity(dataTableName);
|
||||
datatableUtil.checkMainResourceExistsWithinScope(entityTable, appTableId);
|
||||
return datatableUtil.retrieveDataTableGenericResultSet(entityTable, dataTableName, appTableId, order, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countDatatableEntries(final String datatableName, final Long appTableId, String foreignKeyColumn) {
|
||||
final String sqlString = "SELECT COUNT(" + sqlGenerator.escape(foreignKeyColumn) + ") FROM " + sqlGenerator.escape(datatableName)
|
||||
+ " WHERE " + sqlGenerator.escape(foreignKeyColumn) + " = " + appTableId;
|
||||
return this.jdbcTemplate.queryForObject(sqlString, Long.class); // NOSONAR
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDataTableName(String url) {
|
||||
List<String> urlParts = Splitter.on('/').splitToList(url);
|
||||
return urlParts.get(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName(String url) {
|
||||
List<String> urlParts = Splitter.on('/').splitToList(url);
|
||||
return urlParts.get(4);
|
||||
}
|
||||
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* 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.dataqueries.service;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.serialization.DatatableCommandFromApiJsonDeserializer.DATATABLE_NAME_REGEX_PATTERN;
|
||||
import static org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant.API_FIELD_NAME;
|
||||
import static org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant.TABLE_FIELD_ID;
|
||||
import static org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant.TABLE_REGISTERED_TABLE;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetRowData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableNotFoundException;
|
||||
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableSystemErrorException;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.portfolio.search.service.SearchUtil;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DatatableUtil {
|
||||
|
||||
private static final String APPLICATION_TABLE_NAME = "application_table_name";
|
||||
|
||||
private final SearchUtil searchUtil;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final SqlValidator sqlValidator;
|
||||
private final PlatformSecurityContext context;
|
||||
private final GenericDataService genericDataService;
|
||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
public boolean isMultirowDatatable(final List<ResultsetColumnHeaderData> columnHeaders) {
|
||||
return searchUtil.findFiltered(columnHeaders, e -> e.isNamed(TABLE_FIELD_ID)) != null;
|
||||
}
|
||||
|
||||
public String getFKField(EntityTables entityTable) {
|
||||
return entityTable.getForeignKeyColumnNameOnDatatable();
|
||||
}
|
||||
|
||||
public String validateDatatableRegistered(String datatable) {
|
||||
validateDatatableName(datatable);
|
||||
if (!isRegisteredDataTable(datatable)) {
|
||||
throw new DatatableNotFoundException(datatable);
|
||||
}
|
||||
return datatable;
|
||||
}
|
||||
|
||||
public void validateDatatableName(final String name) {
|
||||
if (name == null || name.isEmpty()) {
|
||||
throw new PlatformDataIntegrityException("error.msg.datatables.datatable.null.name", "Data table name must not be blank.");
|
||||
} else if (!name.matches(DATATABLE_NAME_REGEX_PATTERN)) {
|
||||
throw new PlatformDataIntegrityException("error.msg.datatables.datatable.invalid.name.regex", "Invalid data table name.", name);
|
||||
}
|
||||
sqlValidator.validate(name);
|
||||
}
|
||||
|
||||
public EntityTables resolveEntity(final String entityName) {
|
||||
EntityTables entityTable = EntityTables.fromEntityName(entityName);
|
||||
if (entityTable == null) {
|
||||
throw new PlatformDataIntegrityException("error.msg.invalid.application.table", "Invalid Datatable entity: " + entityName,
|
||||
API_FIELD_NAME, entityName);
|
||||
}
|
||||
return entityTable;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EntityTables queryForApplicationEntity(final String datatable) {
|
||||
sqlValidator.validate(datatable);
|
||||
final String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = ?";
|
||||
final SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql, datatable); // NOSONAR
|
||||
|
||||
String applicationTableName;
|
||||
if (rowSet.next()) {
|
||||
applicationTableName = rowSet.getString(APPLICATION_TABLE_NAME);
|
||||
} else {
|
||||
throw new DatatableNotFoundException(datatable);
|
||||
}
|
||||
return resolveEntity(applicationTableName);
|
||||
}
|
||||
|
||||
public CommandProcessingResult checkMainResourceExistsWithinScope(@NotNull EntityTables entityTable, final Long appTableId) {
|
||||
final String sql = dataScopedSQL(entityTable, appTableId);
|
||||
log.debug("data scoped sql: {}", sql);
|
||||
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql);
|
||||
|
||||
if (!rs.next()) {
|
||||
throw new DatatableNotFoundException(entityTable, appTableId);
|
||||
}
|
||||
final Long officeId = (Long) rs.getObject("officeId");
|
||||
final Long groupId = (Long) rs.getObject("groupId");
|
||||
final Long clientId = (Long) rs.getObject("clientId");
|
||||
final Long savingsId = (Long) rs.getObject("savingsId");
|
||||
final Long loanId = (Long) rs.getObject("loanId");
|
||||
final Long transactionId = (Long) rs.getObject("transactionId");
|
||||
final Long entityId = (Long) rs.getObject("entityId");
|
||||
|
||||
if (rs.next()) {
|
||||
throw new DatatableSystemErrorException("System Error: More than one row returned from data scoping query");
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withOfficeId(officeId) //
|
||||
.withGroupId(groupId) //
|
||||
.withClientId(clientId) //
|
||||
.withSavingsId(savingsId) //
|
||||
.withLoanId(loanId).withTransactionId(transactionId == null ? null : String.valueOf(transactionId)).withEntityId(entityId)//
|
||||
.build();
|
||||
}
|
||||
|
||||
public String dataScopedSQL(@NotNull EntityTables entityTable, final Long appTableId) {
|
||||
// unfortunately have to, one way or another, be able to restrict data to the users office hierarchy. Here, a
|
||||
// few key tables are done. But if additional fields are needed on other tables the same pattern applies
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
String officeHierarchy = currentUser.getOffice().getHierarchy();
|
||||
// m_loan and m_savings_account are connected to an m_office through either an m_client or an m_group If both it
|
||||
// means it relates to an m_client that is in a group (still an m_client account)
|
||||
return switch (entityTable) {
|
||||
case LOAN -> "select distinct x.* from ( "
|
||||
+ "(select o.id as officeId, l.group_id as groupId, l.client_id as clientId, null as savingsId, l.id as loanId, null as transactionId, null as entityId from m_loan l "
|
||||
+ getClientOfficeJoinCondition(officeHierarchy, "l") + " where l.id = " + appTableId + ")" + " union all "
|
||||
+ "(select o.id as officeId, l.group_id as groupId, l.client_id as clientId, null as savingsId, l.id as loanId, null as transactionId, null as entityId from m_loan l "
|
||||
+ getGroupOfficeJoinCondition(officeHierarchy, "l") + " where l.id = " + appTableId + ")" + " ) as x";
|
||||
case SAVINGS -> "select distinct x.* from ( "
|
||||
+ "(select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, null as transactionId, null as entityId "
|
||||
+ "from m_savings_account s " + getClientOfficeJoinCondition(officeHierarchy, "s") + " where s.id = " + appTableId + ")"
|
||||
+ " union all "
|
||||
+ "(select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, null as transactionId, null as entityId "
|
||||
+ "from m_savings_account s " + getGroupOfficeJoinCondition(officeHierarchy, "s") + " where s.id = " + appTableId + ")"
|
||||
+ " ) as x";
|
||||
case SAVINGS_TRANSACTION -> "select distinct x.* from ( "
|
||||
+ "(select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, t.id as transactionId, null as entityId "
|
||||
+ "from m_savings_account_transaction t join m_savings_account s on t.savings_account_id = s.id "
|
||||
+ getClientOfficeJoinCondition(officeHierarchy, "s") + " where t.id = " + appTableId + ")" + " union all "
|
||||
+ "(select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, t.id as transactionId, null as entityId "
|
||||
+ "from m_savings_account_transaction t join m_savings_account s on t.savings_account_id = s.id "
|
||||
+ getGroupOfficeJoinCondition(officeHierarchy, "s") + " where t.id = " + appTableId + ")" + " ) as x";
|
||||
case CLIENT ->
|
||||
"select o.id as officeId, null as groupId, c.id as clientId, null as savingsId, null as loanId, null as transactionId, null as entityId from m_client c "
|
||||
+ getOfficeJoinCondition(officeHierarchy, "c") + " where c.id = " + appTableId;
|
||||
case GROUP, CENTER ->
|
||||
"select o.id as officeId, g.id as groupId, null as clientId, null as savingsId, null as loanId, null as transactionId, null as entityId from m_group g "
|
||||
+ getOfficeJoinCondition(officeHierarchy, "g") + " where g.id = " + appTableId;
|
||||
case OFFICE ->
|
||||
"select o.id as officeId, null as groupId, null as clientId, null as savingsId, null as loanId, null as transactionId, null as entityId from m_office o "
|
||||
+ "where o.hierarchy like '" + officeHierarchy + "%'" + " and o.id = " + appTableId;
|
||||
case LOAN_PRODUCT, SAVINGS_PRODUCT, SHARE_PRODUCT ->
|
||||
"select null as officeId, null as groupId, null as clientId, null as savingsId, null as loanId, null as transactionId, p.id as entityId from "
|
||||
+ entityTable.getName() + " as p WHERE p.id = " + appTableId;
|
||||
default -> throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria",
|
||||
"Application Table: " + entityTable.getName() + " not catered for in data Scoping");
|
||||
};
|
||||
}
|
||||
|
||||
public String getOfficeJoinCondition(String officeHierarchy, String joinTableAlias) {
|
||||
return " join m_office o on o.id = " + joinTableAlias + ".office_id and o.hierarchy like '" + officeHierarchy + "%' ";
|
||||
}
|
||||
|
||||
public String getGroupOfficeJoinCondition(String officeHierarchy, String appTableAlias) {
|
||||
return " join m_group g on g.id = " + appTableAlias + ".group_id " + getOfficeJoinCondition(officeHierarchy, "g");
|
||||
}
|
||||
|
||||
public String getClientOfficeJoinCondition(String officeHierarchy, String appTableAlias) {
|
||||
return " join m_client c on c.id = " + appTableAlias + ".client_id " + getOfficeJoinCondition(officeHierarchy, "c");
|
||||
}
|
||||
|
||||
public GenericResultsetData retrieveDataTableGenericResultSet(final EntityTables entityTable, final String dataTableName,
|
||||
final Long appTableId, final String order, final Long id) {
|
||||
final List<ResultsetColumnHeaderData> columnHeaders = genericDataService.fillResultsetColumnHeaders(dataTableName);
|
||||
final boolean multiRow = isMultirowDatatable(columnHeaders);
|
||||
|
||||
String whereClause = getFKField(entityTable) + " = " + appTableId;
|
||||
sqlValidator.validate(whereClause);
|
||||
String sql = "select * from " + sqlGenerator.escape(dataTableName) + " where " + whereClause;
|
||||
|
||||
// id only used for reading a specific entry that belongs to appTableId (in a one to many datatable)
|
||||
if (multiRow && id != null) {
|
||||
sql = sql + " and " + TABLE_FIELD_ID + " = " + id;
|
||||
}
|
||||
if (StringUtils.isNotBlank(order)) {
|
||||
columnValidator.validateSqlInjection(sql, order);
|
||||
sql = sql + " order by " + order;
|
||||
}
|
||||
|
||||
final List<ResultsetRowData> result = genericDataService.fillResultsetRowData(sql, columnHeaders);
|
||||
return new GenericResultsetData(columnHeaders, result);
|
||||
}
|
||||
|
||||
private boolean isRegisteredDataTable(final String datatable) {
|
||||
final String sql = "SELECT COUNT(application_table_name) FROM " + TABLE_REGISTERED_TABLE + " WHERE registered_table_name = ?";
|
||||
final Integer count = jdbcTemplate.queryForObject(sql, Integer.class, datatable);
|
||||
return count != null && count > 0;
|
||||
}
|
||||
|
||||
}
|
||||
+241
-639
File diff suppressed because it is too large
Load Diff
+10
-17
@@ -30,7 +30,6 @@ import org.apache.fineract.infrastructure.core.service.Page;
|
||||
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
||||
import org.apache.fineract.infrastructure.core.service.database.JdbcJavaType;
|
||||
import org.apache.fineract.infrastructure.core.service.database.SqlOperator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableCheckStatusData;
|
||||
@@ -46,7 +45,6 @@ import org.apache.fineract.portfolio.loanproduct.data.LoanProductData;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
|
||||
import org.apache.fineract.portfolio.savings.service.SavingsProductReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -55,33 +53,28 @@ import org.springframework.stereotype.Service;
|
||||
public class EntityDatatableChecksReadPlatformServiceImpl implements EntityDatatableChecksReadService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
protected final DatabaseTypeResolver databaseTypeResolver;
|
||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
private final RegisterDataTableMapper registerDataTableMapper;
|
||||
private final EntityDataTableChecksMapper entityDataTableChecksMapper;
|
||||
private final EntityDatatableChecksRepository entityDatatableChecksRepository;
|
||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
private final DatatableReadService datatableReadService;
|
||||
private final LoanProductReadPlatformService loanProductReadPlatformService;
|
||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||
private final PaginationHelper paginationHelper;
|
||||
|
||||
@Autowired
|
||||
public EntityDatatableChecksReadPlatformServiceImpl(final JdbcTemplate jdbcTemplate, DatabaseTypeResolver databaseTypeResolver,
|
||||
DatabaseSpecificSQLGenerator sqlGenerator, final LoanProductReadPlatformService loanProductReadPlatformService,
|
||||
final SavingsProductReadPlatformService savingsProductReadPlatformService,
|
||||
final EntityDatatableChecksRepository entityDatatableChecksRepository,
|
||||
final ReadWriteNonCoreDataService readWriteNonCoreDataService, PaginationHelper paginationHelper) {
|
||||
|
||||
public EntityDatatableChecksReadPlatformServiceImpl(final JdbcTemplate jdbcTemplate, final DatabaseSpecificSQLGenerator sqlGenerator,
|
||||
final EntityDatatableChecksRepository entityDatatableChecksRepository, final DatatableReadService datatableReadService,
|
||||
final LoanProductReadPlatformService loanProductReadPlatformService,
|
||||
final SavingsProductReadPlatformService savingsProductReadPlatformService, final PaginationHelper paginationHelper) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.databaseTypeResolver = databaseTypeResolver;
|
||||
this.sqlGenerator = sqlGenerator;
|
||||
this.registerDataTableMapper = new RegisterDataTableMapper();
|
||||
this.entityDataTableChecksMapper = new EntityDataTableChecksMapper();
|
||||
this.entityDatatableChecksRepository = entityDatatableChecksRepository;
|
||||
this.datatableReadService = datatableReadService;
|
||||
this.loanProductReadPlatformService = loanProductReadPlatformService;
|
||||
this.savingsProductReadPlatformService = savingsProductReadPlatformService;
|
||||
this.entityDatatableChecksRepository = entityDatatableChecksRepository;
|
||||
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
|
||||
this.paginationHelper = paginationHelper;
|
||||
this.registerDataTableMapper = new RegisterDataTableMapper();
|
||||
this.entityDataTableChecksMapper = new EntityDataTableChecksMapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,7 +127,7 @@ public class EntityDatatableChecksReadPlatformServiceImpl implements EntityDatat
|
||||
if (tableRequiredBeforeAction != null && tableRequiredBeforeAction.size() > 0) {
|
||||
List<DatatableData> ret = new ArrayList<>();
|
||||
for (EntityDatatableChecks t : tableRequiredBeforeAction) {
|
||||
ret.add(this.readWriteNonCoreDataService.retrieveDatatable(t.getDatatableName()));
|
||||
ret.add(this.datatableReadService.retrieveDatatable(t.getDatatableName()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+6
-5
@@ -60,7 +60,8 @@ public class EntityDatatableChecksWritePlatformServiceImpl implements EntityData
|
||||
private final PlatformSecurityContext context;
|
||||
private final EntityDatatableChecksDataValidator fromApiJsonDeserializer;
|
||||
private final EntityDatatableChecksRepository entityDatatableChecksRepository;
|
||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
private final DatatableReadService datatableReadService;
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
private final LoanProductReadPlatformService loanProductReadPlatformService;
|
||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
@@ -77,7 +78,7 @@ public class EntityDatatableChecksWritePlatformServiceImpl implements EntityData
|
||||
// check if the datatable is linked to the entity
|
||||
|
||||
String datatableName = command.stringValueOfParameterNamed("datatableName");
|
||||
DatatableData datatableData = this.readWriteNonCoreDataService.retrieveDatatable(datatableName);
|
||||
DatatableData datatableData = this.datatableReadService.retrieveDatatable(datatableName);
|
||||
|
||||
if (datatableData == null) {
|
||||
throw new DatatableNotFoundException(datatableName);
|
||||
@@ -154,7 +155,7 @@ public class EntityDatatableChecksWritePlatformServiceImpl implements EntityData
|
||||
for (EntityDatatableChecks t : tableRequiredBeforeClientActivation) {
|
||||
|
||||
final String datatableName = t.getDatatableName();
|
||||
final Long countEntries = readWriteNonCoreDataService.countDatatableEntries(datatableName, entityId, foreignKeyColumn);
|
||||
final Long countEntries = datatableReadService.countDatatableEntries(datatableName, entityId, foreignKeyColumn);
|
||||
|
||||
log.debug("The are {} entries in the table {}", countEntries, datatableName);
|
||||
if (countEntries.intValue() == 0) {
|
||||
@@ -182,7 +183,7 @@ public class EntityDatatableChecksWritePlatformServiceImpl implements EntityData
|
||||
for (EntityDatatableChecks t : tableRequiredBeforAction) {
|
||||
|
||||
final String datatableName = t.getDatatableName();
|
||||
final Long countEntries = readWriteNonCoreDataService.countDatatableEntries(datatableName, entityId, foreignKeyColumn);
|
||||
final Long countEntries = datatableReadService.countDatatableEntries(datatableName, entityId, foreignKeyColumn);
|
||||
|
||||
log.debug("The are {} entries in the table {}", countEntries, datatableName);
|
||||
if (countEntries.intValue() == 0) {
|
||||
@@ -220,7 +221,7 @@ public class EntityDatatableChecksWritePlatformServiceImpl implements EntityData
|
||||
isMakerCheckerEnabled = true;
|
||||
}
|
||||
try {
|
||||
this.readWriteNonCoreDataService.createNewDatatableEntry(datatableName, entityId, datatableData.toString());
|
||||
datatableWriteService.createNewDatatableEntry(datatableName, entityId, datatableData.toString());
|
||||
} catch (PlatformApiDataValidationException e) {
|
||||
for (ApiParameterError error : e.getErrors()) {
|
||||
error.setParameterName("datatables." + datatableName + "." + error.getParameterName());
|
||||
|
||||
+27
-15
@@ -26,13 +26,15 @@ import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecific
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DataTableValidator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableKeywordGenerator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadServiceImpl;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableUtil;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteServiceImpl;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataServiceImpl;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.portfolio.search.service.SearchUtil;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -45,17 +47,27 @@ public class DataQueriesAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ReadWriteNonCoreDataService readWriteNonCoreDataService(final JdbcTemplate jdbcTemplate,
|
||||
final DatabaseTypeResolver databaseTypeResolver, final DatabaseSpecificSQLGenerator sqlGenerator,
|
||||
final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper, final GenericDataService genericDataService,
|
||||
final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||
final ConfigurationDomainService configurationDomainService, final CodeReadPlatformService codeReadPlatformService,
|
||||
final DataTableValidator dataTableValidator, final ColumnValidator columnValidator,
|
||||
final NamedParameterJdbcTemplate namedParameterJdbcTemplate, DatatableKeywordGenerator datatableKeywordGenerator,
|
||||
SqlValidator sqlValidator, SearchUtil searchUtil, final BusinessEventNotifierService businessEventNotifierService) {
|
||||
return new ReadWriteNonCoreDataServiceImpl(jdbcTemplate, databaseTypeResolver, sqlGenerator, context, fromJsonHelper,
|
||||
genericDataService, fromApiJsonDeserializer, configurationDomainService, codeReadPlatformService, dataTableValidator,
|
||||
columnValidator, namedParameterJdbcTemplate, datatableKeywordGenerator, sqlValidator, searchUtil,
|
||||
businessEventNotifierService);
|
||||
public DatatableReadService datatableReadService(final JdbcTemplate jdbcTemplate, final DatabaseSpecificSQLGenerator sqlGenerator,
|
||||
final PlatformSecurityContext context, final GenericDataService genericDataService, final DataTableValidator dataTableValidator,
|
||||
final SqlValidator sqlValidator, final SearchUtil searchUtil, final DatatableUtil datatableUtil) {
|
||||
return new DatatableReadServiceImpl(jdbcTemplate, sqlGenerator, context, genericDataService, dataTableValidator, sqlValidator,
|
||||
searchUtil, datatableUtil);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public DatatableWriteService datatableWriteService(final JdbcTemplate jdbcTemplate, final DatabaseTypeResolver databaseTypeResolver,
|
||||
final DatabaseSpecificSQLGenerator sqlGenerator, final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
||||
final GenericDataService genericDataService, final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||
final ConfigurationDomainService configurationDomainService, final CodeReadPlatformService codeReadPlatformService,
|
||||
final DataTableValidator dataTableValidator, final NamedParameterJdbcTemplate namedParameterJdbcTemplate,
|
||||
final DatatableKeywordGenerator datatableKeywordGenerator, final SearchUtil searchUtil,
|
||||
final BusinessEventNotifierService businessEventNotifierService, final DatatableReadService datatableReadService,
|
||||
final DatatableUtil datatableUtil) {
|
||||
return new DatatableWriteServiceImpl(jdbcTemplate, databaseTypeResolver, sqlGenerator, context, fromJsonHelper, genericDataService,
|
||||
fromApiJsonDeserializer, configurationDomainService, codeReadPlatformService, dataTableValidator,
|
||||
namedParameterJdbcTemplate, datatableKeywordGenerator, searchUtil, businessEventNotifierService, datatableReadService,
|
||||
datatableUtil);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -26,8 +26,8 @@ import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
||||
import org.apache.fineract.infrastructure.survey.data.ClientScoresOverview;
|
||||
@@ -46,7 +46,7 @@ public class ReadSurveyServiceImpl implements ReadSurveyService {
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final SqlValidator sqlValidator;
|
||||
private final GenericDataService genericDataService;
|
||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
private final DatatableReadService datatableReadService;
|
||||
|
||||
@Override
|
||||
public List<SurveyDataTableData> retrieveAllSurveys() {
|
||||
@@ -183,7 +183,7 @@ public class ReadSurveyServiceImpl implements ReadSurveyService {
|
||||
@Override
|
||||
public GenericResultsetData retrieveSurveyEntry(String surveyName, Long clientId, Long entryId) {
|
||||
|
||||
return readWriteNonCoreDataService.retrieveDataTableGenericResultSet(surveyName, clientId, null, entryId);
|
||||
return datatableReadService.retrieveDataTableGenericResultSet(surveyName, clientId, null, entryId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -24,7 +24,8 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableWriteService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -35,16 +36,16 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@RequiredArgsConstructor
|
||||
public class WriteSurveyServiceImpl implements WriteSurveyService {
|
||||
|
||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
private final DatatableReadService datatableReadService;
|
||||
private final DatatableWriteService datatableWriteService;
|
||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult registerSurvey(JsonCommand command) {
|
||||
|
||||
final String dataTableName = this.readWriteNonCoreDataService.getDataTableName(command.getUrl());
|
||||
final String dataTableName = datatableReadService.getDataTableName(command.getUrl());
|
||||
final String permissionSql = this.getPermissionSql(dataTableName);
|
||||
this.readWriteNonCoreDataService.registerDatatable(command, permissionSql);
|
||||
datatableWriteService.registerDatatable(command, permissionSql);
|
||||
|
||||
return CommandProcessingResult.commandOnlyResult(command.commandId());
|
||||
|
||||
@@ -73,8 +74,7 @@ public class WriteSurveyServiceImpl implements WriteSurveyService {
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult fullFillSurvey(final String dataTableName, final Long appTableId, final JsonCommand command) {
|
||||
|
||||
return readWriteNonCoreDataService.createPPIEntry(dataTableName, appTableId, command);
|
||||
return datatableWriteService.createPPIEntry(dataTableName, appTableId, command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -38,8 +38,8 @@ import org.apache.fineract.infrastructure.core.service.database.SqlOperator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DataTableValidator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionData;
|
||||
@@ -66,7 +66,7 @@ public class SavingsAccountTransactionsSearchServiceImpl implements SavingsAccou
|
||||
private final PlatformSecurityContext context;
|
||||
private final GenericDataService genericDataService;
|
||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
private final ReadWriteNonCoreDataService datatableService;
|
||||
private final DatatableReadService datatableReadService;
|
||||
private final DataTableValidator dataTableValidator;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final SearchUtil searchUtil;
|
||||
@@ -239,7 +239,7 @@ public class SavingsAccountTransactionsSearchServiceImpl implements SavingsAccou
|
||||
ArrayList<Object> dataParams = new ArrayList<>();
|
||||
for (int i = 0; i < datatableQueries.size(); i++) {
|
||||
TableQueryData tableQuery = datatableQueries.get(i);
|
||||
boolean added = datatableService.buildDataQueryEmbedded(EntityTables.SAVINGS_TRANSACTION, tableQuery.getTable(),
|
||||
boolean added = datatableReadService.buildDataQueryEmbedded(EntityTables.SAVINGS_TRANSACTION, tableQuery.getTable(),
|
||||
tableQuery.getQuery(), selectColumns, dataSelect, dataFrom, dataWhere, dataParams, alias, ("d" + i), dateFormat,
|
||||
dateTimeFormat, locale);
|
||||
if (added) {
|
||||
|
||||
+2
-2
@@ -30,10 +30,10 @@ import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DataTableValidator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.DatatableReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.entityaccess.service.FineractEntityAccessUtil;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
@@ -154,7 +154,7 @@ public class SavingsConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(SavingsAccountTransactionSearchService.class)
|
||||
public SavingsAccountTransactionSearchService savingsAccountTransactionSearchService(PlatformSecurityContext context,
|
||||
GenericDataService genericDataService, DatabaseSpecificSQLGenerator sqlGenerator, ReadWriteNonCoreDataService datatableService,
|
||||
GenericDataService genericDataService, DatabaseSpecificSQLGenerator sqlGenerator, DatatableReadService datatableService,
|
||||
DataTableValidator dataTableValidator, JdbcTemplate jdbcTemplate, SearchUtil searchUtil) {
|
||||
return new SavingsAccountTransactionsSearchServiceImpl(context, genericDataService, sqlGenerator, datatableService,
|
||||
dataTableValidator, jdbcTemplate, searchUtil);
|
||||
|
||||
+115
-84
@@ -18,11 +18,13 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.dataqueries.service;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -36,66 +38,64 @@ import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||
import org.apache.fineract.infrastructure.codes.service.CodeReadPlatformService;
|
||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.domain.ActionContext;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DatatableCommandFromApiJsonDeserializer;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DataTableValidator;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetRowData;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.datatable.DatatableEntryBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.infrastructure.security.utils.DefaultSqlValidator;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.portfolio.search.service.SearchUtil;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.PreparedStatementCreator;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class DatatableBusinessEventTest {
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
class DatatableBusinessEventTest {
|
||||
|
||||
private static final String DATATABLE_NAME = "test_loan_data";
|
||||
private static final long APP_TABLE_ID = 1L;
|
||||
private static final long DATATABLE_ID = 1L;
|
||||
|
||||
@Mock
|
||||
private PlatformSecurityContext context;
|
||||
@Mock
|
||||
private BusinessEventNotifierService businessEventNotifierService;
|
||||
@Mock
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
@Mock
|
||||
private GenericDataService genericDataService;
|
||||
@Mock
|
||||
private SearchUtil searchUtil;
|
||||
@Mock
|
||||
private DatabaseTypeResolver databaseTypeResolver;
|
||||
@Mock
|
||||
private DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
@Mock
|
||||
private FineractPlatformTenantConnection tenantConnection;
|
||||
@Mock
|
||||
private DefaultSqlValidator sqlValidator;
|
||||
private PlatformSecurityContext context;
|
||||
@Mock
|
||||
private FromJsonHelper fromJsonHelper;
|
||||
@Mock
|
||||
private GenericDataService genericDataService;
|
||||
@Mock
|
||||
private DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
@Mock
|
||||
private ConfigurationDomainService configurationDomainService;
|
||||
@@ -104,38 +104,73 @@ public class DatatableBusinessEventTest {
|
||||
@Mock
|
||||
private DataTableValidator dataTableValidator;
|
||||
@Mock
|
||||
private ColumnValidator columnValidator;
|
||||
@Mock
|
||||
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||
@Mock
|
||||
private DatatableKeywordGenerator datatableKeywordGenerator;
|
||||
@Mock
|
||||
private SearchUtil searchUtil;
|
||||
@Mock
|
||||
private BusinessEventNotifierService businessEventNotifierService;
|
||||
@Mock
|
||||
private DatatableReadService datatableReadService;
|
||||
@Mock
|
||||
private DatatableUtil datatableUtil;
|
||||
|
||||
@InjectMocks
|
||||
private ReadWriteNonCoreDataServiceImpl underTest;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor;
|
||||
|
||||
private static String DATATABLE_NAME = "test_loan_data";
|
||||
private DatatableWriteServiceImpl underTest;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
void setUp() {
|
||||
setupThreadLocalContext();
|
||||
setupSecurityContext();
|
||||
setupEntityTable();
|
||||
setupCommandProcessingResult();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
ThreadLocalContextUtil.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotifyBusinessEventAfterCreatingNewDatatableEntry() {
|
||||
setupCreateDatatableEntryMocks();
|
||||
JsonCommand command = createJsonCommand("{}", APP_TABLE_ID);
|
||||
|
||||
underTest.createNewDatatableEntry(DATATABLE_NAME, APP_TABLE_ID, command);
|
||||
|
||||
verifyBusinessEvent(APP_TABLE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotifyBusinessEventAfterUpdatingDatatableEntry() {
|
||||
setupUpdateDeleteDatatableMocks();
|
||||
JsonCommand command = createJsonCommand("{}", APP_TABLE_ID);
|
||||
|
||||
underTest.updateDatatableEntryOneToMany(DATATABLE_NAME, APP_TABLE_ID, DATATABLE_ID, command);
|
||||
|
||||
verifyBusinessEvent(APP_TABLE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotifyBusinessEventAfterDeletingDatatableEntry() {
|
||||
setupUpdateDeleteDatatableMocks();
|
||||
JsonCommand command = createJsonCommand("{}", APP_TABLE_ID);
|
||||
|
||||
underTest.deleteDatatableEntry(DATATABLE_NAME, APP_TABLE_ID, DATATABLE_ID, command);
|
||||
|
||||
verifyBusinessEvent(APP_TABLE_ID);
|
||||
}
|
||||
|
||||
private void setupThreadLocalContext() {
|
||||
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
|
||||
ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
|
||||
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, LocalDate.parse("2024-01-16"),
|
||||
BusinessDateType.COB_DATE, LocalDate.parse("2024-01-15"))));
|
||||
|
||||
SqlRowSet sqlRS = Mockito.mock(SqlRowSet.class);
|
||||
SqlRowSet sqlRSData = Mockito.mock(SqlRowSet.class);
|
||||
doNothing().when(sqlValidator).validate(anyString());
|
||||
when(jdbcTemplate.queryForRowSet(anyString(), anyString())).thenReturn(sqlRS);
|
||||
when(jdbcTemplate.queryForRowSet(anyString())).thenReturn(sqlRSData);
|
||||
|
||||
when(sqlRS.next()).thenReturn(true).thenReturn(false);
|
||||
when(sqlRS.getString("application_table_name")).thenReturn("m_loan");
|
||||
when(sqlRSData.next()).thenReturn(true).thenReturn(false);
|
||||
when(sqlRSData.getObject(anyString())).thenReturn(1L);
|
||||
Map<BusinessDateType, LocalDate> businessDates = Map.of(BusinessDateType.BUSINESS_DATE, LocalDate.parse("2024-01-16"),
|
||||
BusinessDateType.COB_DATE, LocalDate.parse("2024-01-15"));
|
||||
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(businessDates));
|
||||
}
|
||||
|
||||
private void setupSecurityContext() {
|
||||
AppUser currentUser = Mockito.mock(AppUser.class);
|
||||
Office office = Mockito.mock(Office.class);
|
||||
when(context.authenticatedUser()).thenReturn(currentUser);
|
||||
@@ -143,61 +178,57 @@ public class DatatableBusinessEventTest {
|
||||
when(office.getHierarchy()).thenReturn(".");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
ThreadLocalContextUtil.reset();
|
||||
private void setupEntityTable() {
|
||||
EntityTables entityTable = Mockito.mock(EntityTables.class);
|
||||
when(entityTable.getForeignKeyColumnNameOnDatatable()).thenReturn("loan_id");
|
||||
when(datatableUtil.queryForApplicationEntity(anyString())).thenReturn(entityTable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void businessEventCreateNewDatatableEntryTest() {
|
||||
private void setupCommandProcessingResult() {
|
||||
CommandProcessingResult commandProcessingResult = Mockito.mock(CommandProcessingResult.class);
|
||||
when(commandProcessingResult.getOfficeId()).thenReturn(1L);
|
||||
when(datatableUtil.checkMainResourceExistsWithinScope(any(EntityTables.class), anyLong())).thenReturn(commandProcessingResult);
|
||||
}
|
||||
|
||||
private void setupCreateDatatableEntryMocks() {
|
||||
List<ResultsetColumnHeaderData> columnHeaders = new ArrayList<>();
|
||||
when(genericDataService.fillResultsetColumnHeaders(anyString())).thenReturn(columnHeaders);
|
||||
|
||||
when(jdbcTemplate.update(any(PreparedStatementCreator.class), any(KeyHolder.class))).thenReturn(1);
|
||||
|
||||
underTest.createNewDatatableEntry(DATATABLE_NAME, 1L, createJsonCommand("{}", 1L));
|
||||
GeneratedKeyHolder keyHolder = Mockito.mock(GeneratedKeyHolder.class);
|
||||
when(keyHolder.getKeys()).thenReturn(Map.of("id", 1L));
|
||||
when(sqlGenerator.fetchPK(any())).thenReturn(1L);
|
||||
|
||||
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = verifyBusinessEvents(1);
|
||||
verifyDatatableBusinessEvent(businessEventArgumentCaptor, 0, 1L);
|
||||
when(fromJsonHelper.extractDataMap(any(), anyString())).thenReturn(new HashMap<>());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void businessEventUpdateDatatableEntryTest() {
|
||||
List<Object> values = new ArrayList<>();
|
||||
values.add(1L);
|
||||
List<ResultsetRowData> result = new ArrayList<>();
|
||||
result.add(ResultsetRowData.create(values));
|
||||
when(genericDataService.fillResultsetRowData(anyString(), any())).thenReturn(result);
|
||||
private void setupUpdateDeleteDatatableMocks() {
|
||||
List<ResultsetColumnHeaderData> columnHeaders = new ArrayList<>();
|
||||
List<Object> rowValues = new ArrayList<>();
|
||||
rowValues.add(1L);
|
||||
|
||||
// ResultsetColumnHeaderData resultSet = Mockito.mock(ResultsetColumnHeaderData.class);
|
||||
// when(searchUtil.getFiltered(columnHeaders,
|
||||
// ResultsetColumnHeaderData::getIsColumnPrimaryKey)).thenReturn(resultSet);
|
||||
List<ResultsetRowData> rows = new ArrayList<>();
|
||||
rows.add(ResultsetRowData.create(rowValues));
|
||||
|
||||
underTest.updateDatatableEntryOneToMany(DATATABLE_NAME, 1L, 1L, createJsonCommand("{}", 1L));
|
||||
GenericResultsetData resultData = new GenericResultsetData(columnHeaders, rows);
|
||||
|
||||
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = verifyBusinessEvents(1);
|
||||
verifyDatatableBusinessEvent(businessEventArgumentCaptor, 0, 1L);
|
||||
Mockito.doReturn(resultData).when(datatableUtil).retrieveDataTableGenericResultSet(any(EntityTables.class), eq(DATATABLE_NAME),
|
||||
eq(APP_TABLE_ID), isNull(), eq(DATATABLE_ID));
|
||||
|
||||
when(genericDataService.fillResultsetRowData(anyString(), any())).thenReturn(rows);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void businessEventDeleteDatatableEntryTest() {
|
||||
private void verifyBusinessEvent(Long expectedEntityId) {
|
||||
ArgumentCaptor<BusinessEvent<?>> eventCaptor = ArgumentCaptor.forClass(BusinessEvent.class);
|
||||
verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(eventCaptor.capture());
|
||||
|
||||
underTest.deleteDatatableEntry(DATATABLE_NAME, 1L, 1L, createJsonCommand("{}", 1L));
|
||||
BusinessEvent<?> capturedEvent = eventCaptor.getValue();
|
||||
assertInstanceOf(DatatableEntryBusinessEvent.class, capturedEvent);
|
||||
DatatableEntryBusinessEvent event = (DatatableEntryBusinessEvent) capturedEvent;
|
||||
|
||||
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = verifyBusinessEvents(1);
|
||||
verifyDatatableBusinessEvent(businessEventArgumentCaptor, 0, 1L);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ArgumentCaptor<BusinessEvent<?>> verifyBusinessEvents(int expectedBusinessEvents) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = ArgumentCaptor.forClass(BusinessEvent.class);
|
||||
verify(businessEventNotifierService, times(expectedBusinessEvents)).notifyPostBusinessEvent(businessEventArgumentCaptor.capture());
|
||||
return businessEventArgumentCaptor;
|
||||
}
|
||||
|
||||
private void verifyDatatableBusinessEvent(ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor, int index, Long entityId) {
|
||||
assertTrue(businessEventArgumentCaptor.getAllValues().get(index) instanceof DatatableEntryBusinessEvent);
|
||||
assertEquals(DATATABLE_NAME, ((DatatableEntryBusinessEvent) businessEventArgumentCaptor.getAllValues().get(index))
|
||||
.getDatatableEntryDetails().getDatatableName());
|
||||
assertEquals(entityId, ((DatatableEntryBusinessEvent) businessEventArgumentCaptor.getAllValues().get(index)).getAggregateRootId());
|
||||
assertEquals(DATATABLE_NAME, event.getDatatableEntryDetails().getDatatableName());
|
||||
assertEquals(expectedEntityId, event.getAggregateRootId());
|
||||
}
|
||||
|
||||
private JsonCommand createJsonCommand(final String jsonCommand, final Long resourceId) {
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
@SpringBootTest
|
||||
@ContextConfiguration(classes = TestConfiguration.class)
|
||||
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
|
||||
public class ReadWriteNonCoreDataServiceImplTest {
|
||||
public class DatatableReadServiceImplTest {
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
@@ -69,7 +69,7 @@ public class ReadWriteNonCoreDataServiceImplTest {
|
||||
private DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
|
||||
@Autowired
|
||||
private ReadWriteNonCoreDataService underTest;
|
||||
private DatatableReadService underTest;
|
||||
|
||||
@Test
|
||||
public void testSqlInjectionCaughtQueryDataTable() {
|
||||
Reference in New Issue
Block a user