RED-9472: seperation of system rules

code review changes
This commit is contained in:
yhampe 2024-11-13 09:44:51 +01:00
parent de7ea74ccf
commit 301dc718e8
8 changed files with 147 additions and 327 deletions

View File

@ -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());

View File

@ -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());
}

View File

@ -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();
}
}

View File

@ -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());
}

View File

@ -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()

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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();
}
}
}