RED-7493: provide error messages in testRules Endpoint #103
@ -0,0 +1,16 @@
|
||||
package com.iqser.red.service.redaction.v1.model;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
public class DroolsSyntaxErrorMessage {
|
||||
|
||||
Integer line;
|
||||
Integer column;
|
||||
String message;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.iqser.red.service.redaction.v1.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
public class DroolsSyntaxValidation {
|
||||
|
||||
boolean compiled;
|
||||
List<DroolsSyntaxErrorMessage> droolsSyntaxErrorMessages;
|
||||
}
|
||||
@ -4,9 +4,11 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation;
|
||||
|
||||
public interface RedactionResource {
|
||||
|
||||
@PostMapping(value = "/rules/test", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
void testRules(@RequestBody String rules);
|
||||
DroolsSyntaxValidation testRules(@RequestBody String rules);
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.iqser.red.service.redaction.v1.server.controller;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation;
|
||||
import com.iqser.red.service.redaction.v1.resources.RedactionResource;
|
||||
import com.iqser.red.service.redaction.v1.server.exception.RulesValidationException;
|
||||
import com.iqser.red.service.redaction.v1.server.redaction.service.DroolsExecutionService;
|
||||
@ -19,10 +20,10 @@ public class RedactionController implements RedactionResource {
|
||||
|
||||
|
||||
@Override
|
||||
public void testRules(@RequestBody String rules) {
|
||||
public DroolsSyntaxValidation testRules(@RequestBody String rules) {
|
||||
|
||||
try {
|
||||
droolsExecutionService.testRules(rules);
|
||||
return droolsExecutionService.testRules(rules);
|
||||
} catch (Exception e) {
|
||||
throw new RulesValidationException("Could not test rules: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
@ -7,17 +7,14 @@ import static java.util.stream.Collectors.toList;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.drools.compiler.kie.builder.impl.InternalKieServices;
|
||||
import org.kie.api.KieServices;
|
||||
import org.kie.api.builder.KieBuilder;
|
||||
import org.kie.api.builder.KieFileSystem;
|
||||
@ -28,24 +25,18 @@ import org.kie.api.runtime.rule.QueryResults;
|
||||
import org.kie.api.runtime.rule.QueryResultsRow;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.hash.HashFunction;
|
||||
import com.google.common.hash.Hasher;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.common.primitives.Longs;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribute;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation;
|
||||
import com.iqser.red.service.redaction.v1.server.client.RulesClient;
|
||||
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.Document;
|
||||
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.SemanticNode;
|
||||
import com.iqser.red.service.redaction.v1.server.document.services.EntityCreationService;
|
||||
import com.iqser.red.service.redaction.v1.server.document.services.EntityEnrichmentService;
|
||||
import com.iqser.red.service.redaction.v1.server.document.services.ManualRedactionApplicationService;
|
||||
import com.iqser.red.service.redaction.v1.server.exception.RulesValidationException;
|
||||
import com.iqser.red.service.redaction.v1.server.redaction.adapter.NerEntities;
|
||||
import com.iqser.red.service.redaction.v1.server.redaction.model.KieWrapper;
|
||||
import com.iqser.red.service.redaction.v1.server.redaction.model.dictionary.Dictionary;
|
||||
@ -60,12 +51,15 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = false)
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
public class DroolsExecutionService {
|
||||
|
||||
final RulesClient rulesClient;
|
||||
RulesClient rulesClient;
|
||||
|
||||
EntityEnrichmentService entityEnrichmentService;
|
||||
|
||||
DroolsSyntaxValidationFactory droolsSyntaxValidationFactory;
|
||||
|
||||
final EntityEnrichmentService entityEnrichmentService;
|
||||
|
||||
@Timed("redactmanager_executeRules")
|
||||
public List<FileAttribute> executeRules(KieContainer kieContainer,
|
||||
@ -191,7 +185,7 @@ public class DroolsExecutionService {
|
||||
}
|
||||
|
||||
|
||||
private void registerNewKieContainerVersion(String dossierTemplateId, long version, String rules) {
|
||||
private KieBuilder registerNewKieContainerVersion(String dossierTemplateId, long version, String rules) {
|
||||
|
||||
KieServices kieServices = KieServices.Factory.get();
|
||||
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
|
||||
@ -199,26 +193,16 @@ public class DroolsExecutionService {
|
||||
InputStream input = new ByteArrayInputStream(rules.getBytes(StandardCharsets.UTF_8));
|
||||
kieFileSystem.write("src/main/resources/drools/rules" + dossierTemplateId + ".drl", kieServices.getResources().newInputStreamResource(input));
|
||||
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
|
||||
kieBuilder.buildAll();
|
||||
return kieBuilder.buildAll();
|
||||
}
|
||||
|
||||
|
||||
public void testRules(String rules) {
|
||||
public DroolsSyntaxValidation testRules(String rules) {
|
||||
|
||||
var versionId = System.currentTimeMillis();
|
||||
var testRules = "test-rules";
|
||||
registerNewKieContainerVersion(testRules, versionId, rules);
|
||||
var releaseId = getReleaseId(testRules, versionId);
|
||||
try {
|
||||
KieServices kieServices = KieServices.Factory.get();
|
||||
var containerId = UUID.randomUUID().toString();
|
||||
var container = kieServices.newKieContainer(containerId, releaseId);
|
||||
container.newKieSession();
|
||||
container.dispose();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RulesValidationException("Could not update rules: " + e.getMessage(), e);
|
||||
}
|
||||
KieBuilder kieBuilder = registerNewKieContainerVersion(testRules, versionId, rules);
|
||||
return droolsSyntaxValidationFactory.buildDroolsSyntaxValidation(kieBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package com.iqser.red.service.redaction.v1.server.redaction.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.kie.api.builder.KieBuilder;
|
||||
import org.kie.api.builder.Message;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxErrorMessage;
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation;
|
||||
|
||||
@Service
|
||||
public class DroolsSyntaxValidationFactory {
|
||||
|
||||
public DroolsSyntaxValidation buildDroolsSyntaxValidation(KieBuilder kieBuilder) {
|
||||
|
||||
List<Message> errorMessages = kieBuilder.getResults().getMessages(Message.Level.ERROR);
|
||||
List<DroolsSyntaxErrorMessage> droolsSyntaxErrorMessages = errorMessages.stream().map(this::buildDroolsSyntaxErrorMessage).toList();
|
||||
return DroolsSyntaxValidation.builder().compiled(droolsSyntaxErrorMessages.isEmpty()).droolsSyntaxErrorMessages(droolsSyntaxErrorMessages).build();
|
||||
}
|
||||
|
||||
|
||||
public DroolsSyntaxErrorMessage buildDroolsSyntaxErrorMessage(Message message) {
|
||||
|
||||
return DroolsSyntaxErrorMessage.builder().line(message.getLine()).column(message.getColumn()).message(message.getText()).build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.iqser.red.service.redaction.v1.server.redaction.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation;
|
||||
import com.iqser.red.service.redaction.v1.server.client.RulesClient;
|
||||
import com.iqser.red.service.redaction.v1.server.document.services.EntityEnrichmentService;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
class DroolsExecutionServiceTest {
|
||||
|
||||
@MockBean
|
||||
RulesClient rulesClient;
|
||||
@MockBean
|
||||
EntityEnrichmentService entityEnrichmentService;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() {
|
||||
|
||||
MockitoAnnotations.openMocks(this);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void testRules() {
|
||||
|
||||
DroolsExecutionService droolsExecutionService = new DroolsExecutionService(rulesClient, entityEnrichmentService, new DroolsSyntaxValidationFactory());
|
||||
var rulesFile = new ClassPathResource("drools/rules.drl");
|
||||
|
||||
String rulesString = new String(rulesFile.getInputStream().readAllBytes());
|
||||
|
||||
DroolsSyntaxValidation droolsSyntaxValidation = droolsExecutionService.testRules(rulesString);
|
||||
assertTrue(droolsSyntaxValidation.isCompiled());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void testCorruptedRules() {
|
||||
|
||||
DroolsExecutionService droolsExecutionService = new DroolsExecutionService(rulesClient, entityEnrichmentService, new DroolsSyntaxValidationFactory());
|
||||
var rulesFile = new ClassPathResource("drools/rules.drl");
|
||||
|
||||
String rulesString = new String(rulesFile.getInputStream().readAllBytes());
|
||||
String corruptedRules = rulesString.replaceAll(";", "");
|
||||
|
||||
DroolsSyntaxValidation droolsSyntaxValidation = droolsExecutionService.testRules(corruptedRules);
|
||||
assertFalse(droolsSyntaxValidation.isCompiled());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user