Compare commits

..
Author SHA1 Message Date
Thierry Göckel bf89e42fcf DEV: Update rules on each redaction request. 2020-07-09 13:47:31 +02:00
Thierry Goeckel a3d471e940 Pull request #1: DEV: Handle rules validation exception when updating.
Merge in RED/redaction-service from dev/rules-validation to master

* commit '23741deff713d5c865c13aa3a8cac73795d969e8':
  DEV: Use appropriate HTTP request type.
  DEV: Handle rules validation exception when updating.
2020-07-09 10:25:26 +02:00
Thierry Göckel 23741deff7 DEV: Use appropriate HTTP request type. 2020-07-09 10:06:17 +02:00
Thierry Göckel bbc3b862a0 DEV: Handle rules validation exception when updating. 2020-07-08 11:27:28 +02:00
8 changed files with 120 additions and 24 deletions
@@ -1,6 +1,7 @@
package com.iqser.red.service.redaction.v1.resources;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -23,9 +24,10 @@ public interface RedactionResource {
@PostMapping(value = "/debug/htmlTables", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
RedactionResult htmlTables(@RequestBody RedactionRequest redactionRequest);
@PostMapping(value = "/rules", produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = "/rules", produces = MediaType.APPLICATION_JSON_VALUE)
String getRules();
@PostMapping(value = "/rules/update", consumes = MediaType.APPLICATION_JSON_VALUE)
void updateRules(@RequestBody String rules);
}
}
@@ -31,6 +31,16 @@
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.iqser.red.service</groupId>
<artifactId>redaction-service-api-v1</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.iqser.red.service</groupId>
<artifactId>configuration-service-api-v1</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
@@ -46,11 +56,6 @@
<artifactId>jts-core</artifactId>
<version>1.16.1</version>
</dependency>
<dependency>
<groupId>com.iqser.red.service</groupId>
<artifactId>redaction-service-api-v1</artifactId>
<version>${project.version}</version>
</dependency>
<!-- commons -->
<dependency>
<groupId>com.iqser.gin4.commons</groupId>
@@ -19,7 +19,7 @@ import com.iqser.red.service.redaction.v1.server.settings.RedactionServiceSettin
@Import({DefaultWebMvcConfiguration.class})
@EnableConfigurationProperties(RedactionServiceSettings.class)
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
@@ -30,6 +30,7 @@ public class Application {
@Bean
public KieContainer kieContainer() {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
@@ -39,6 +40,7 @@ public class Application {
KieModule kieModule = kieBuilder.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
}
@@ -0,0 +1,9 @@
package com.iqser.red.service.redaction.v1.server.client;
import org.springframework.cloud.openfeign.FeignClient;
import com.iqser.red.service.configuration.v1.api.resource.RulesResource;
@FeignClient(name = RulesResource.SERVICE_NAME, url = "http://" + RulesResource.SERVICE_NAME + ":8080")
public interface RulesClient extends RulesResource {
}
@@ -0,0 +1,41 @@
package com.iqser.red.service.redaction.v1.server.controller;
import java.time.OffsetDateTime;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.iqser.gin4.commons.api.errorhandling.ErrorMessage;
import com.iqser.red.service.redaction.v1.server.exception.RulesValidationException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestControllerAdvice
public class ControllerAdvice {
/* error handling */
@ResponseBody
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = NullPointerException.class)
public ErrorMessage handleContentNotFoundException(NullPointerException e) {
if (e != null) {
log.error(e.getMessage(), e);
return new ErrorMessage(OffsetDateTime.now(), e.getMessage());
}
log.error("Nullpointer exception at ", e);
return new ErrorMessage(OffsetDateTime.now(), "Nullpointer exception");
}
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = RulesValidationException.class)
public ErrorMessage handleRulesValidationException(RulesValidationException e) {
return new ErrorMessage(OffsetDateTime.now(), e.getMessage());
}
}
@@ -13,6 +13,7 @@ import com.iqser.red.service.redaction.v1.model.RedactionResult;
import com.iqser.red.service.redaction.v1.resources.RedactionResource;
import com.iqser.red.service.redaction.v1.server.classification.model.Document;
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
import com.iqser.red.service.redaction.v1.server.client.RulesClient;
import com.iqser.red.service.redaction.v1.server.exception.RedactionException;
import com.iqser.red.service.redaction.v1.server.redaction.service.DroolsExecutionService;
import com.iqser.red.service.redaction.v1.server.redaction.service.EntityRedactionService;
@@ -24,9 +25,7 @@ import com.iqser.red.service.redaction.v1.server.visualization.service.PdfFlatte
import com.iqser.red.service.redaction.v1.server.visualization.service.PdfVisualisationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequiredArgsConstructor
public class RedactionController implements RedactionResource {
@@ -37,11 +36,15 @@ public class RedactionController implements RedactionResource {
private final EntityRedactionService entityRedactionService;
private final PdfFlattenService pdfFlattenService;
private final DroolsExecutionService droolsExecutionService;
private final RulesClient rulesClient;
private long rulesVersion = -1;
@Override
public RedactionResult redact(@RequestBody RedactionRequest redactionRequest) {
try (PDDocument pdDocument = PDDocument.load(new ByteArrayInputStream(redactionRequest.getDocument()))) {
updateRules();
pdDocument.setAllSecurityToBeRemoved(true);
Document classifiedDoc = pdfSegmentationService.parseDocument(pdDocument);
@@ -58,12 +61,14 @@ public class RedactionController implements RedactionResource {
} catch (IOException e) {
throw new RedactionException(e);
}
}
@Override
public RedactionResult classify(@RequestBody RedactionRequest pdfSegmentationRequest) {
try (PDDocument pdDocument = PDDocument.load(new ByteArrayInputStream(pdfSegmentationRequest.getDocument()))) {
updateRules();
pdDocument.setAllSecurityToBeRemoved(true);
Document classifiedDoc = pdfSegmentationService.parseDocument(pdDocument);
@@ -74,12 +79,14 @@ public class RedactionController implements RedactionResource {
} catch (IOException e) {
throw new RedactionException(e);
}
}
@Override
public RedactionResult sections(@RequestBody RedactionRequest redactionRequest) {
try (PDDocument pdDocument = PDDocument.load(new ByteArrayInputStream(redactionRequest.getDocument()))) {
updateRules();
pdDocument.setAllSecurityToBeRemoved(true);
Document classifiedDoc = pdfSegmentationService.parseDocument(pdDocument);
@@ -90,11 +97,14 @@ public class RedactionController implements RedactionResource {
} catch (IOException e) {
throw new RedactionException(e);
}
}
@Override
public RedactionResult htmlTables(@RequestBody RedactionRequest redactionRequest) {
try (PDDocument pdDocument = PDDocument.load(new ByteArrayInputStream(redactionRequest.getDocument()))) {
updateRules();
pdDocument.setAllSecurityToBeRemoved(true);
Document classifiedDoc = pdfSegmentationService.parseDocument(pdDocument);
@@ -114,17 +124,21 @@ public class RedactionController implements RedactionResource {
} catch (IOException e) {
throw new RedactionException(e);
}
}
@Override
public String getRules() {
return droolsExecutionService.getRules();
}
@Override
public void updateRules(@RequestBody String rules) {
droolsExecutionService.updateRules(rules);
}
private RedactionResult convert(PDDocument document, int numberOfPages) throws IOException {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
document.save(byteArrayOutputStream);
return RedactionResult.builder()
@@ -132,6 +146,17 @@ public class RedactionController implements RedactionResource {
.numberOfPages(numberOfPages)
.build();
}
}
private void updateRules() {
long version = rulesClient.getVersion();
if (version > rulesVersion) {
rulesVersion = version;
updateRules(rulesClient.getRules().getRules());
}
}
}
@@ -0,0 +1,9 @@
package com.iqser.red.service.redaction.v1.server.exception;
public class RulesValidationException extends RuntimeException {
public RulesValidationException(String message, Throwable t) {
super(message, t);
}
}
@@ -2,9 +2,11 @@ package com.iqser.red.service.redaction.v1.server.redaction.service;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
@@ -14,6 +16,7 @@ import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.iqser.red.service.redaction.v1.server.exception.RulesValidationException;
import com.iqser.red.service.redaction.v1.server.redaction.model.Section;
import com.iqser.red.service.redaction.v1.server.redaction.utils.ResourceLoader;
@@ -26,7 +29,7 @@ public class DroolsExecutionService {
private String currentDrlRules;
@PostConstruct
public void init (){
public void init() {
currentDrlRules = ResourceLoader.loadAsString("drools/rules.drl");
}
@@ -39,29 +42,29 @@ public class DroolsExecutionService {
return section;
}
public void updateRules(String drlAsString) {
try {
if (StringUtils.isEmpty(drlAsString)) {
throw new RuntimeException("Rules cannot be empty.");
}
KieServices kieServices = KieServices.Factory.get();
InputStream input = new ByteArrayInputStream(drlAsString.getBytes("UTF-8"));
InputStream input = new ByteArrayInputStream(drlAsString.getBytes(StandardCharsets.UTF_8));
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write("src/main/resources/drools/rules.drl",
kieServices.getResources().newInputStreamResource(input));
kieFileSystem.write("src/main/resources/drools/rules.drl", kieServices.getResources().newInputStreamResource(input));
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
kieContainer.updateToVersion(kieModule.getReleaseId());
currentDrlRules = drlAsString;
} catch (Exception e){
throw new RuntimeException("Could not update rules");
} catch (Exception e) {
throw new RulesValidationException("Could not update rules", e);
}
}
public String getRules(){
public String getRules() {
return currentDrlRules;
}
}
}