From fb8f227ac9a5f82899dc7c3ee2a7c7b46078ed86 Mon Sep 17 00:00:00 2001 From: yhampe Date: Thu, 12 Sep 2024 10:24:59 +0200 Subject: [PATCH] RED-9472: seperation of system rules added endpoints for seperating and readding system rules working on service --- .../redaction-service-api-v1/build.gradle.kts | 1 + .../v1/resources/RuleBuilderResource.java | 11 ++++ .../build.gradle.kts | 1 + .../controller/RuleBuilderController.java | 29 ++++++++-- .../v1/server/model/RulesResponse.java | 23 ++++++++ .../model/drools/RuleFileBluePrint.java | 14 +++++ .../v1/server/service/RuleBuilderService.java | 55 +++++++++++++++++++ .../server/service/drools/RuleFileParser.java | 53 ++++++++++++++++++ 8 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/RulesResponse.java create mode 100644 redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java diff --git a/redaction-service-v1/redaction-service-api-v1/build.gradle.kts b/redaction-service-v1/redaction-service-api-v1/build.gradle.kts index 1f228316..3bf38721 100644 --- a/redaction-service-v1/redaction-service-api-v1/build.gradle.kts +++ b/redaction-service-v1/redaction-service-api-v1/build.gradle.kts @@ -9,6 +9,7 @@ val persistenceServiceVersion = "2.545.0" dependencies { implementation("org.springframework:spring-web:6.0.12") implementation("com.iqser.red.service:persistence-service-internal-api-v1:${persistenceServiceVersion}") + api("com.knecon.fforesight:swagger-commons:0.7.0") } publishing { diff --git a/redaction-service-v1/redaction-service-api-v1/src/main/java/com/iqser/red/service/redaction/v1/resources/RuleBuilderResource.java b/redaction-service-v1/redaction-service-api-v1/src/main/java/com/iqser/red/service/redaction/v1/resources/RuleBuilderResource.java index 3864ba9b..5f0563f1 100644 --- a/redaction-service-v1/redaction-service-api-v1/src/main/java/com/iqser/red/service/redaction/v1/resources/RuleBuilderResource.java +++ b/redaction-service-v1/redaction-service-api-v1/src/main/java/com/iqser/red/service/redaction/v1/resources/RuleBuilderResource.java @@ -1,13 +1,24 @@ package com.iqser.red.service.redaction.v1.resources; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesResponse; import com.iqser.red.service.redaction.v1.model.RuleBuilderModel; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; + +import io.swagger.v3.oas.annotations.media.Schema; public interface RuleBuilderResource { @PostMapping(value = "/rule-builder-model", produces = MediaType.APPLICATION_JSON_VALUE) RuleBuilderModel getRuleBuilderModel(); + @PostMapping(value="/rulefile-system", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + RulesResponse getRuleFileWithoutSystemRules(@Schema(type = "string", format = "UTF_8", name = "file") @RequestPart(name = "ruleFile") String ruleFile); + + @PostMapping(value="/rulefile", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + RulesResponse getRuleFileWithSeperatedSystemRules(@Schema(type = "string", format = "UTF_8", name = "file") @RequestPart(name = "ruleFile") String ruleFile); + } diff --git a/redaction-service-v1/redaction-service-server-v1/build.gradle.kts b/redaction-service-v1/redaction-service-server-v1/build.gradle.kts index 87c4b538..a7061434 100644 --- a/redaction-service-v1/redaction-service-server-v1/build.gradle.kts +++ b/redaction-service-v1/redaction-service-server-v1/build.gradle.kts @@ -76,6 +76,7 @@ dependencies { implementation("net.logstash.logback:logstash-logback-encoder:7.4") api("ch.qos.logback:logback-classic") + api("com.knecon.fforesight:swagger-commons:0.7.0") implementation("org.reflections:reflections:0.10.2") diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java index 306dccbe..f690127f 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java @@ -1,27 +1,44 @@ package com.iqser.red.service.redaction.v1.server.controller; -import java.util.Collections; - import org.springframework.web.bind.annotation.RestController; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesResponse; import com.iqser.red.service.redaction.v1.model.RuleBuilderModel; import com.iqser.red.service.redaction.v1.resources.RuleBuilderResource; +import com.iqser.red.service.redaction.v1.server.service.RuleBuilderService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @RestController +@Slf4j @RequiredArgsConstructor public class RuleBuilderController implements RuleBuilderResource { + private final RuleBuilderService ruleBuilderService; + + @Override public RuleBuilderModel getRuleBuilderModel() { - RuleBuilderModel ruleBuilderModel = new RuleBuilderModel(); + return this.ruleBuilderService.getRuleBuilderModel(); + } - ruleBuilderModel.setWhenClauses(Collections.emptyList()); - ruleBuilderModel.setThenConditions(Collections.emptyList()); - return ruleBuilderModel; + @Override + public RulesResponse getRuleFileWithoutSystemRules(String rulesString) { + + RulesResponse rulesResponse = new RulesResponse(); + String filteredRules = this.ruleBuilderService.getRuleFileWithoutSystemRules(rulesString); + log.info("Filtered rules: {}", filteredRules); + return rulesResponse; + } + + + @Override + public RulesResponse getRuleFileWithSeperatedSystemRules(String rulesString) { + + return this.ruleBuilderService.getRuleFileWithSeperatedSystemRules(rulesString); } } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/RulesResponse.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/RulesResponse.java new file mode 100644 index 00000000..442e249e --- /dev/null +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/RulesResponse.java @@ -0,0 +1,23 @@ +package com.iqser.red.service.redaction.v1.server.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Schema(description = "Object containing a string of Drools rules.") +public class RulesResponse { + + @Schema(description = "The actual string of rules.") + private String rules; + + @Schema(description = "The DossierTemplate Id for these rules") + private String dossierTemplateId; + + @Schema(description = "Bad written rules can lead to timeouts or endless processing. This will be detected by the system and all analyse request for the rules will be rejected. This flag indicates that a timeout was detected and you need to fix the rules") + private boolean timeoutDetected; + +} diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleFileBluePrint.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleFileBluePrint.java index 338e58a7..98d6cf0a 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleFileBluePrint.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleFileBluePrint.java @@ -18,8 +18,10 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.FieldDefaults; +import lombok.extern.slf4j.Slf4j; @Data +@Slf4j @Builder @NoArgsConstructor @AllArgsConstructor @@ -43,6 +45,18 @@ public final class RuleFileBluePrint { } + public void dropRulesByIdentifier(RuleType ruleType) { + + log.info("removing rule with identifier {}", ruleType.name()); + + List rulesToBeRemoved = ruleClasses.stream() + .filter(ruleClass -> Objects.equals(ruleClass.ruleType(), ruleType)) + .collect(Collectors.toList()); + log.info("rules to be removed {}", rulesToBeRemoved); + ruleClasses.removeAll(rulesToBeRemoved); + } + + public Set getImportSplitByKeyword() { return Arrays.stream(imports.replaceAll("\n", "").split("import")) diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java new file mode 100644 index 00000000..c849802f --- /dev/null +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java @@ -0,0 +1,55 @@ +package com.iqser.red.service.redaction.v1.server.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesResponse; +import com.iqser.red.service.redaction.v1.model.RuleBuilderModel; +import com.iqser.red.service.redaction.v1.server.model.drools.RuleFileBluePrint; +import com.iqser.red.service.redaction.v1.server.model.drools.RuleType; +import com.iqser.red.service.redaction.v1.server.service.drools.RuleFileParser; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class RuleBuilderService { + + private final List systemRules = new ArrayList<>(Arrays.asList("AI", "MAN", "X", "DICT", "FA", "LDS")); + + + public RuleBuilderModel getRuleBuilderModel() { + + RuleBuilderModel ruleBuilderModel = new RuleBuilderModel(); + + ruleBuilderModel.setWhenClauses(Collections.emptyList()); + ruleBuilderModel.setThenConditions(Collections.emptyList()); + + return ruleBuilderModel; + } + + + public String getRuleFileWithoutSystemRules(String rulesString) { + + RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(rulesString); + log.info("Starting to remove system rules from ruleFile {}", ruleFileBluePrint); + for (String systemRule : systemRules) { + ruleFileBluePrint.dropRulesByIdentifier(RuleType.fromString(systemRule)); + } + log.info("Finished removing system rules for ruleFile {}", ruleFileBluePrint); + + return RuleFileParser.buildRulesStringFromBluePrint(ruleFileBluePrint); + } + + + public RulesResponse getRuleFileWithSeperatedSystemRules(String rulesString) { + + RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(rulesString); + return null; + } + +} diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleFileParser.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleFileParser.java index 375dc0f2..efd2976c 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleFileParser.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleFileParser.java @@ -83,6 +83,59 @@ public class RuleFileParser { } + @SneakyThrows + public String buildRulesStringFromBluePrint(RuleFileBluePrint bluePrint) { + + StringBuilder ruleStringBuilder = new StringBuilder(); + + // Append imports + ruleStringBuilder.append(bluePrint.getImports()).append("\n\n"); + + // Append globals + if (!bluePrint.getGlobals().isEmpty()) { + ruleStringBuilder.append(bluePrint.getGlobals()).append("\n\n"); + } + + // Append queries + for (BasicQuery query : bluePrint.getQueries()) { + ruleStringBuilder.append(buildQueryString(query)).append("\n\n"); + } + + // Append rules + for (RuleClass ruleClass : bluePrint.getRuleClasses()) { + ruleStringBuilder.append(buildRuleString(ruleClass)).append("\n\n"); + } + + // Return the final rule string + return ruleStringBuilder.toString().trim(); + } + + + private String buildQueryString(BasicQuery query) { + + return "query \"" + query.getName() + "\"\n" + query.getCode() + "\n" + "end"; + } + + + private String buildRuleString(RuleClass ruleClass) { + + StringBuilder ruleBuilder = new StringBuilder(); + + // Use RuleType to distinguish between different rule types, if needed + ruleBuilder.append("rule \"").append(ruleClass.ruleType().name()).append("\"\n"); + + for (RuleUnit ruleUnit : ruleClass.ruleUnits()) { + for (BasicRule rule : ruleUnit.rules()) { + // Assuming BasicRule has a method to retrieve the condition as a string + ruleBuilder.append(rule.getCode()).append("\n"); + } + } + ruleBuilder.append("end"); + + return ruleBuilder.toString(); + } + + private static void validateRule(String ruleString, RuleDescr rule, DroolsValidation customDroolsValidation, List allRules) { BasicRule basicRule;