RED-9472: seperation of system rules
code review changes
This commit is contained in:
parent
de7ea74ccf
commit
301dc718e8
@ -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<RulesUploadResponse> 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());
|
||||
|
||||
@ -47,60 +47,16 @@ public final class RuleCompilationResult {
|
||||
|
||||
public void dropRulesByIdentifier(RuleType ruleType) {
|
||||
|
||||
log.info("removing rule with identifier {}", ruleType.name());
|
||||
|
||||
List<RuleClass> 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<String> systemRules) {
|
||||
|
||||
log.info("removing all rules except the system rules");
|
||||
|
||||
List<RuleClass> 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<RuleClass> rulesToBeRemoved = ruleClasses.stream()
|
||||
.filter(ruleClass -> Objects.equals(ruleClass.ruleType(), ruleType))
|
||||
.toList();
|
||||
return rulesToBeRemoved.size();
|
||||
}
|
||||
|
||||
|
||||
private boolean filterOutRule(RuleType ruleType, List<String> filteredRules) {
|
||||
|
||||
return !filteredRules.contains(ruleType.name());
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getImportSplitByKeyword() {
|
||||
|
||||
return Arrays.stream(imports.replace("\n", "").split("import"))
|
||||
return Arrays.stream(imports.replaceAll("\n", "").split("import"))
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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<Integer, List<BasicRule>> 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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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<RuleUnit> 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<RuleClass> findRuleClassByType(RuleType ruleType) {
|
||||
|
||||
return ruleClasses.stream()
|
||||
|
||||
@ -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<RuleType> 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<RuleIdentifier> 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<String> 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<RuleIdentifier> rules = new ArrayList();
|
||||
Set<String> 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<RuleUnit> 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<RuleUnit> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<BasicRule> allRules = new LinkedList<>();
|
||||
List<BasicQuery> allQueries = new LinkedList<>();
|
||||
PackageDescr packageDescr = new PackageDescr();
|
||||
String imports = "";
|
||||
String globals = "";
|
||||
List<RuleClass> 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<RuleClass> buildRuleClasses(List<BasicRule> allRules) {
|
||||
|
||||
//todo: comments
|
||||
List<RuleType> ruleTypeOrder = allRules.stream()
|
||||
.map(BasicRule::getIdentifier)
|
||||
.map(RuleIdentifier::type)
|
||||
|
||||
@ -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<String> 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<RuleIdentifier> 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user