From 1ac0a184b7c3f69af06ab7b500590832458bbeb1 Mon Sep 17 00:00:00 2001 From: Kilian Schuettler Date: Tue, 22 Aug 2023 15:08:19 +0200 Subject: [PATCH 1/3] RED-7493: provide error messages in upload endpoint --- .../api/impl/controller/RulesController.java | 27 +++++++++++-------- .../pom.xml | 1 + .../api/external/resource/RulesResource.java | 6 ++--- .../persistence-service-processor-v1/pom.xml | 1 + .../DossierTemplateTesterAndProvider.java | 2 +- .../server/integration/tests/RulesTest.java | 2 +- .../rules/RuleSyntaxErrorMessage.java | 26 ++++++++++++++++++ .../{ => dossiertemplate/rules}/Rules.java | 2 +- 8 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/rules/RuleSyntaxErrorMessage.java rename persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/{ => dossiertemplate/rules}/Rules.java (95%) diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java index 4911f0fd3..d2b41e492 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java @@ -28,8 +28,11 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService; import com.iqser.red.service.persistence.service.v1.api.external.resource.RulesResource; import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Rules; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RuleSyntaxErrorMessage; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules; import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesSyntaxErrorMessages; +import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation; import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; import feign.FeignException; @@ -50,15 +53,15 @@ public class RulesController implements RulesResource { @Override @PreAuthorize("hasAuthority('" + WRITE_RULES + "')") - public void upload(@RequestBody Rules rules) { + public ResponseEntity upload(@RequestBody Rules rules) { - try { - redactionServiceClient.testRules(rules.getRules()); - } catch (FeignException e) { - if (e.status() == HttpStatus.BAD_REQUEST.value()) { - throw new InvalidRulesException("Rules could not be updated, validation check failed: " + e.getMessage()); - } - throw processFeignException(e); + DroolsSyntaxValidation droolsSyntaxValidation = redactionServiceClient.testRules(rules.getRules()); + if (!droolsSyntaxValidation.isCompiled()) { + var rulesSyntaxErrorMessages = droolsSyntaxValidation.getDroolsSyntaxErrorMessages() + .stream() + .map(errorMessage -> RuleSyntaxErrorMessage.builder().line(errorMessage.getLine()).column(errorMessage.getColumn()).message(errorMessage.getMessage()).build()) + .toList(); + return new ResponseEntity<>(rulesSyntaxErrorMessages, HttpStatus.BAD_REQUEST); } rulesPersistenceService.setRules(rules.getRules(), rules.getDossierTemplateId()); @@ -68,6 +71,8 @@ public class RulesController implements RulesResource { .category(AuditCategory.DOSSIER_TEMPLATE.name()) .message("Rules have been updated") .build()); + + return ResponseEntity.ok().build(); } @@ -82,10 +87,10 @@ public class RulesController implements RulesResource { @Override @PreAuthorize("hasAuthority('" + WRITE_RULES + "')") - public void uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestPart(name = "file") MultipartFile file) { + public ResponseEntity uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestPart(name = "file") MultipartFile file) { try { - upload(new Rules(new String(file.getBytes(), StandardCharsets.UTF_8), dossierTemplateId)); + return upload(new Rules(new String(file.getBytes(), StandardCharsets.UTF_8), dossierTemplateId)); } catch (IOException e) { throw new FileUploadException("Could not upload file.", e); } diff --git a/persistence-service-v1/persistence-service-external-api-v1/pom.xml b/persistence-service-v1/persistence-service-external-api-v1/pom.xml index a2605d023..756cef88f 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/pom.xml +++ b/persistence-service-v1/persistence-service-external-api-v1/pom.xml @@ -49,6 +49,7 @@ com.iqser.red.service redaction-service-api-v1 + 4.110.0 com.iqser.red.service diff --git a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java index 337ecb923..fe7976d63 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java +++ b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.multipart.MultipartFile; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Rules; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -37,7 +37,7 @@ public interface RulesResource { @PostMapping(value = RULES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.") @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")}) - void upload(@RequestBody Rules rules); + ResponseEntity upload(@RequestBody Rules rules); @ResponseBody @@ -57,7 +57,7 @@ public interface RulesResource { @PostMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + UPLOAD_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.") @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")}) - void uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestPart(name = "file") MultipartFile file); + ResponseEntity uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestPart(name = "file") MultipartFile file); @ResponseBody diff --git a/persistence-service-v1/persistence-service-processor-v1/pom.xml b/persistence-service-v1/persistence-service-processor-v1/pom.xml index c651c40b2..4e8a2153d 100644 --- a/persistence-service-v1/persistence-service-processor-v1/pom.xml +++ b/persistence-service-v1/persistence-service-processor-v1/pom.xml @@ -65,6 +65,7 @@ com.iqser.red.service redaction-service-api-v1 + 4.110.0 com.iqser.red.service diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/DossierTemplateTesterAndProvider.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/DossierTemplateTesterAndProvider.java index 8b88edd60..f79634790 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/DossierTemplateTesterAndProvider.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/DossierTemplateTesterAndProvider.java @@ -15,7 +15,7 @@ import com.iqser.red.service.peristence.v1.server.integration.client.DossierTemp import com.iqser.red.service.peristence.v1.server.integration.client.LegalBasisClient; import com.iqser.red.service.peristence.v1.server.integration.client.RulesClient; import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Rules; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.Colors; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.legalbasis.LegalBasis; diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/RulesTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/RulesTest.java index 7ca06a445..1a422e99f 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/RulesTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/RulesTest.java @@ -11,7 +11,7 @@ import com.iqser.red.service.peristence.v1.server.integration.client.RulesClient import com.iqser.red.service.peristence.v1.server.integration.client.VersionClient; import com.iqser.red.service.peristence.v1.server.integration.service.DossierTemplateTesterAndProvider; import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Rules; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules; public class RulesTest extends AbstractPersistenceServerServiceTest { diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/rules/RuleSyntaxErrorMessage.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/rules/RuleSyntaxErrorMessage.java new file mode 100644 index 000000000..0dc191941 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/rules/RuleSyntaxErrorMessage.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.models.security.SecurityScheme; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldDefaults; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@FieldDefaults(level = AccessLevel.PRIVATE) +@Schema(description = "Object containing a drools syntax error message, its line, and its column.") +public class RuleSyntaxErrorMessage { + + @Schema(description = "The Line where the error occurred.") + Integer line; + @Schema(description = "The Column where the error occurred.") + Integer column; + @Schema(description = "The error message.") + String message; +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/Rules.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/rules/Rules.java similarity index 95% rename from persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/Rules.java rename to persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/rules/Rules.java index 588d57581..1144f350c 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/Rules.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/rules/Rules.java @@ -1,4 +1,4 @@ -package com.iqser.red.service.persistence.service.v1.api.shared.model; +package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AccessLevel; -- 2.47.2 From b1b544faf65e1e30aad18fbf0de80e4417c90484 Mon Sep 17 00:00:00 2001 From: Kilian Schuettler Date: Tue, 22 Aug 2023 15:30:34 +0200 Subject: [PATCH 2/3] RED-7493: fix versions in parent pom --- .../v1/external/api/impl/controller/RulesController.java | 4 ---- .../persistence-service-external-api-v1/pom.xml | 1 - .../persistence-service-processor-v1/pom.xml | 1 - persistence-service-v1/pom.xml | 2 +- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java index d2b41e492..77f5d601f 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java @@ -2,7 +2,6 @@ package com.iqser.red.persistence.service.v1.external.api.impl.controller; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_RULES; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_RULES; -import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -23,7 +22,6 @@ import org.springframework.web.multipart.MultipartFile; import com.iqser.red.service.persistence.management.v1.processor.client.redactionservice.RedactionClient; import com.iqser.red.service.persistence.management.v1.processor.exception.FileUploadException; -import com.iqser.red.service.persistence.management.v1.processor.exception.InvalidRulesException; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService; import com.iqser.red.service.persistence.service.v1.api.external.resource.RulesResource; @@ -31,11 +29,9 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCatego import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RuleSyntaxErrorMessage; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules; import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest; -import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesSyntaxErrorMessages; import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation; import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; -import feign.FeignException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/persistence-service-v1/persistence-service-external-api-v1/pom.xml b/persistence-service-v1/persistence-service-external-api-v1/pom.xml index 756cef88f..a2605d023 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/pom.xml +++ b/persistence-service-v1/persistence-service-external-api-v1/pom.xml @@ -49,7 +49,6 @@ com.iqser.red.service redaction-service-api-v1 - 4.110.0 com.iqser.red.service diff --git a/persistence-service-v1/persistence-service-processor-v1/pom.xml b/persistence-service-v1/persistence-service-processor-v1/pom.xml index 4e8a2153d..c651c40b2 100644 --- a/persistence-service-v1/persistence-service-processor-v1/pom.xml +++ b/persistence-service-v1/persistence-service-processor-v1/pom.xml @@ -65,7 +65,6 @@ com.iqser.red.service redaction-service-api-v1 - 4.110.0 com.iqser.red.service diff --git a/persistence-service-v1/pom.xml b/persistence-service-v1/pom.xml index 8dd77134c..cc084e907 100755 --- a/persistence-service-v1/pom.xml +++ b/persistence-service-v1/pom.xml @@ -29,7 +29,7 @@ - 4.30.0 + 4.110.0 2.71.0 4.29.0 4.13.0 -- 2.47.2 From 8b1d26e4e5b820e778854e3c780afbe97e53d3b5 Mon Sep 17 00:00:00 2001 From: Kilian Schuettler Date: Tue, 22 Aug 2023 15:43:33 +0200 Subject: [PATCH 3/3] RED-7493: fix tests --- .../utils/AbstractPersistenceServerServiceTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java index cf95526f0..b63d0438d 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java @@ -3,9 +3,8 @@ package com.iqser.red.service.peristence.v1.server.integration.utils; import static org.mockito.Mockito.when; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -90,9 +89,9 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalseRecommendationEntryRepository; import com.iqser.red.service.persistence.management.v1.processor.service.redactionlog.RedactionLogMergeService; import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; -import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.ApplicationConfig; import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLog; +import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation; import com.iqser.red.storage.commons.service.StorageService; import com.knecon.fforesight.databasetenantcommons.providers.TenantCreatedListener; import com.knecon.fforesight.databasetenantcommons.providers.events.TenantCreatedEvent; @@ -106,7 +105,6 @@ import com.knecon.fforesight.tenantcommons.model.S3StorageConnection; import com.knecon.fforesight.tenantcommons.model.SearchConnection; import com.knecon.fforesight.tenantcommons.model.TenantResponse; -import io.lettuce.core.RedisClient; import io.micrometer.prometheus.PrometheusMeterRegistry; import lombok.extern.slf4j.Slf4j; @@ -242,6 +240,7 @@ public abstract class AbstractPersistenceServerServiceTest { } + @BeforeEach public void setupOptimize() { @@ -279,6 +278,7 @@ public abstract class AbstractPersistenceServerServiceTest { when(amqpAdmin.getQueueInfo(Mockito.any())).thenReturn(null); when(redactionLogMergeService.provideRedactionLog(Mockito.any())).thenReturn(new RedactionLog(1, 1, Lists.newArrayList(), null, 0, 0, 0, 0)); + when(redactionClient.testRules(Mockito.anyString())).thenReturn(DroolsSyntaxValidation.builder().compiled(true).droolsSyntaxErrorMessages(Collections.emptyList()).build()); } -- 2.47.2