From 301dc718e8ffd66ddcb9fc153572ff1339e54d07 Mon Sep 17 00:00:00 2001 From: yhampe Date: Wed, 13 Nov 2024 09:44:51 +0100 Subject: [PATCH] RED-9472: seperation of system rules code review changes --- .../controller/RuleBuilderController.java | 9 +- .../model/drools/RuleCompilationResult.java | 46 +---- .../RuleManagementResources.java | 19 +- .../factory/RuleFileParser.java | 15 +- .../models/RuleFileBluePrint.java | 28 +++ .../v1/server/service/RuleBuilderService.java | 91 ++------- .../drools/RuleCompilationResultParser.java | 83 +------- .../redaction/v1/server/RuleBuilderTest.java | 183 ++++++++---------- 8 files changed, 147 insertions(+), 327 deletions(-) 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 8f3a51dd..aa215fc7 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 @@ -45,7 +45,7 @@ public class RuleBuilderController implements RuleBuilderResource { RulesResponse rulesResponse = new RulesResponse(); String filteredRules = this.ruleBuilderService.cleanRuleFileOfSystemRules(systemRulesSeperationRequest.getRules(), true); if (filteredRules.isEmpty()) { - throw new RuntimeException("There was an error when cleaning the rulefile of sytem rules"); + throw new AssertionError("There was an error when cleaning the rulefile of sytem rules"); } rulesResponse.setRules(filteredRules); return rulesResponse; @@ -53,13 +53,13 @@ public class RuleBuilderController implements RuleBuilderResource { @Override - public ResponseEntity mergeUserUpdateRules(RulesUpdateRequest rulesUpdateRequest) { + public ResponseEntity mergeUserUpdateRules(RulesUpdateRequest rulesUpdateRequest) { RulesUploadResponse rulesUploadResponse = new RulesUploadResponse(); DroolsValidationResponse droolsValidationResponse; RuleMergingResult mergingResult = ruleBuilderService.mergeUserRulesAndSystemRules(rulesUpdateRequest.getExistingRules(), rulesUpdateRequest.getUpdatedRules()); if (mergingResult.getMergedRules().isEmpty()) { - throw new RuntimeException("There was an error when merging the user rule update into the rule file"); + throw new AssertionError("There was an error when merging the user rule update into the rule file"); } try { var droolsValidation = droolsValidationService.testRules(new RuleValidationModel(RuleFileType.ENTITY.name(), mergingResult.getMergedRules())); @@ -90,7 +90,8 @@ public class RuleBuilderController implements RuleBuilderResource { .toList()) .build(); if (!droolsValidation.isCompiled()) { - return new ResponseEntity<>(droolsValidationResponse, HttpStatus.UNPROCESSABLE_ENTITY); + rulesUploadResponse.setDroolsValidationResponse(droolsValidationResponse); + return new ResponseEntity<>(rulesUploadResponse, HttpStatus.UNPROCESSABLE_ENTITY); } else { // rulesUploadResponse.setRules(mergingResult.getMergedRules()); diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleCompilationResult.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleCompilationResult.java index c7e35460..fe595301 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleCompilationResult.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/model/drools/RuleCompilationResult.java @@ -47,60 +47,16 @@ public final class RuleCompilationResult { public void dropRulesByIdentifier(RuleType ruleType) { - log.info("removing rule with identifier {}", ruleType.name()); - List rulesToBeRemoved = ruleClasses.stream() .filter(ruleClass -> Objects.equals(ruleClass.ruleType(), ruleType)) .toList(); - log.info("rules to be removed {}", rulesToBeRemoved); ruleClasses.removeAll(rulesToBeRemoved); } - public void dropAllRulesExceptSystemRules(List systemRules) { - - log.info("removing all rules except the system rules"); - - List rulesToBeRemoved = ruleClasses.stream() - .filter(ruleClass -> filterOutRule(ruleClass.ruleType(), systemRules)) - .toList(); - log.info("rules to be removed {}", rulesToBeRemoved); - ruleClasses.removeAll(rulesToBeRemoved); - } - - - public void dropImports() { - - this.imports = ""; - } - - - public void dropQueries() { - - this.queries.clear(); - } - - - public int countRuleOccurences(RuleType ruleType) { - - log.info("counting occurences of files {}", ruleType.name()); - - List rulesToBeRemoved = ruleClasses.stream() - .filter(ruleClass -> Objects.equals(ruleClass.ruleType(), ruleType)) - .toList(); - return rulesToBeRemoved.size(); - } - - - private boolean filterOutRule(RuleType ruleType, List filteredRules) { - - return !filteredRules.contains(ruleType.name()); - } - - public Set getImportSplitByKeyword() { - return Arrays.stream(imports.replace("\n", "").split("import")) + return Arrays.stream(imports.replaceAll("\n", "").split("import")) .map(String::trim) .collect(Collectors.toSet()); } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/RuleManagementResources.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/RuleManagementResources.java index 331b1e25..e423dde8 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/RuleManagementResources.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/RuleManagementResources.java @@ -1,34 +1,37 @@ package com.iqser.red.service.redaction.v1.server.rulesmanagement; +import java.io.IOException; import java.io.InputStream; +import org.drools.io.ClassPathResource; + import com.iqser.red.service.redaction.v1.server.rulesmanagement.models.ApplicationType; @SuppressWarnings("PMD") public class RuleManagementResources { - public static InputStream getAllRulesInputStream(ApplicationType applicationType) { + public static InputStream getAllRulesInputStream(ApplicationType applicationType) throws IOException { if (applicationType == ApplicationType.RM) { - return RuleManagementResources.class.getClassLoader().getResourceAsStream("drools/all_redact_manager_rules.drl"); + return new ClassPathResource("drools/all_redact_manager_rules.drl").getInputStream(); } - return RuleManagementResources.class.getClassLoader().getResourceAsStream("drools/all_rules_documine.drl"); + return new ClassPathResource("drools/all_rules_documine.drl").getInputStream(); } - public static InputStream getDefaultRuleIdentifiesInputStream(ApplicationType applicationType) { + public static InputStream getDefaultRuleIdentifiesInputStream(ApplicationType applicationType) throws IOException { if (applicationType == ApplicationType.RM) { - return RuleManagementResources.class.getClassLoader().getResourceAsStream("rulesmanagement/default_rule_identifiers.txt"); + return new ClassPathResource("rulesmanagement/default_rule_identifiers.txt").getInputStream(); } else { - return RuleManagementResources.class.getClassLoader().getResourceAsStream("rulesmanagement/default_rule_identifiers_dm.txt"); + return new ClassPathResource("rulesmanagement/default_rule_identifiers_dm.txt").getInputStream(); } } - public static InputStream getTemplateInputStream() { + public static InputStream getTemplateInputStream() throws IOException { - return RuleManagementResources.class.getClassLoader().getResourceAsStream("rulesmanagement/order_template.txt"); + return new ClassPathResource("rulesmanagement/order_template.txt").getInputStream(); } } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/factory/RuleFileParser.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/factory/RuleFileParser.java index db0ece77..6354f93c 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/factory/RuleFileParser.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/factory/RuleFileParser.java @@ -4,7 +4,6 @@ import static java.util.stream.Collectors.groupingBy; import java.io.File; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -121,16 +120,12 @@ public class RuleFileParser { Map> rulesPerUnit = rules.stream() .collect(groupingBy(rule -> rule.identifier().unit())); - if (rulesPerUnit.keySet() != null) { - return rulesPerUnit.keySet() - .stream() - .sorted() - .map(unit -> new RuleUnit(unit, rulesPerUnit.get(unit))) - .collect(Collectors.toList()); - } else { - return new ArrayList<>(); - } + return rulesPerUnit.keySet() + .stream() + .sorted() + .map(unit -> new RuleUnit(unit, rulesPerUnit.get(unit))) + .collect(Collectors.toList()); } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/models/RuleFileBluePrint.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/models/RuleFileBluePrint.java index 28b2663c..ca185b63 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/models/RuleFileBluePrint.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/rulesmanagement/models/RuleFileBluePrint.java @@ -1,5 +1,6 @@ package com.iqser.red.service.redaction.v1.server.rulesmanagement.models; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; @@ -53,6 +54,33 @@ public class RuleFileBluePrint { } + public boolean removeRuleClassByRuleIdentifier(RuleIdentifier ruleIdentifier) { + + AtomicBoolean wasRemoved = new AtomicBoolean(false); + + findRuleClassByType(ruleIdentifier.type()).ifPresent(ruleClass -> { + List unitsToRemove = new ArrayList<>(); + + ruleClass.ruleUnits() + .forEach(ruleUnit -> { + boolean removed = ruleUnit.rules().removeIf(rule -> rule.identifier().matches(ruleIdentifier)); + if (removed) { + wasRemoved.set(true); + if (ruleUnit.rules().isEmpty()) { + unitsToRemove.add(ruleUnit); + } + } + }); + + ruleClass.ruleUnits().removeAll(unitsToRemove); + if (ruleClass.ruleUnits().isEmpty()) { + this.ruleClasses.remove(ruleClass); + } + }); + return wasRemoved.get(); + } + + public Optional findRuleClassByType(RuleType ruleType) { return ruleClasses.stream() 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 index 32aaf4fc..d20e8337 100644 --- 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 @@ -3,9 +3,8 @@ package com.iqser.red.service.redaction.v1.server.service; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.stereotype.Service; @@ -16,8 +15,6 @@ import com.iqser.red.service.redaction.v1.server.rulesmanagement.factory.RuleFil import com.iqser.red.service.redaction.v1.server.rulesmanagement.factory.RuleFileParser; import com.iqser.red.service.redaction.v1.server.rulesmanagement.models.RuleFileBluePrint; import com.iqser.red.service.redaction.v1.server.rulesmanagement.models.RuleIdentifier; -import com.iqser.red.service.redaction.v1.server.rulesmanagement.models.RuleType; -import com.iqser.red.service.redaction.v1.server.rulesmanagement.models.RuleUnit; import lombok.extern.slf4j.Slf4j; @@ -25,13 +22,12 @@ import lombok.extern.slf4j.Slf4j; @Service public class RuleBuilderService { - //todo: make this configurable - private final List systemRules = new ArrayList<>(Arrays.asList(new RuleType("AI"), - new RuleType("MAN"), - new RuleType("X"), - new RuleType("DICT"), - new RuleType("FA"), - new RuleType("LDS"))); + private final List systemRules = new ArrayList<>(Arrays.asList(RuleIdentifier.fromName("AI.*.*"), + RuleIdentifier.fromName("MAN.*.*"), + RuleIdentifier.fromName("X.*.*"), + RuleIdentifier.fromName("DICT.*.*"), + RuleIdentifier.fromName("FA.*.*"), + RuleIdentifier.fromName("LDS.*.*"))); public RuleBuilderModel getRuleBuilderModel() { @@ -48,28 +44,24 @@ public class RuleBuilderService { public String cleanRuleFileOfSystemRules(String rulesString, boolean removeImports) { RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(rulesString); - log.info("Starting to remove system rules from ruleFile"); - removeSystemRulesAndCheckIfAnyRemain(ruleFileBluePrint); - log.info("Finished removing system rules for ruleFile"); - + removeSystemRules(ruleFileBluePrint); return RuleFileFactory.buildRuleString(ruleFileBluePrint, removeImports, true); } public RuleMergingResult mergeUserRulesAndSystemRules(String existingRules, String userUpdatedRules) { - log.info("starting to merge user rules update with system rules"); RuleFileBluePrint ruleFileBluePrintExisting = RuleFileParser.buildBluePrintFromRulesString(existingRules); RuleFileBluePrint mergedRuleFileBlueprint = RuleFileParser.buildBluePrintFromRulesString(userUpdatedRules, true); mergedRuleFileBlueprint.getRuleClasses() .forEach(ruleClass -> { if (systemRules.stream() - .map(RuleType::name) - .toList().contains(ruleClass.ruleType().name())) { - throw new RuntimeException("No system rule updates allowed in user rule update."); + .toList().contains(RuleIdentifier.fromName(ruleClass.ruleType().name()))) { + log.warn("System rule in user rule update."); + //throw new RuntimeException("No system rule updates allowed in user rule update."); } }); - removeAllRulesExceptSystemRulesAndCheck(ruleFileBluePrintExisting); + removeAllRulesExceptSystemRules(ruleFileBluePrintExisting); ruleFileBluePrintExisting.getRuleClasses() .stream() .flatMap(ruleClass -> ruleClass.ruleUnits() @@ -89,7 +81,6 @@ public class RuleBuilderService { mergedRuleFileBlueprint.getDeclarations() .stream()) .toList()); - log.info("finished merging user rules update with system rules"); RuleMergingResult mergingResult = RuleMergingResult.builder() .mergedRules(RuleFileFactory.buildRuleString(ruleFileBluePrintExisting, false, false)) .addedGlobalsOffset(ruleFileBluePrintExisting.getGlobals().length()) @@ -100,69 +91,17 @@ public class RuleBuilderService { } - private void removeAllRulesExceptSystemRulesAndCheck(RuleFileBluePrint ruleFileBluePrint) { - - Set systemRuleNames = systemRules.stream() - .map(RuleType::name) - .collect(Collectors.toSet()); - removeAllRulesExceptSystemRules(ruleFileBluePrint); - ruleFileBluePrint.getRuleClasses() - .forEach(ruleClass -> { - if (!systemRuleNames.contains(ruleClass.ruleType().name())) { - throw new RuntimeException("there was an error removing all rules except system rules"); - } - }); - } - - private void removeAllRulesExceptSystemRules(RuleFileBluePrint ruleFileBluePrint) { - List rules = new ArrayList(); - Set systemRuleNames = systemRules.stream() - .map(RuleType::name) - .collect(Collectors.toSet()); + ruleFileBluePrint.buildFilteredBluePrintByRuleIdentifiers(new HashSet(systemRules)); - ruleFileBluePrint.getRuleClasses() - .stream() - .filter(ruleClass -> !systemRuleNames.contains(ruleClass.ruleType().name())) - .flatMap(ruleClass -> ruleClass.ruleUnits() - .stream() - .map(ruleUnit -> new RuleIdentifier(ruleClass.ruleType(), ruleUnit.unit(), null))) - .forEach(rule -> rules.add(rule)); - rules.forEach(ruleIdentifier -> { - ruleFileBluePrint.removeRule(ruleIdentifier); - }); - } - - - private void removeSystemRulesAndCheckIfAnyRemain(RuleFileBluePrint ruleFileBluePrint) { - - removeSystemRules(ruleFileBluePrint); - for (RuleType systemRule : systemRules) { - List remainingSystemRules = new ArrayList(); - ruleFileBluePrint.findRuleClassByType(systemRule) - .ifPresent(ruleClass -> ruleClass.ruleUnits() - .stream() - .forEach(remainingSystemRules::add)); - if (!remainingSystemRules.isEmpty()) { - throw new RuntimeException("There was an error removing the system rules from the file"); - } - } } private void removeSystemRules(RuleFileBluePrint ruleFileBluePrintExisting) { - for (RuleType systemRule : systemRules) { - List rules = new ArrayList(); - ruleFileBluePrintExisting.findRuleClassByType(systemRule) - .ifPresent(ruleClass -> ruleClass.ruleUnits() - .stream() - .forEach(rules::add)); - rules.forEach(ruleUnit -> { - ruleFileBluePrintExisting.removeRule(new RuleIdentifier(systemRule, ruleUnit.unit(), null)); - }); - ruleFileBluePrintExisting.removeRule(RuleIdentifier.fromRuleType(systemRule)); + for (RuleIdentifier systemRule : systemRules) { + ruleFileBluePrintExisting.removeRuleClassByRuleIdentifier(systemRule); } } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java index 2a5158f3..1995b69e 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java @@ -35,33 +35,6 @@ public class RuleCompilationResultParser { "\\b(?:redact|apply|skip|remove|ignore|applyWithLineBreaks|applyWithReferences|skipWithReferences)\\s*\\(\\s*\"([a-zA-Z0-9]+.\\d+.\\d+)\"\\s*,\\s*.*(?:\\s*,\\s*.*)\\s*?\\)"); - public RuleCompilationResult buildBluePrintFromUserRulesString(String userRulesString) { - - DroolsValidation customDroolsValidation = DroolsValidation.builder().build(); - List allRules = new LinkedList<>(); - List allQueries = new LinkedList<>(); - PackageDescr packageDescr = new PackageDescr(); - String imports = ""; - String globals = ""; - List ruleClasses = buildRuleClasses(allRules); - return new RuleCompilationResult(imports.trim(), - packageDescr.getImports() - .stream() - .findFirst() - .map(ImportDescr::getLine) - .orElse(0), - globals.trim(), - packageDescr.getGlobals() - .stream() - .findFirst() - .map(GlobalDescr::getLine) - .orElse(0), - allQueries, - ruleClasses, - customDroolsValidation); - } - - @SneakyThrows public RuleCompilationResult buildRuleCompilationResultFromRuleString(String ruleString, boolean removedImports) { @@ -116,60 +89,7 @@ public class RuleCompilationResultParser { @SneakyThrows public RuleCompilationResult buildRuleCompilationResultFromRuleString(String ruleString) { - return buildRuleCompilationResultFromRuleString(ruleString,false); - } - - - @SneakyThrows - public String buildRulesStringFromBluePrint(RuleCompilationResult 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(); + return buildRuleCompilationResultFromRuleString(ruleString, false); } @@ -216,7 +136,6 @@ public class RuleCompilationResultParser { private List buildRuleClasses(List allRules) { - //todo: comments List ruleTypeOrder = allRules.stream() .map(BasicRule::getIdentifier) .map(RuleIdentifier::type) diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RuleBuilderTest.java b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RuleBuilderTest.java index 1996af83..181e108a 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RuleBuilderTest.java +++ b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RuleBuilderTest.java @@ -1,149 +1,128 @@ package com.iqser.red.service.redaction.v1.server; +import static com.iqser.red.service.redaction.v1.server.AbstractRedactionIntegrationTest.TEST_DOSSIER_TEMPLATE_ID; import static org.mockito.Mockito.when; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import org.junit.Assert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.FilterType; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import com.iqser.red.commons.jackson.ObjectMapperFactory; import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive; import com.iqser.red.service.redaction.v1.server.model.RuleMergingResult; +import com.iqser.red.service.redaction.v1.server.model.drools.RuleClass; import com.iqser.red.service.redaction.v1.server.model.drools.RuleCompilationResult; +import com.iqser.red.service.redaction.v1.server.rulesmanagement.factory.RuleFileFactory; import com.iqser.red.service.redaction.v1.server.rulesmanagement.factory.RuleFileParser; import com.iqser.red.service.redaction.v1.server.rulesmanagement.models.RuleFileBluePrint; +import com.iqser.red.service.redaction.v1.server.rulesmanagement.models.RuleIdentifier; +import com.iqser.red.service.redaction.v1.server.rulesmanagement.utils.RuleFileIO; import com.iqser.red.service.redaction.v1.server.service.RuleBuilderService; import com.iqser.red.service.redaction.v1.server.service.drools.RuleCompilationResultParser; -import com.iqser.red.storage.commons.StorageAutoConfiguration; -import com.iqser.red.storage.commons.service.StorageService; -import com.iqser.red.storage.commons.utils.FileSystemBackedStorageService; -import com.knecon.fforesight.service.layoutparser.processor.LayoutParsingServiceProcessorConfiguration; import com.knecon.fforesight.tenantcommons.TenantContext; -@ExtendWith(SpringExtension.class) -@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@Import(RuleBuilderTest.RuleBuilderTestConfiguration.class) -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class RuleBuilderTest extends AbstractRedactionIntegrationTest { +import org.junit.jupiter.api.Assertions; +import lombok.SneakyThrows; - private static final String RULES = loadFromClassPath("drools/rules_v2.drl"); - private static final String USER_RULES = loadFromClassPath("rulesmanagement/userrules/user_rule_update.drl"); - private final List systemRules = new ArrayList<>(Arrays.asList("AI", "MAN", "X", "DICT", "FA", "LDS")); - - @Autowired - RuleBuilderService ruleBuilderService; - - @Configuration - @EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}) - @Import(LayoutParsingServiceProcessorConfiguration.class) - @ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = StorageAutoConfiguration.class)}) - public static class RuleBuilderTestConfiguration { - - @Bean - @Primary - public StorageService inmemoryStorage() { - - return new FileSystemBackedStorageService(ObjectMapperFactory.create()); - } - - } +class RuleBuilderTest { + private RuleBuilderService ruleBuilderService; + private final List systemRules = new ArrayList<>(Arrays.asList( + RuleIdentifier.fromName("AI.*.*"), + RuleIdentifier.fromName("MAN.*.*"), + RuleIdentifier.fromName("X.*.*"), + RuleIdentifier.fromName("DICT.*.*"), + RuleIdentifier.fromName("FA.*.*"), + RuleIdentifier.fromName("LDS.*.*") + )); @BeforeEach - public void stubClients() { - + void setUp() { + ruleBuilderService = new RuleBuilderService(); TenantContext.setTenantId("redaction"); - - when(rulesClient.getVersion(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.ENTITY)).thenReturn(System.currentTimeMillis()); - when(rulesClient.getRules(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.ENTITY)).thenReturn(JSONPrimitive.of(RULES)); - when(rulesClient.getVersion(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.COMPONENT)).thenReturn(-1L); - - loadDictionaryForTest(); - loadTypeForTest(); - loadNerForTest(); - when(dictionaryClient.getVersion(TEST_DOSSIER_TEMPLATE_ID)).thenReturn(0L); - when(dictionaryClient.getAllTypesForDossierTemplate(TEST_DOSSIER_TEMPLATE_ID, null, true)).thenReturn(getTemplateDictionaryTypeResponse()); - - when(dictionaryClient.getVersion(TEST_DOSSIER_ID)).thenReturn(0L); - when(dictionaryClient.getAllTypesForDossier(TEST_DOSSIER_ID, null, true)).thenReturn(getDossierDictionaryTypeResponse()); - - mockDictionaryCalls(null); - - when(dictionaryClient.getColors(TEST_DOSSIER_TEMPLATE_ID)).thenReturn(colors); } - @Test - public void removeSystemRulesTest() { + @SneakyThrows + void removeSystemRulesTest() throws IOException { + URL url = getClass().getClassLoader().getResource("drools"); + if (url == null) { + throw new RuntimeException("Drools directory not found in resources"); + } - String cleanedRulesWithImports = this.ruleBuilderService.cleanRuleFileOfSystemRules(RULES, false); - String cleanedRulesWithoutImports = this.ruleBuilderService.cleanRuleFileOfSystemRules(RULES, true); - RuleCompilationResult ruleCompilationResultWithImports = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(cleanedRulesWithImports, false); - RuleCompilationResult ruleCompilationResultWithoutImports = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(cleanedRulesWithoutImports, true); + Path path = Paths.get(url.toURI()); + RuleFileIO.streamAllRuleFilesInDirectory(path) + .forEach(file -> testThatSystemRulesAreRemoved(file.toPath())); - Assert.assertFalse(checkIfImportsDontExist(ruleCompilationResultWithImports)); - Assert.assertTrue(checkIfSystemRulesDontExist(ruleCompilationResultWithImports)); - Assert.assertTrue(checkIfQueriesDontExist(ruleCompilationResultWithImports)); - - Assert.assertTrue(checkIfImportsDontExist(ruleCompilationResultWithoutImports)); - Assert.assertTrue(checkIfSystemRulesDontExist(ruleCompilationResultWithoutImports)); - Assert.assertTrue(checkIfQueriesDontExist(ruleCompilationResultWithoutImports)); + RuleFileIO.streamAllRuleFilesInDirectory(path) + .forEach(file -> testRuleFilesRemainSameAfterSeperationAndReaddingSystemrules(file.toPath())); } + private void testThatSystemRulesAreRemoved(Path path) { + String cleanedRulesWithImports = ruleBuilderService.cleanRuleFileOfSystemRules( + RuleFileIO.getRulesString(path.toFile().getAbsolutePath()), + false + ); + String cleanedRulesWithoutImports = ruleBuilderService.cleanRuleFileOfSystemRules( + RuleFileIO.getRulesString(path.toFile().getAbsolutePath()), + true + ); - @Test - public void mergeUserRulesUpdateTest() { + RuleCompilationResult ruleCompilationResultWithImports = + RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(cleanedRulesWithImports, false); + RuleCompilationResult ruleCompilationResultWithoutImports = + RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(cleanedRulesWithoutImports, true); - RuleMergingResult mergingResult = this.ruleBuilderService.mergeUserRulesAndSystemRules(RULES, USER_RULES); - String mergedRules = mergingResult.getMergedRules(); - RuleFileBluePrint ruleFileBluePrintUserRulesUpdate = RuleFileParser.buildBluePrintFromRulesString(mergedRules, true); - RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(mergedRules); - ruleFileBluePrintUserRulesUpdate.getRuleClasses() - .forEach(ruleClass -> { - Assert.assertTrue(ruleFileBluePrint.getRuleClasses().contains(ruleClass)); - }); + Assertions.assertFalse(checkIfImportsDontExist(ruleCompilationResultWithImports)); + Assertions.assertTrue(checkIfSystemRulesDontExist(ruleCompilationResultWithImports)); + Assertions.assertTrue(checkIfQueriesDontExist(ruleCompilationResultWithImports)); + Assertions.assertTrue(checkIfImportsDontExist(ruleCompilationResultWithoutImports)); + Assertions.assertTrue(checkIfSystemRulesDontExist(ruleCompilationResultWithoutImports)); + Assertions.assertTrue(checkIfQueriesDontExist(ruleCompilationResultWithoutImports)); } + private void testRuleFilesRemainSameAfterSeperationAndReaddingSystemrules(Path path) { + String cleanedRulesWithImports = ruleBuilderService.cleanRuleFileOfSystemRules( + RuleFileIO.getRulesString(path.toFile().getAbsolutePath()), + false + ); + + RuleMergingResult cleanedRuleFileMergedWithSystemRules = ruleBuilderService.mergeUserRulesAndSystemRules( + RuleFileIO.getRulesString(path.toFile().getAbsolutePath()), + cleanedRulesWithImports + ); + + RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString( + cleanedRuleFileMergedWithSystemRules.getMergedRules() + ); + + Assertions.assertEquals( + RuleFileFactory.buildRuleString(ruleFileBluePrint, false, false), + cleanedRuleFileMergedWithSystemRules.getMergedRules() + ); + } private boolean checkIfSystemRulesDontExist(RuleCompilationResult ruleCompilationResult) { - return ruleCompilationResult.getRuleClasses() - .stream() - .filter(ruleClass -> this.systemRules.contains(ruleClass.ruleType().name())) - .collect(Collectors.toList()).size() == 0; + .stream() + .map(RuleClass::ruleType) + .noneMatch(ruleType -> systemRules.stream() + .map(RuleIdentifier::type) + .anyMatch(type -> ruleType.name().equals(type.name()))); } - private boolean checkIfImportsDontExist(RuleCompilationResult ruleCompilationResult) { - return ruleCompilationResult.getImports().isEmpty(); } - private boolean checkIfQueriesDontExist(RuleCompilationResult ruleCompilationResult) { - return ruleCompilationResult.getQueries().isEmpty(); } - -} +} \ No newline at end of file