RED-9472: seperation of system rules
refactored two have a rulefileblueprint and a rulefileblueprint for validationresult changed the flow of merging and seperating system and user rules added functions and declarations to rule file parsing
This commit is contained in:
parent
4978259fc6
commit
ae38506809
@ -1,6 +1,7 @@
|
|||||||
package com.iqser.red.service.redaction.v1.resources;
|
package com.iqser.red.service.redaction.v1.resources;
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
@ -20,6 +21,6 @@ public interface RuleBuilderResource {
|
|||||||
|
|
||||||
|
|
||||||
@PostMapping(value = "/internal-api/rules/system-rules", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
@PostMapping(value = "/internal-api/rules/system-rules", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
RulesResponse getRuleFileWithSeperatedSystemRules(@RequestBody RulesUpdateRequest rulesUpdateRequest);
|
ResponseEntity mergeUserUpdateRules(@RequestBody RulesUpdateRequest rulesUpdateRequest);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,20 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.controller;
|
package com.iqser.red.service.redaction.v1.server.controller;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.DroolsValidationResponse;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RuleBlacklistErrorMessage;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RuleSyntaxErrorMessage;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RuleSyntaxWarningMessage;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesResponse;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesResponse;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUpdateRequest;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUpdateRequest;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.SystemRulesSeperationRequest;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.SystemRulesSeperationRequest;
|
||||||
import com.iqser.red.service.redaction.v1.model.RuleBuilderModel;
|
import com.iqser.red.service.redaction.v1.model.RuleBuilderModel;
|
||||||
import com.iqser.red.service.redaction.v1.model.RuleValidationModel;
|
import com.iqser.red.service.redaction.v1.model.RuleValidationModel;
|
||||||
import com.iqser.red.service.redaction.v1.resources.RuleBuilderResource;
|
import com.iqser.red.service.redaction.v1.resources.RuleBuilderResource;
|
||||||
|
import com.iqser.red.service.redaction.v1.server.model.RuleMergingResult;
|
||||||
import com.iqser.red.service.redaction.v1.server.service.RuleBuilderService;
|
import com.iqser.red.service.redaction.v1.server.service.RuleBuilderService;
|
||||||
import com.iqser.red.service.redaction.v1.server.service.drools.DroolsValidationService;
|
import com.iqser.red.service.redaction.v1.server.service.drools.DroolsValidationService;
|
||||||
import com.iqser.red.service.redaction.v1.server.utils.exception.RulesValidationException;
|
import com.iqser.red.service.redaction.v1.server.utils.exception.RulesValidationException;
|
||||||
@ -36,28 +43,54 @@ public class RuleBuilderController implements RuleBuilderResource {
|
|||||||
|
|
||||||
RulesResponse rulesResponse = new RulesResponse();
|
RulesResponse rulesResponse = new RulesResponse();
|
||||||
String filteredRules = this.ruleBuilderService.cleanRuleFileOfSystemRules(systemRulesSeperationRequest.getRules(), true);
|
String filteredRules = this.ruleBuilderService.cleanRuleFileOfSystemRules(systemRulesSeperationRequest.getRules(), true);
|
||||||
try {
|
|
||||||
droolsValidationService.testRules(new RuleValidationModel(RuleFileType.ENTITY.name(), filteredRules));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RulesValidationException("Error trying to compile the cleaned rule file: " + filteredRules + " with message: {} " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
rulesResponse.setRules(filteredRules);
|
rulesResponse.setRules(filteredRules);
|
||||||
return rulesResponse;
|
return rulesResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RulesResponse getRuleFileWithSeperatedSystemRules(RulesUpdateRequest rulesUpdateRequest) {
|
public ResponseEntity mergeUserUpdateRules(RulesUpdateRequest rulesUpdateRequest) {
|
||||||
|
|
||||||
RulesResponse rulesResponse = new RulesResponse();
|
RulesResponse rulesResponse = new RulesResponse();
|
||||||
String mergedRules = ruleBuilderService.getRuleFileWithSeperatedSystemRules(rulesUpdateRequest.getExistingRules(), rulesUpdateRequest.getUpdatedRules());
|
DroolsValidationResponse droolsValidationResponse = new DroolsValidationResponse();
|
||||||
|
RuleMergingResult mergingResult = ruleBuilderService.mergeUserRulesAndSystemRules(rulesUpdateRequest.getExistingRules(), rulesUpdateRequest.getUpdatedRules());
|
||||||
try {
|
try {
|
||||||
droolsValidationService.testRules(new RuleValidationModel(RuleFileType.ENTITY.name(), mergedRules));
|
var droolsValidation = droolsValidationService.testRules(new RuleValidationModel(RuleFileType.ENTITY.name(), mergingResult.getMergedRules()));
|
||||||
} catch (Exception e) {
|
droolsValidationResponse = DroolsValidationResponse.builder()
|
||||||
throw new RulesValidationException("Error trying to compile the cleaned rule file: " + mergedRules + " with message: {} " + e.getMessage(), e);
|
.syntaxErrorMessages(droolsValidation.getSyntaxErrorMessages()
|
||||||
|
.stream()
|
||||||
|
.map(droolsSyntaxErrorMessage -> new RuleSyntaxErrorMessage(droolsSyntaxErrorMessage.getLine()
|
||||||
|
- (mergingResult.getAddedImportsOffset()
|
||||||
|
+ mergingResult.getAddedGlobalsOffset()),
|
||||||
|
droolsSyntaxErrorMessage.getColumn(),
|
||||||
|
droolsSyntaxErrorMessage.getMessage()))
|
||||||
|
.toList())
|
||||||
|
.deprecatedWarnings(droolsValidation.getDeprecatedWarnings()
|
||||||
|
.stream()
|
||||||
|
.map(droolsSyntaxDeprecatedWarnings -> new RuleSyntaxWarningMessage(droolsSyntaxDeprecatedWarnings.getLine()
|
||||||
|
- (mergingResult.getAddedImportsOffset()
|
||||||
|
+ mergingResult.getAddedGlobalsOffset()),
|
||||||
|
droolsSyntaxDeprecatedWarnings.getColumn(),
|
||||||
|
droolsSyntaxDeprecatedWarnings.getMessage()))
|
||||||
|
.toList())
|
||||||
|
.blacklistErrorMessages(droolsValidation.getBlacklistErrorMessages()
|
||||||
|
.stream()
|
||||||
|
.map(droolsBlacklistErrorMessage -> new RuleBlacklistErrorMessage(droolsBlacklistErrorMessage.getLine()
|
||||||
|
- (mergingResult.getAddedImportsOffset()
|
||||||
|
+ mergingResult.getAddedGlobalsOffset()),
|
||||||
|
droolsBlacklistErrorMessage.getColumn(),
|
||||||
|
droolsBlacklistErrorMessage.getMessage()))
|
||||||
|
.toList())
|
||||||
|
.build();
|
||||||
|
if (!droolsValidation.isCompiled()) {
|
||||||
|
return new ResponseEntity<>(droolsValidationResponse, HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
|
} else {
|
||||||
|
rulesResponse.setRules(mergingResult.getMergedRules());
|
||||||
}
|
}
|
||||||
rulesResponse.setRules(mergedRules);
|
} catch (Exception e) {
|
||||||
return rulesResponse;
|
throw new RulesValidationException("Could not test rules: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(rulesResponse, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.iqser.red.service.redaction.v1.server.model;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "Object containing a string of Drools rules.")
|
||||||
|
public class RuleMergingResult {
|
||||||
|
|
||||||
|
@Schema(description = "The merged rules.")
|
||||||
|
private String mergedRules;
|
||||||
|
|
||||||
|
@Schema(description = "the length of added imports from sytemRules")
|
||||||
|
private int addedImportsOffset;
|
||||||
|
@Schema(description = "the length of added globals from sytemRules")
|
||||||
|
private int addedGlobalsOffset;
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,23 +0,0 @@
|
|||||||
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;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -26,7 +26,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public final class RuleFileBluePrint {
|
public final class RuleCompilationResult {
|
||||||
|
|
||||||
String imports;
|
String imports;
|
||||||
int importLine;
|
int importLine;
|
||||||
@ -8,9 +8,11 @@ import java.util.List;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.iqser.red.service.redaction.v1.model.RuleBuilderModel;
|
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.RuleMergingResult;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleType;
|
import com.knecon.fforesight.utility.rules.management.factory.RuleFileFactory;
|
||||||
import com.iqser.red.service.redaction.v1.server.service.drools.RuleFileParser;
|
import com.knecon.fforesight.utility.rules.management.factory.RuleFileParser;
|
||||||
|
import com.knecon.fforesight.utility.rules.management.models.RuleFileBluePrint;
|
||||||
|
import com.knecon.fforesight.utility.rules.management.models.RuleIdentifier;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@ -37,34 +39,32 @@ public class RuleBuilderService {
|
|||||||
RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(rulesString);
|
RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(rulesString);
|
||||||
log.info("Starting to remove system rules from ruleFile");
|
log.info("Starting to remove system rules from ruleFile");
|
||||||
for (String systemRule : systemRules) {
|
for (String systemRule : systemRules) {
|
||||||
ruleFileBluePrint.dropRulesByIdentifier(RuleType.fromString(systemRule));
|
ruleFileBluePrint.removeRule(RuleIdentifier.fromName(systemRule));
|
||||||
}
|
|
||||||
ruleFileBluePrint.dropQueries();
|
|
||||||
if (removeImports) {
|
|
||||||
ruleFileBluePrint.dropImports();
|
|
||||||
}
|
}
|
||||||
log.info("Finished removing system rules for ruleFile");
|
log.info("Finished removing system rules for ruleFile");
|
||||||
|
|
||||||
return RuleFileParser.buildRulesStringFromBluePrint(ruleFileBluePrint);
|
// removing imports if flagged and dropping queries when building result string
|
||||||
|
return RuleFileFactory.buildRuleString(ruleFileBluePrint, removeImports, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getRuleFileWithSeperatedSystemRules(String existingRules, String updatedRules) {
|
public RuleMergingResult mergeUserRulesAndSystemRules(String existingRules, String updatedRules) {
|
||||||
|
//todo: when returning validation result to frotnend substract the length of imports/globals
|
||||||
|
log.info("starting to merge user rules update with system rules");
|
||||||
RuleFileBluePrint ruleFileBluePrintExisting = RuleFileParser.buildBluePrintFromRulesString(existingRules);
|
RuleFileBluePrint ruleFileBluePrintExisting = RuleFileParser.buildBluePrintFromRulesString(existingRules);
|
||||||
ruleFileBluePrintExisting.dropAllRulesExceptSystemRules(systemRules);
|
RuleFileBluePrint ruleFileBluePrintExistingMerged = RuleFileParser.buildBluePrintFromRulesString(updatedRules);
|
||||||
RuleFileBluePrint ruleFileBluePrintUpdate = RuleFileParser.buildBluePrintFromRulesString(updatedRules);
|
// add imports from systemrules
|
||||||
for (String systemRule : systemRules) {
|
ruleFileBluePrintExistingMerged.setImports(ruleFileBluePrintExisting.getImports() + ruleFileBluePrintExistingMerged.getImports());
|
||||||
if (ruleFileBluePrintUpdate.countRuleOccurences(RuleType.fromString(systemRule)) > 0) {
|
//add globals from systemrules
|
||||||
throw new RuntimeException("System rules are not allowed in an update.");
|
ruleFileBluePrintExistingMerged.setGlobals(ruleFileBluePrintExisting.getGlobals() + ruleFileBluePrintExistingMerged.getGlobals());
|
||||||
|
log.info("finished merging user rules update with system rules");
|
||||||
|
RuleMergingResult mergingResult = RuleMergingResult.builder()
|
||||||
|
.mergedRules(RuleFileFactory.buildRuleString(ruleFileBluePrintExisting, false, false))
|
||||||
|
.addedGlobalsOffset(ruleFileBluePrintExisting.getGlobals().length())
|
||||||
|
.addedImportsOffset(ruleFileBluePrintExisting.getImports().length())
|
||||||
|
.build();
|
||||||
|
|
||||||
}
|
return mergingResult;
|
||||||
}
|
|
||||||
ruleFileBluePrintExisting.setImports(ruleFileBluePrintUpdate.getImports());
|
|
||||||
ruleFileBluePrintUpdate.getRuleClasses()
|
|
||||||
.forEach(ruleFileBluePrintExisting::addRuleClass);
|
|
||||||
|
|
||||||
return RuleFileParser.buildRulesStringFromBluePrint(ruleFileBluePrintExisting);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import com.iqser.red.service.redaction.v1.server.model.dictionary.SearchImplemen
|
|||||||
import com.iqser.red.service.redaction.v1.server.model.drools.BasicQuery;
|
import com.iqser.red.service.redaction.v1.server.model.drools.BasicQuery;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.BasicRule;
|
import com.iqser.red.service.redaction.v1.server.model.drools.BasicRule;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleClass;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleClass;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleFileBluePrint;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleCompilationResult;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleUnit;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleUnit;
|
||||||
import com.iqser.red.service.redaction.v1.server.storage.RuleManagementResources;
|
import com.iqser.red.service.redaction.v1.server.storage.RuleManagementResources;
|
||||||
|
|
||||||
@ -69,70 +69,70 @@ public class DroolsValidationService {
|
|||||||
|
|
||||||
private DroolsValidation buildCustomDroolsValidation(String ruleString, RuleFileType ruleFileType) throws DroolsParserException {
|
private DroolsValidation buildCustomDroolsValidation(String ruleString, RuleFileType ruleFileType) throws DroolsParserException {
|
||||||
|
|
||||||
RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(ruleString);
|
RuleCompilationResult ruleCompilationResult = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(ruleString);
|
||||||
|
|
||||||
DroolsValidation customValidation = ruleFileBluePrint.getDroolsValidation();
|
DroolsValidation customValidation = ruleCompilationResult.getDroolsValidation();
|
||||||
|
|
||||||
addSyntaxDeprecatedWarnings(ruleFileType, ruleFileBluePrint, customValidation);
|
addSyntaxDeprecatedWarnings(ruleFileType, ruleCompilationResult, customValidation);
|
||||||
|
|
||||||
addSyntaxErrorMessages(ruleFileType, ruleFileBluePrint, customValidation);
|
addSyntaxErrorMessages(ruleFileType, ruleCompilationResult, customValidation);
|
||||||
|
|
||||||
if (redactionServiceSettings.isRuleExecutionSecured()) {
|
if (redactionServiceSettings.isRuleExecutionSecured()) {
|
||||||
addBlacklistErrorMessages(ruleFileBluePrint, customValidation);
|
addBlacklistErrorMessages(ruleCompilationResult, customValidation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return customValidation;
|
return customValidation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void addSyntaxDeprecatedWarnings(RuleFileType ruleFileType, RuleFileBluePrint ruleFileBluePrint, DroolsValidation customValidation) {
|
private void addSyntaxDeprecatedWarnings(RuleFileType ruleFileType, RuleCompilationResult ruleCompilationResult, DroolsValidation customValidation) {
|
||||||
|
|
||||||
// find deprecated elements in the ruleFileBluePrint
|
// find deprecated elements in the ruleFileBluePrint
|
||||||
DroolsSyntaxDeprecatedWarnings warningMessageForImports = getWarningsForDeprecatedImports(ruleFileBluePrint);
|
DroolsSyntaxDeprecatedWarnings warningMessageForImports = getWarningsForDeprecatedImports(ruleCompilationResult);
|
||||||
if (warningMessageForImports != null) {
|
if (warningMessageForImports != null) {
|
||||||
customValidation.getDeprecatedWarnings().add(warningMessageForImports);
|
customValidation.getDeprecatedWarnings().add(warningMessageForImports);
|
||||||
}
|
}
|
||||||
customValidation.getDeprecatedWarnings().addAll(getWarningsForDeprecatedRules(ruleFileBluePrint));
|
customValidation.getDeprecatedWarnings().addAll(getWarningsForDeprecatedRules(ruleCompilationResult));
|
||||||
|
|
||||||
if (ruleFileType.equals(RuleFileType.COMPONENT)) {
|
if (ruleFileType.equals(RuleFileType.COMPONENT)) {
|
||||||
if (!ruleFileBluePrint.getGlobals().contains(ComponentDroolsExecutionService.COMPONENT_MAPPING_SERVICE_GLOBAL)) {
|
if (!ruleCompilationResult.getGlobals().contains(ComponentDroolsExecutionService.COMPONENT_MAPPING_SERVICE_GLOBAL)) {
|
||||||
customValidation.getDeprecatedWarnings().add(buildComponentMappingServiceMissingMessage(ruleFileBluePrint));
|
customValidation.getDeprecatedWarnings().add(buildComponentMappingServiceMissingMessage(ruleCompilationResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static DroolsSyntaxDeprecatedWarnings buildComponentMappingServiceMissingMessage(RuleFileBluePrint ruleFileBluePrint) {
|
private static DroolsSyntaxDeprecatedWarnings buildComponentMappingServiceMissingMessage(RuleCompilationResult ruleCompilationResult) {
|
||||||
|
|
||||||
return DroolsSyntaxDeprecatedWarnings.builder()
|
return DroolsSyntaxDeprecatedWarnings.builder()
|
||||||
.message("global ComponentMappingService "
|
.message("global ComponentMappingService "
|
||||||
+ ComponentDroolsExecutionService.COMPONENT_MAPPING_SERVICE_GLOBAL
|
+ ComponentDroolsExecutionService.COMPONENT_MAPPING_SERVICE_GLOBAL
|
||||||
+ "\n is missing from the rules, consider adding it, as it will be required in future versions!")
|
+ "\n is missing from the rules, consider adding it, as it will be required in future versions!")
|
||||||
.line(ruleFileBluePrint.getGlobalsLine())
|
.line(ruleCompilationResult.getGlobalsLine())
|
||||||
.column(0)
|
.column(0)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private DroolsSyntaxDeprecatedWarnings getWarningsForDeprecatedImports(RuleFileBluePrint ruleFileBluePrint) {
|
private DroolsSyntaxDeprecatedWarnings getWarningsForDeprecatedImports(RuleCompilationResult ruleCompilationResult) {
|
||||||
|
|
||||||
if (!deprecatedElementsFinder.getDeprecatedClasses().isEmpty()) {
|
if (!deprecatedElementsFinder.getDeprecatedClasses().isEmpty()) {
|
||||||
String imports = ruleFileBluePrint.getImports();
|
String imports = ruleCompilationResult.getImports();
|
||||||
SearchImplementation classesSearchImplementation = deprecatedElementsFinder.getClassesSearchImplementation();
|
SearchImplementation classesSearchImplementation = deprecatedElementsFinder.getClassesSearchImplementation();
|
||||||
List<SearchImplementation.MatchPosition> matches = classesSearchImplementation.getMatches(imports);
|
List<SearchImplementation.MatchPosition> matches = classesSearchImplementation.getMatches(imports);
|
||||||
if (!matches.isEmpty()) {
|
if (!matches.isEmpty()) {
|
||||||
String sb = "Following imports are deprecated: \n" + matches.stream()
|
String sb = "Following imports are deprecated: \n" + matches.stream()
|
||||||
.map(m -> imports.substring(m.startIndex(), m.endIndex()))
|
.map(m -> imports.substring(m.startIndex(), m.endIndex()))
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
return DroolsSyntaxDeprecatedWarnings.builder().line(ruleFileBluePrint.getImportLine()).column(0).message(sb).build();
|
return DroolsSyntaxDeprecatedWarnings.builder().line(ruleCompilationResult.getImportLine()).column(0).message(sb).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<DroolsSyntaxDeprecatedWarnings> getWarningsForDeprecatedRules(RuleFileBluePrint ruleFileBluePrint) {
|
private List<DroolsSyntaxDeprecatedWarnings> getWarningsForDeprecatedRules(RuleCompilationResult ruleCompilationResult) {
|
||||||
|
|
||||||
List<DroolsSyntaxDeprecatedWarnings> warningMessages = new ArrayList<>();
|
List<DroolsSyntaxDeprecatedWarnings> warningMessages = new ArrayList<>();
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ public class DroolsValidationService {
|
|||||||
SearchImplementation methodsSearchImplementation = deprecatedElementsFinder.getMethodsSearchImplementation();
|
SearchImplementation methodsSearchImplementation = deprecatedElementsFinder.getMethodsSearchImplementation();
|
||||||
Map<String, String> deprecatedMethodsSignatureMap = deprecatedElementsFinder.getDeprecatedMethodsSignaturesMap();
|
Map<String, String> deprecatedMethodsSignatureMap = deprecatedElementsFinder.getDeprecatedMethodsSignaturesMap();
|
||||||
|
|
||||||
for (RuleClass ruleClass : ruleFileBluePrint.getRuleClasses()) {
|
for (RuleClass ruleClass : ruleCompilationResult.getRuleClasses()) {
|
||||||
for (RuleUnit ruleUnit : ruleClass.ruleUnits()) {
|
for (RuleUnit ruleUnit : ruleClass.ruleUnits()) {
|
||||||
for (BasicRule basicRule : ruleUnit.rules()) {
|
for (BasicRule basicRule : ruleUnit.rules()) {
|
||||||
List<SearchImplementation.MatchPosition> matches = methodsSearchImplementation.getMatches(basicRule.getCode());
|
List<SearchImplementation.MatchPosition> matches = methodsSearchImplementation.getMatches(basicRule.getCode());
|
||||||
@ -165,32 +165,32 @@ public class DroolsValidationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void addSyntaxErrorMessages(RuleFileType ruleFileType, RuleFileBluePrint ruleFileBluePrint, DroolsValidation customValidation) {
|
private void addSyntaxErrorMessages(RuleFileType ruleFileType, RuleCompilationResult ruleCompilationResult, DroolsValidation customValidation) {
|
||||||
|
|
||||||
RuleFileBluePrint baseRuleFileBluePrint = switch (ruleFileType) {
|
RuleCompilationResult baseRuleCompilationResult = switch (ruleFileType) {
|
||||||
case ENTITY -> RuleFileParser.buildBluePrintFromRulesString(RuleManagementResources.getBaseRuleFileString());
|
case ENTITY -> RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(RuleManagementResources.getBaseRuleFileString());
|
||||||
case COMPONENT -> RuleFileParser.buildBluePrintFromRulesString(RuleManagementResources.getBaseComponentRuleFileString());
|
case COMPONENT -> RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(RuleManagementResources.getBaseComponentRuleFileString());
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!importsAreValid(baseRuleFileBluePrint, ruleFileBluePrint)) {
|
if (!importsAreValid(baseRuleCompilationResult, ruleCompilationResult)) {
|
||||||
customValidation.getSyntaxErrorMessages()
|
customValidation.getSyntaxErrorMessages()
|
||||||
.add(DroolsSyntaxErrorMessage.builder()
|
.add(DroolsSyntaxErrorMessage.builder()
|
||||||
.line(ruleFileBluePrint.getImportLine())
|
.line(ruleCompilationResult.getImportLine())
|
||||||
.column(0)
|
.column(0)
|
||||||
.message(String.format("Changing the imports is not allowed! Must be: %n%s", baseRuleFileBluePrint.getImports()))
|
.message(String.format("Changing the imports is not allowed! Must be: %n%s", baseRuleCompilationResult.getImports()))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
if (!ruleFileBluePrint.getGlobals().contains(baseRuleFileBluePrint.getGlobals())) {
|
if (!ruleCompilationResult.getGlobals().contains(baseRuleCompilationResult.getGlobals())) {
|
||||||
customValidation.getSyntaxErrorMessages()
|
customValidation.getSyntaxErrorMessages()
|
||||||
.add(DroolsSyntaxErrorMessage.builder()
|
.add(DroolsSyntaxErrorMessage.builder()
|
||||||
.line(ruleFileBluePrint.getGlobalsLine())
|
.line(ruleCompilationResult.getGlobalsLine())
|
||||||
.column(0)
|
.column(0)
|
||||||
.message(String.format("Removing the globals is not allowed! Must be: %n%s", baseRuleFileBluePrint.getGlobals()))
|
.message(String.format("Removing the globals is not allowed! Must be: %n%s", baseRuleCompilationResult.getGlobals()))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
baseRuleFileBluePrint.getQueries()
|
baseRuleCompilationResult.getQueries()
|
||||||
.forEach(basicQuery -> {
|
.forEach(basicQuery -> {
|
||||||
if (!validateQueryIsPresent(basicQuery, ruleFileBluePrint)) {
|
if (!validateQueryIsPresent(basicQuery, ruleCompilationResult)) {
|
||||||
customValidation.getSyntaxErrorMessages()
|
customValidation.getSyntaxErrorMessages()
|
||||||
.add(DroolsSyntaxErrorMessage.builder()
|
.add(DroolsSyntaxErrorMessage.builder()
|
||||||
.line(basicQuery.getLine())
|
.line(basicQuery.getLine())
|
||||||
@ -201,7 +201,7 @@ public class DroolsValidationService {
|
|||||||
});
|
});
|
||||||
if (ruleFileType.equals(RuleFileType.ENTITY)) {
|
if (ruleFileType.equals(RuleFileType.ENTITY)) {
|
||||||
String requiredAgendaGroup = "LOCAL_DICTIONARY_ADDS";
|
String requiredAgendaGroup = "LOCAL_DICTIONARY_ADDS";
|
||||||
if (!validateAgendaGroupIsPresent(ruleFileBluePrint, requiredAgendaGroup)) {
|
if (!validateAgendaGroupIsPresent(ruleCompilationResult, requiredAgendaGroup)) {
|
||||||
customValidation.getSyntaxErrorMessages()
|
customValidation.getSyntaxErrorMessages()
|
||||||
.add(DroolsSyntaxErrorMessage.builder()
|
.add(DroolsSyntaxErrorMessage.builder()
|
||||||
.line(0)
|
.line(0)
|
||||||
@ -213,18 +213,18 @@ public class DroolsValidationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean validateAgendaGroupIsPresent(RuleFileBluePrint ruleFileBluePrint, String agendaGroupName) {
|
private boolean validateAgendaGroupIsPresent(RuleCompilationResult ruleCompilationResult, String agendaGroupName) {
|
||||||
|
|
||||||
return ruleFileBluePrint.streamAllRules()
|
return ruleCompilationResult.streamAllRules()
|
||||||
.anyMatch(basicRule -> basicRule.getAgendaGroup().equals(agendaGroupName));
|
.anyMatch(basicRule -> basicRule.getAgendaGroup().equals(agendaGroupName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean importsAreValid(RuleFileBluePrint baseRuleFileBluePrint, RuleFileBluePrint ruleFileBluePrint) {
|
private boolean importsAreValid(RuleCompilationResult baseRuleCompilationResult, RuleCompilationResult ruleCompilationResult) {
|
||||||
|
|
||||||
// imports may shrink, but not add anything new!
|
// imports may shrink, but not add anything new!
|
||||||
Set<String> baseImports = baseRuleFileBluePrint.getImportSplitByKeyword();
|
Set<String> baseImports = baseRuleCompilationResult.getImportSplitByKeyword();
|
||||||
Set<String> imports = ruleFileBluePrint.getImportSplitByKeyword();
|
Set<String> imports = ruleCompilationResult.getImportSplitByKeyword();
|
||||||
|
|
||||||
Set<String> additionalImports = Sets.difference(imports, baseImports);
|
Set<String> additionalImports = Sets.difference(imports, baseImports);
|
||||||
|
|
||||||
@ -233,15 +233,15 @@ public class DroolsValidationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean validateQueryIsPresent(BasicQuery queryToCheckFor, RuleFileBluePrint ruleFileBluePrint) {
|
private static boolean validateQueryIsPresent(BasicQuery queryToCheckFor, RuleCompilationResult ruleCompilationResult) {
|
||||||
|
|
||||||
return ruleFileBluePrint.getQueries()
|
return ruleCompilationResult.getQueries()
|
||||||
.stream()
|
.stream()
|
||||||
.anyMatch(query -> query.getName().equals(queryToCheckFor.getName()) && query.getCode().equals(queryToCheckFor.getCode()));
|
.anyMatch(query -> query.getName().equals(queryToCheckFor.getName()) && query.getCode().equals(queryToCheckFor.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void addBlacklistErrorMessages(RuleFileBluePrint ruleFileBluePrint, DroolsValidation customValidation) {
|
private void addBlacklistErrorMessages(RuleCompilationResult ruleCompilationResult, DroolsValidation customValidation) {
|
||||||
|
|
||||||
List<DroolsBlacklistErrorMessage> blacklistErrorMessages = new ArrayList<>();
|
List<DroolsBlacklistErrorMessage> blacklistErrorMessages = new ArrayList<>();
|
||||||
|
|
||||||
@ -253,14 +253,14 @@ public class DroolsValidationService {
|
|||||||
|
|
||||||
// check also the imports
|
// check also the imports
|
||||||
DroolsBlacklistErrorMessage blacklistErrorMessage = checkAndGetBlackListedMessages(blacklistedKeywordSearchImplementation,
|
DroolsBlacklistErrorMessage blacklistErrorMessage = checkAndGetBlackListedMessages(blacklistedKeywordSearchImplementation,
|
||||||
ruleFileBluePrint.getImports(),
|
ruleCompilationResult.getImports(),
|
||||||
ruleFileBluePrint.getImportLine());
|
ruleCompilationResult.getImportLine());
|
||||||
if (blacklistErrorMessage != null) {
|
if (blacklistErrorMessage != null) {
|
||||||
blacklistErrorMessages.add(blacklistErrorMessage);
|
blacklistErrorMessages.add(blacklistErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the rules
|
// check the rules
|
||||||
for (RuleClass ruleClass : ruleFileBluePrint.getRuleClasses()) {
|
for (RuleClass ruleClass : ruleCompilationResult.getRuleClasses()) {
|
||||||
for (RuleUnit ruleUnit : ruleClass.ruleUnits()) {
|
for (RuleUnit ruleUnit : ruleClass.ruleUnits()) {
|
||||||
for (BasicRule basicRule : ruleUnit.rules()) {
|
for (BasicRule basicRule : ruleUnit.rules()) {
|
||||||
DroolsBlacklistErrorMessage ruleBlacklistErrorMessage = checkAndGetBlackListedMessages(blacklistedKeywordSearchImplementation,
|
DroolsBlacklistErrorMessage ruleBlacklistErrorMessage = checkAndGetBlackListedMessages(blacklistedKeywordSearchImplementation,
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import com.iqser.red.service.redaction.v1.model.DroolsValidation;
|
|||||||
import com.iqser.red.service.redaction.v1.server.model.drools.BasicQuery;
|
import com.iqser.red.service.redaction.v1.server.model.drools.BasicQuery;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.BasicRule;
|
import com.iqser.red.service.redaction.v1.server.model.drools.BasicRule;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleClass;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleClass;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleFileBluePrint;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleCompilationResult;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleIdentifier;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleIdentifier;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleType;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleType;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleUnit;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleUnit;
|
||||||
@ -29,14 +29,38 @@ import lombok.SneakyThrows;
|
|||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class RuleFileParser {
|
public class RuleCompilationResultParser {
|
||||||
|
|
||||||
private final static Pattern ruleIdentifierInCodeFinder = Pattern.compile(
|
private final static Pattern ruleIdentifierInCodeFinder = Pattern.compile(
|
||||||
"\\b(?:redact|apply|skip|remove|ignore|applyWithLineBreaks|applyWithReferences|skipWithReferences)\\s*\\(\\s*\"([a-zA-Z0-9]+.\\d+.\\d+)\"\\s*,\\s*.*(?:\\s*,\\s*.*)\\s*?\\)");
|
"\\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
|
@SneakyThrows
|
||||||
public RuleFileBluePrint buildBluePrintFromRulesString(String ruleString) {
|
public RuleCompilationResult buildRuleCompilationResultFromRuleString(String ruleString) {
|
||||||
|
|
||||||
DroolsValidation customDroolsValidation = DroolsValidation.builder().build();
|
DroolsValidation customDroolsValidation = DroolsValidation.builder().build();
|
||||||
DrlParser parser = new DrlParser(LanguageLevelOption.DRL6);
|
DrlParser parser = new DrlParser(LanguageLevelOption.DRL6);
|
||||||
@ -65,7 +89,7 @@ public class RuleFileParser {
|
|||||||
|
|
||||||
List<RuleClass> ruleClasses = buildRuleClasses(allRules);
|
List<RuleClass> ruleClasses = buildRuleClasses(allRules);
|
||||||
|
|
||||||
return new RuleFileBluePrint(imports.trim(),
|
return new RuleCompilationResult(imports.trim(),
|
||||||
packageDescr.getImports()
|
packageDescr.getImports()
|
||||||
.stream()
|
.stream()
|
||||||
.findFirst()
|
.findFirst()
|
||||||
@ -84,7 +108,7 @@ public class RuleFileParser {
|
|||||||
|
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public String buildRulesStringFromBluePrint(RuleFileBluePrint bluePrint) {
|
public String buildRulesStringFromBluePrint(RuleCompilationResult bluePrint) {
|
||||||
|
|
||||||
StringBuilder ruleStringBuilder = new StringBuilder();
|
StringBuilder ruleStringBuilder = new StringBuilder();
|
||||||
|
|
||||||
@ -179,6 +203,7 @@ public class RuleFileParser {
|
|||||||
|
|
||||||
private List<RuleClass> buildRuleClasses(List<BasicRule> allRules) {
|
private List<RuleClass> buildRuleClasses(List<BasicRule> allRules) {
|
||||||
|
|
||||||
|
//todo: comments
|
||||||
List<RuleType> ruleTypeOrder = allRules.stream()
|
List<RuleType> ruleTypeOrder = allRules.stream()
|
||||||
.map(BasicRule::getIdentifier)
|
.map(BasicRule::getIdentifier)
|
||||||
.map(RuleIdentifier::type)
|
.map(RuleIdentifier::type)
|
||||||
@ -22,11 +22,11 @@ import com.iqser.red.service.redaction.v1.model.RuleValidationModel;
|
|||||||
import com.iqser.red.service.redaction.v1.server.DeprecatedElementsFinder;
|
import com.iqser.red.service.redaction.v1.server.DeprecatedElementsFinder;
|
||||||
import com.iqser.red.service.redaction.v1.server.RedactionServiceSettings;
|
import com.iqser.red.service.redaction.v1.server.RedactionServiceSettings;
|
||||||
import com.iqser.red.service.redaction.v1.server.client.RulesClient;
|
import com.iqser.red.service.redaction.v1.server.client.RulesClient;
|
||||||
import com.iqser.red.service.redaction.v1.server.model.drools.RuleFileBluePrint;
|
import com.iqser.red.service.redaction.v1.server.model.drools.RuleCompilationResult;
|
||||||
import com.iqser.red.service.redaction.v1.server.service.document.EntityEnrichmentService;
|
import com.iqser.red.service.redaction.v1.server.service.document.EntityEnrichmentService;
|
||||||
import com.iqser.red.service.redaction.v1.server.service.drools.DroolsValidationService;
|
import com.iqser.red.service.redaction.v1.server.service.drools.DroolsValidationService;
|
||||||
import com.iqser.red.service.redaction.v1.server.service.drools.KieContainerCreationService;
|
import com.iqser.red.service.redaction.v1.server.service.drools.KieContainerCreationService;
|
||||||
import com.iqser.red.service.redaction.v1.server.service.drools.RuleFileParser;
|
import com.iqser.red.service.redaction.v1.server.service.drools.RuleCompilationResultParser;
|
||||||
import com.iqser.red.service.redaction.v1.server.storage.RuleManagementResources;
|
import com.iqser.red.service.redaction.v1.server.storage.RuleManagementResources;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
@ -235,11 +235,11 @@ class DroolsValidationServiceTest {
|
|||||||
if (droolsValidation.isCompiled()) {
|
if (droolsValidation.isCompiled()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(rulesString);
|
RuleCompilationResult ruleCompilationResult = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(rulesString);
|
||||||
RuleFileBluePrint baseRuleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(RuleManagementResources.getBaseRuleFileString());
|
RuleCompilationResult baseRuleCompilationResult = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(RuleManagementResources.getBaseRuleFileString());
|
||||||
|
|
||||||
rulesString = rulesString.replace(ruleFileBluePrint.getImports(), baseRuleFileBluePrint.getImports());
|
rulesString = rulesString.replace(ruleCompilationResult.getImports(), baseRuleCompilationResult.getImports());
|
||||||
rulesString = rulesString.replace(ruleFileBluePrint.getGlobals(), baseRuleFileBluePrint.getGlobals());
|
rulesString = rulesString.replace(ruleCompilationResult.getGlobals(), baseRuleCompilationResult.getGlobals());
|
||||||
|
|
||||||
try (OutputStream outStream = new FileOutputStream(rulesFile.getFile().getAbsolutePath().replace("/test", "").replace("build", "src/test"))) {
|
try (OutputStream outStream = new FileOutputStream(rulesFile.getFile().getAbsolutePath().replace("/test", "").replace("build", "src/test"))) {
|
||||||
outStream.write(rulesString.getBytes(StandardCharsets.UTF_8));
|
outStream.write(rulesString.getBytes(StandardCharsets.UTF_8));
|
||||||
@ -460,9 +460,9 @@ class DroolsValidationServiceTest {
|
|||||||
end
|
end
|
||||||
""";
|
""";
|
||||||
|
|
||||||
RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(ruleString);
|
RuleCompilationResult ruleCompilationResult = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(ruleString);
|
||||||
|
|
||||||
assertFalse(ruleFileBluePrint.getDroolsValidation().isCompiled());
|
assertFalse(ruleCompilationResult.getDroolsValidation().isCompiled());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -48,17 +48,17 @@ public class RuleFileFactory {
|
|||||||
}
|
}
|
||||||
RuleFileBluePrint bluePrint = RuleFileParser.buildBluePrintFromAllRulesFile(applicationType);
|
RuleFileBluePrint bluePrint = RuleFileParser.buildBluePrintFromAllRulesFile(applicationType);
|
||||||
RuleFileBluePrint filteredBluePrint = bluePrint.buildFilteredBluePrintByRuleIdentifiers(identifiers);
|
RuleFileBluePrint filteredBluePrint = bluePrint.buildFilteredBluePrintByRuleIdentifiers(identifiers);
|
||||||
return buildRuleString(filteredBluePrint);
|
return buildRuleString(filteredBluePrint, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public String buildRuleString(RuleFileBluePrint bluePrint) {
|
public String buildRuleString(RuleFileBluePrint bluePrint, boolean dropImports, boolean dropQueries) {
|
||||||
|
|
||||||
try (var templateInputStream = RuleManagementResources.getTemplateInputStream()) {
|
try (var templateInputStream = RuleManagementResources.getTemplateInputStream()) {
|
||||||
String template = new String(templateInputStream.readAllBytes(), StandardCharsets.UTF_8);
|
String template = new String(templateInputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
List<RuleType> templateRuleOrder = parseRuleOrder(template);
|
List<RuleType> templateRuleOrder = parseRuleOrder(template);
|
||||||
return buildBluePrintWithTemplateRuleOrder(bluePrint, templateRuleOrder);
|
return buildBluePrintWithTemplateRuleOrder(bluePrint, templateRuleOrder, dropImports, dropQueries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,23 +72,31 @@ public class RuleFileFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String buildBluePrintWithTemplateRuleOrder(RuleFileBluePrint bluePrint, List<RuleType> ruleOrder) {
|
private String buildBluePrintWithTemplateRuleOrder(RuleFileBluePrint bluePrint, List<RuleType> ruleOrder, boolean dropImports, boolean dropQueries) {
|
||||||
|
|
||||||
Set<RuleType> additionalRuleTypes = bluePrint.ruleClasses()
|
Set<RuleType> additionalRuleTypes = bluePrint.getRuleClasses()
|
||||||
.stream()
|
.stream()
|
||||||
.map(RuleClass::ruleType)
|
.map(RuleClass::ruleType)
|
||||||
.filter(ruleType -> !ruleOrder.contains(ruleType))
|
.filter(ruleType -> !ruleOrder.contains(ruleType))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(bluePrint.imports());
|
if (!dropImports) {
|
||||||
|
sb.append(bluePrint.getImports());
|
||||||
sb.append("\n\n");
|
sb.append("\n\n");
|
||||||
sb.append(bluePrint.globals());
|
}
|
||||||
|
sb.append(bluePrint.getGlobals());
|
||||||
sb.append("\n\n");
|
sb.append("\n\n");
|
||||||
|
sb.append("//------------------------------------ declarations ------------------------------------");
|
||||||
|
sb.append("\n\n");
|
||||||
|
sb.append(bluePrint.getDeclarations());
|
||||||
|
sb.append("\n\n");
|
||||||
|
if (!dropQueries) {
|
||||||
sb.append("//------------------------------------ queries ------------------------------------");
|
sb.append("//------------------------------------ queries ------------------------------------");
|
||||||
sb.append("\n\n");
|
sb.append("\n\n");
|
||||||
sb.append(bluePrint.queries());
|
sb.append(bluePrint.getQueries());
|
||||||
sb.append("\n\n");
|
sb.append("\n\n");
|
||||||
|
}
|
||||||
for (RuleType ruleBlockType : ruleOrder) {
|
for (RuleType ruleBlockType : ruleOrder) {
|
||||||
if (ruleBlockType.isWildCard()) {
|
if (ruleBlockType.isWildCard()) {
|
||||||
additionalRuleTypes.stream()
|
additionalRuleTypes.stream()
|
||||||
@ -101,6 +109,9 @@ public class RuleFileFactory {
|
|||||||
}
|
}
|
||||||
writeRuleClass(bluePrint, ruleBlockType, sb);
|
writeRuleClass(bluePrint, ruleBlockType, sb);
|
||||||
}
|
}
|
||||||
|
sb.append("//------------------------------------ functions ------------------------------------");
|
||||||
|
sb.append("\n\n");
|
||||||
|
sb.append(bluePrint.getFunctions());
|
||||||
return sb.toString().trim() + "\n";
|
return sb.toString().trim() + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.drools.drl.ast.descr.AbstractClassTypeDeclarationDescr;
|
||||||
|
import org.drools.drl.ast.descr.FunctionDescr;
|
||||||
import org.drools.drl.ast.descr.ImportDescr;
|
import org.drools.drl.ast.descr.ImportDescr;
|
||||||
import org.drools.drl.ast.descr.PackageDescr;
|
import org.drools.drl.ast.descr.PackageDescr;
|
||||||
import org.drools.drl.ast.descr.RuleDescr;
|
import org.drools.drl.ast.descr.RuleDescr;
|
||||||
@ -18,6 +20,8 @@ import org.kie.internal.builder.conf.LanguageLevelOption;
|
|||||||
|
|
||||||
import com.knecon.fforesight.utility.rules.management.RuleManagementResources;
|
import com.knecon.fforesight.utility.rules.management.RuleManagementResources;
|
||||||
import com.knecon.fforesight.utility.rules.management.models.ApplicationType;
|
import com.knecon.fforesight.utility.rules.management.models.ApplicationType;
|
||||||
|
import com.knecon.fforesight.utility.rules.management.models.BasicDeclaration;
|
||||||
|
import com.knecon.fforesight.utility.rules.management.models.BasicFunction;
|
||||||
import com.knecon.fforesight.utility.rules.management.models.BasicRule;
|
import com.knecon.fforesight.utility.rules.management.models.BasicRule;
|
||||||
import com.knecon.fforesight.utility.rules.management.models.RuleClass;
|
import com.knecon.fforesight.utility.rules.management.models.RuleClass;
|
||||||
import com.knecon.fforesight.utility.rules.management.models.RuleFileBluePrint;
|
import com.knecon.fforesight.utility.rules.management.models.RuleFileBluePrint;
|
||||||
@ -49,6 +53,8 @@ public class RuleFileParser {
|
|||||||
PackageDescr packageDescr = parser.parse(false, rulesString);
|
PackageDescr packageDescr = parser.parse(false, rulesString);
|
||||||
StringBuilder queryBuilder = new StringBuilder();
|
StringBuilder queryBuilder = new StringBuilder();
|
||||||
List<BasicRule> allRules = new LinkedList<>();
|
List<BasicRule> allRules = new LinkedList<>();
|
||||||
|
List<BasicFunction> functions = new LinkedList<>();
|
||||||
|
List<BasicDeclaration> declarations = new LinkedList<>();
|
||||||
for (RuleDescr rule : packageDescr.getRules()) {
|
for (RuleDescr rule : packageDescr.getRules()) {
|
||||||
if (rule.isQuery()) {
|
if (rule.isQuery()) {
|
||||||
queryBuilder.append(rulesString, rule.getStartCharacter(), rule.getEndCharacter());
|
queryBuilder.append(rulesString, rule.getStartCharacter(), rule.getEndCharacter());
|
||||||
@ -57,6 +63,21 @@ public class RuleFileParser {
|
|||||||
}
|
}
|
||||||
allRules.add(BasicRule.fromRuleDescr(rule, rulesString));
|
allRules.add(BasicRule.fromRuleDescr(rule, rulesString));
|
||||||
}
|
}
|
||||||
|
for (FunctionDescr function : packageDescr.getFunctions()) {
|
||||||
|
functions.add(BasicFunction.fromFunctionDescr(function, rulesString));
|
||||||
|
}
|
||||||
|
for (AbstractClassTypeDeclarationDescr declaration : packageDescr.getTypeDeclarations()) {
|
||||||
|
declarations.add(BasicDeclaration.fromDeclarationDescription(declaration, rulesString));
|
||||||
|
}
|
||||||
|
for (AbstractClassTypeDeclarationDescr declaration : packageDescr.getEnumDeclarations()) {
|
||||||
|
declarations.add(BasicDeclaration.fromDeclarationDescription(declaration, rulesString));
|
||||||
|
}
|
||||||
|
for (AbstractClassTypeDeclarationDescr declaration : packageDescr.getClassAndEnumDeclarationDescrs()) {
|
||||||
|
declarations.add(BasicDeclaration.fromDeclarationDescription(declaration, rulesString));
|
||||||
|
}
|
||||||
|
for (AbstractClassTypeDeclarationDescr declaration : packageDescr.getTypeDeclarations()) {
|
||||||
|
declarations.add(BasicDeclaration.fromDeclarationDescription(declaration, rulesString));
|
||||||
|
}
|
||||||
String imports = rulesString.substring(0,
|
String imports = rulesString.substring(0,
|
||||||
packageDescr.getImports()
|
packageDescr.getImports()
|
||||||
.stream()
|
.stream()
|
||||||
@ -70,7 +91,7 @@ public class RuleFileParser {
|
|||||||
|
|
||||||
List<RuleClass> ruleClasses = buildRuleClasses(allRules);
|
List<RuleClass> ruleClasses = buildRuleClasses(allRules);
|
||||||
|
|
||||||
return new RuleFileBluePrint(imports.trim(), globals.trim(), queryBuilder.toString().trim(), ruleClasses);
|
return new RuleFileBluePrint(imports.trim(), globals.trim(), queryBuilder.toString().trim(), ruleClasses, declarations, functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ public class RuleFileMigrator {
|
|||||||
//replaceRules(ruleFileBluePrint, combinedBluePrint);
|
//replaceRules(ruleFileBluePrint, combinedBluePrint);
|
||||||
replaceRuleIdentifiers(combinedBluePrint, ruleFileBluePrint);
|
replaceRuleIdentifiers(combinedBluePrint, ruleFileBluePrint);
|
||||||
|
|
||||||
String migratedRulesString = RuleFileFactory.buildRuleString(ruleFileBluePrint);
|
String migratedRulesString = RuleFileFactory.buildRuleString(ruleFileBluePrint,false, false);
|
||||||
String migratedFilePath = ruleFile.getAbsolutePath();
|
String migratedFilePath = ruleFile.getAbsolutePath();
|
||||||
try (var out = new FileOutputStream(migratedFilePath)) {
|
try (var out = new FileOutputStream(migratedFilePath)) {
|
||||||
out.write(migratedRulesString.getBytes(StandardCharsets.UTF_8));
|
out.write(migratedRulesString.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public class RuleIdentifierMigrator {
|
|||||||
|
|
||||||
bluePrint = migrateMatchedRuleForAllRules(bluePrint);
|
bluePrint = migrateMatchedRuleForAllRules(bluePrint);
|
||||||
|
|
||||||
String ruleString = RuleFileFactory.buildRuleString(bluePrint);
|
String ruleString = RuleFileFactory.buildRuleString(bluePrint, false, false);
|
||||||
try (var out = new FileOutputStream("/tmp/all_redact_manager_rules.drl")) {
|
try (var out = new FileOutputStream("/tmp/all_redact_manager_rules.drl")) {
|
||||||
out.write(ruleString.getBytes(StandardCharsets.UTF_8));
|
out.write(ruleString.getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
@ -57,9 +57,10 @@ public class RuleIdentifierMigrator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//todo: introduce functions and declarations
|
||||||
private static RuleFileBluePrint migrateMatchedRuleForAllRules(RuleFileBluePrint bluePrint) {
|
private static RuleFileBluePrint migrateMatchedRuleForAllRules(RuleFileBluePrint bluePrint) {
|
||||||
|
|
||||||
List<BasicRule> migratedRules = bluePrint.ruleClasses()
|
List<BasicRule> migratedRules = bluePrint.getRuleClasses()
|
||||||
.stream()
|
.stream()
|
||||||
.map(RuleClass::ruleUnits)
|
.map(RuleClass::ruleUnits)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
@ -67,7 +68,12 @@ public class RuleIdentifierMigrator {
|
|||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.map(RuleIdentifierMigrator::migrateMatchedRule)
|
.map(RuleIdentifierMigrator::migrateMatchedRule)
|
||||||
.toList();
|
.toList();
|
||||||
RuleFileBluePrint migratedBluePrint = new RuleFileBluePrint(bluePrint.imports(), bluePrint.globals(), bluePrint.queries(), new LinkedList<>());
|
RuleFileBluePrint migratedBluePrint = new RuleFileBluePrint(bluePrint.getImports(),
|
||||||
|
bluePrint.getGlobals(),
|
||||||
|
bluePrint.getQueries(),
|
||||||
|
new LinkedList<>(),
|
||||||
|
new LinkedList<>(),
|
||||||
|
new LinkedList<>());
|
||||||
migratedRules.forEach(migratedBluePrint::addRule);
|
migratedRules.forEach(migratedBluePrint::addRule);
|
||||||
return migratedBluePrint;
|
return migratedBluePrint;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.knecon.fforesight.utility.rules.management.models;
|
||||||
|
|
||||||
|
import org.drools.drl.ast.descr.AbstractClassTypeDeclarationDescr;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
|
@ToString
|
||||||
|
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||||
|
public class BasicDeclaration {
|
||||||
|
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
|
String declarationFullTypeName;
|
||||||
|
String body;
|
||||||
|
int line;
|
||||||
|
|
||||||
|
|
||||||
|
public static BasicDeclaration fromDeclarationDescription(AbstractClassTypeDeclarationDescr declaration, String rulesString) {
|
||||||
|
|
||||||
|
String declarationFullTypeName = declaration.getFullTypeName();
|
||||||
|
String body = rulesString.substring(declaration.getStartCharacter(), declaration.getEndCharacter());
|
||||||
|
int line = declaration.getLine();
|
||||||
|
|
||||||
|
return new BasicDeclaration(declarationFullTypeName, body, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.knecon.fforesight.utility.rules.management.models;
|
||||||
|
|
||||||
|
import org.drools.drl.ast.descr.FunctionDescr;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
|
@ToString
|
||||||
|
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||||
|
public class BasicFunction {
|
||||||
|
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
|
String functionName;
|
||||||
|
String returnType;
|
||||||
|
String body;
|
||||||
|
int line;
|
||||||
|
|
||||||
|
|
||||||
|
public static BasicFunction fromFunctionDescr(FunctionDescr function, String rulesString) {
|
||||||
|
|
||||||
|
String functionName = function.getName();
|
||||||
|
String returnType = function.getReturnType();
|
||||||
|
String body = rulesString.substring(function.getStartCharacter(), function.getEndCharacter());
|
||||||
|
int line = function.getLine();
|
||||||
|
|
||||||
|
return new BasicFunction(functionName, returnType, body, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -10,7 +10,29 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public record RuleFileBluePrint(String imports, String globals, String queries, List<RuleClass> ruleClasses) {
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Slf4j
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
public class RuleFileBluePrint {
|
||||||
|
|
||||||
|
String imports;
|
||||||
|
String globals;
|
||||||
|
String queries;
|
||||||
|
List<RuleClass> ruleClasses;
|
||||||
|
List<BasicDeclaration> declarations;
|
||||||
|
List<BasicFunction> functions;
|
||||||
|
|
||||||
|
|
||||||
public boolean removeRule(RuleIdentifier ruleIdentifier) {
|
public boolean removeRule(RuleIdentifier ruleIdentifier) {
|
||||||
|
|
||||||
@ -24,7 +46,7 @@ public record RuleFileBluePrint(String imports, String globals, String queries,
|
|||||||
ruleClass.ruleUnits().remove(ruleUnit);
|
ruleClass.ruleUnits().remove(ruleUnit);
|
||||||
}
|
}
|
||||||
if (ruleClass.ruleUnits().isEmpty()) {
|
if (ruleClass.ruleUnits().isEmpty()) {
|
||||||
ruleClasses().remove(ruleClass);
|
this.ruleClasses.remove(ruleClass);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return wasRemoved.get();
|
return wasRemoved.get();
|
||||||
@ -41,7 +63,7 @@ public record RuleFileBluePrint(String imports, String globals, String queries,
|
|||||||
|
|
||||||
public Set<BasicRule> getAllRules() {
|
public Set<BasicRule> getAllRules() {
|
||||||
|
|
||||||
return ruleClasses().stream()
|
return this.ruleClasses.stream()
|
||||||
.map(RuleClass::ruleUnits)
|
.map(RuleClass::ruleUnits)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.map(RuleUnit::rules)
|
.map(RuleUnit::rules)
|
||||||
@ -101,7 +123,7 @@ public record RuleFileBluePrint(String imports, String globals, String queries,
|
|||||||
|
|
||||||
public Set<RuleIdentifier> getAllRuleIdentifiers() {
|
public Set<RuleIdentifier> getAllRuleIdentifiers() {
|
||||||
|
|
||||||
return ruleClasses().stream()
|
return ruleClasses.stream()
|
||||||
.map(RuleClass::ruleUnits)
|
.map(RuleClass::ruleUnits)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.map(RuleUnit::rules)
|
.map(RuleUnit::rules)
|
||||||
@ -122,10 +144,16 @@ public record RuleFileBluePrint(String imports, String globals, String queries,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setImports(String newImports) {
|
||||||
|
|
||||||
|
this.imports = newImports;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public RuleFileBluePrint buildFilteredBluePrintByRuleIdentifiers(Set<RuleIdentifier> identifiers) {
|
public RuleFileBluePrint buildFilteredBluePrintByRuleIdentifiers(Set<RuleIdentifier> identifiers) {
|
||||||
|
|
||||||
RuleFileBluePrint filteredBluePrint = new RuleFileBluePrint(imports(), globals(), queries(), new LinkedList<>());
|
RuleFileBluePrint filteredBluePrint = new RuleFileBluePrint(imports, globals, queries, new LinkedList<>(), new LinkedList<>(), new LinkedList<>());
|
||||||
ruleClasses().stream()
|
ruleClasses.stream()
|
||||||
.flatMap(ruleClass -> ruleClass.ruleUnits()
|
.flatMap(ruleClass -> ruleClass.ruleUnits()
|
||||||
.stream())
|
.stream())
|
||||||
.flatMap(ruleUnit -> ruleUnit.rules()
|
.flatMap(ruleUnit -> ruleUnit.rules()
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import com.knecon.fforesight.utility.rules.management.factory.RuleFileParser;
|
|||||||
import com.knecon.fforesight.utility.rules.management.models.RuleFileBluePrint;
|
import com.knecon.fforesight.utility.rules.management.models.RuleFileBluePrint;
|
||||||
import com.knecon.fforesight.utility.rules.management.models.RuleIdentifier;
|
import com.knecon.fforesight.utility.rules.management.models.RuleIdentifier;
|
||||||
|
|
||||||
public class RuleFileBluePrintMergingTest {
|
public class RuleCompilationResultMergingTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBothRuleFilesCanBeMerged() {
|
public void testBothRuleFilesCanBeMerged() {
|
||||||
Loading…
x
Reference in New Issue
Block a user