RED-9349 - Add possibility to log stuff in the rules #446
@ -20,6 +20,7 @@ val persistenceServiceVersion = "2.444.0"
|
||||
val springBootStarterVersion = "3.1.5"
|
||||
val springCloudVersion = "4.0.4"
|
||||
val testContainersVersion = "1.19.7"
|
||||
val tomcatVersion = "10.1.18"
|
||||
|
||||
configurations {
|
||||
all {
|
||||
@ -41,6 +42,7 @@ dependencies {
|
||||
|
||||
implementation("com.iqser.red.commons:dictionary-merge-commons:1.5.0")
|
||||
implementation("com.iqser.red.commons:storage-commons:2.45.0")
|
||||
implementation("com.knecon.fforesight:keycloak-commons:0.29.0")
|
||||
implementation("com.knecon.fforesight:tenant-commons:0.24.0")
|
||||
implementation("com.knecon.fforesight:tracing-commons:0.5.0")
|
||||
|
||||
@ -60,6 +62,11 @@ dependencies {
|
||||
implementation("org.springframework.boot:spring-boot-starter-cache:${springBootStarterVersion}")
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-redis:${springBootStarterVersion}")
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter-websocket:${springBootStarterVersion}")
|
||||
implementation("org.springframework.security:spring-security-messaging:6.1.3")
|
||||
implementation("org.apache.tomcat:tomcat-websocket:${tomcatVersion}")
|
||||
implementation("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
|
||||
implementation("net.logstash.logback:logstash-logback-encoder:7.4")
|
||||
implementation("ch.qos.logback:logback-classic")
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import com.iqser.red.service.dictionarymerge.commons.DictionaryMergeService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.SharedMongoAutoConfiguration;
|
||||
import com.iqser.red.service.redaction.v1.server.client.RulesClient;
|
||||
import com.iqser.red.storage.commons.StorageAutoConfiguration;
|
||||
import com.knecon.fforesight.keycloakcommons.DefaultKeyCloakCommonsAutoConfiguration;
|
||||
import com.knecon.fforesight.mongo.database.commons.MongoDatabaseCommonsAutoConfiguration;
|
||||
import com.knecon.fforesight.mongo.database.commons.liquibase.EnableMongoLiquibase;
|
||||
import com.knecon.fforesight.tenantcommons.MultiTenancyAutoConfiguration;
|
||||
@ -32,7 +33,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@EnableCaching
|
||||
@ImportAutoConfiguration({MultiTenancyAutoConfiguration.class, SharedMongoAutoConfiguration.class})
|
||||
@ImportAutoConfiguration({MultiTenancyAutoConfiguration.class, SharedMongoAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class})
|
||||
@Import({MetricsConfiguration.class, StorageAutoConfiguration.class, MongoDatabaseCommonsAutoConfiguration.class})
|
||||
@EnableFeignClients(basePackageClasses = RulesClient.class)
|
||||
@EnableConfigurationProperties(RedactionServiceSettings.class)
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
package com.iqser.red.service.redaction.v1.server.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.simp.config.ChannelRegistration;
|
||||
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
|
||||
import org.springframework.messaging.simp.stomp.StompCommand;
|
||||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
|
||||
import org.springframework.messaging.support.ChannelInterceptor;
|
||||
import org.springframework.messaging.support.MessageHeaderAccessor;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
|
||||
|
||||
import com.knecon.fforesight.keycloakcommons.security.TenantAuthenticationManagerResolver;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
@RequiredArgsConstructor
|
||||
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
private final TenantAuthenticationManagerResolver tenantAuthenticationManagerResolver;
|
||||
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry config) {
|
||||
|
||||
config.enableSimpleBroker("/topic");
|
||||
config.setApplicationDestinationPrefixes("/app");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
|
||||
registry.addEndpoint("/api/rules-logging/rulesocket").setAllowedOrigins("*");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void configureClientInboundChannel(ChannelRegistration registration) {
|
||||
|
||||
// https://docs.spring.io/spring-framework/reference/web/websocket/stomp/authentication-token-based.html
|
||||
registration.interceptors(new ChannelInterceptor() {
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
|
||||
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
|
||||
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
|
||||
Optional.ofNullable(accessor.getNativeHeader("Authorization"))
|
||||
.ifPresent(ah -> {
|
||||
String bearerToken = ah.get(0).replace("Bearer ", "");
|
||||
log.info("Received bearer token {}", bearerToken);
|
||||
AuthenticationManager authenticationManager = tenantAuthenticationManagerResolver.resolve(bearerToken);
|
||||
JwtAuthenticationToken token = (JwtAuthenticationToken) authenticationManager.authenticate(new BearerTokenAuthenticationToken(bearerToken));
|
||||
accessor.setUser(token);
|
||||
});
|
||||
}
|
||||
return message;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public TomcatServletWebServerFactory tomcatContainerFactory() {
|
||||
|
||||
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
|
||||
factory.setTomcatContextCustomizers(Collections.singletonList(tomcatContextCustomizer()));
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public TomcatContextCustomizer tomcatContextCustomizer() {
|
||||
|
||||
return context -> context.addServletContainerInitializer(new WsSci(), null);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package com.iqser.red.service.redaction.v1.server.config;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
|
||||
import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
|
||||
import org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
|
||||
import com.knecon.fforesight.keycloakcommons.security.TokenUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class WebSocketSecurityConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Value("${cors.enabled:false}")
|
||||
private boolean corsEnabled;
|
||||
|
||||
|
||||
@Override
|
||||
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
|
||||
|
||||
messages.simpTypeMatchers(SimpMessageType.HEARTBEAT, SimpMessageType.UNSUBSCRIBE, SimpMessageType.DISCONNECT)
|
||||
.permitAll()
|
||||
.simpTypeMatchers(SimpMessageType.CONNECT)
|
||||
.anonymous() // this is intended, see WebSocketConfiguration.configureClientInboundChannel
|
||||
.simpTypeMatchers(SimpMessageType.SUBSCRIBE)
|
||||
.access("@tenantWebSocketSecurityMatcher.checkCanSubscribeTo(authentication,message)")
|
||||
.anyMessage()
|
||||
.denyAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean sameOriginDisabled() {
|
||||
|
||||
return corsEnabled;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public TenantWebSocketSecurityMatcher tenantWebSocketSecurityMatcher() {
|
||||
|
||||
return new TenantWebSocketSecurityMatcher();
|
||||
}
|
||||
|
||||
|
||||
public class TenantWebSocketSecurityMatcher {
|
||||
|
||||
public boolean checkCanSubscribeTo(JwtAuthenticationToken authentication, Message<?> message) {
|
||||
|
||||
var targetedTenant = extractTenantId(message);
|
||||
var currentTenant = getCurrentTenant(authentication);
|
||||
return targetedTenant.isPresent() && currentTenant.isPresent() && currentTenant.get().equals(targetedTenant.get());
|
||||
}
|
||||
|
||||
|
||||
private Optional<String> getCurrentTenant(JwtAuthenticationToken authentication) {
|
||||
|
||||
if (authentication != null && authentication.getToken() != null && authentication.getToken().getTokenValue() != null) {
|
||||
return Optional.of(TokenUtils.toTenant(authentication.getToken().getTokenValue()));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Optional<String> extractTenantId(Message<?> message) {
|
||||
|
||||
StompHeaderAccessor sha = StompHeaderAccessor.wrap(message);
|
||||
String topic = sha.getDestination();
|
||||
if (topic == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String tenant = topic.split("/")[2];
|
||||
return Optional.of(tenant);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.iqser.red.service.redaction.v1.server.logger;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@ToString
|
||||
public final class Context {
|
||||
|
||||
private String fileId;
|
||||
private String dossierId;
|
||||
private String dossierTemplateId;
|
||||
@Setter
|
||||
private long ruleVersion;
|
||||
private int analysisNumber;
|
||||
private String tenantId;
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.iqser.red.service.redaction.v1.server.logger;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
@Builder
|
||||
@ToString
|
||||
public class RuleLogEvent {
|
||||
|
||||
private String tenantId;
|
||||
private String fileId;
|
||||
private String dossierId;
|
||||
private String dossierTemplateId;
|
||||
private long ruleVersion;
|
||||
private int analysisNumber;
|
||||
private OffsetDateTime timeStamp;
|
||||
private LogLevel logLevel;
|
||||
private String message;
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
enum LogLevel {
|
||||
INFO("INFO"),
|
||||
WARN("WARN"),
|
||||
ERROR("ERROR");
|
||||
|
||||
private final String name;
|
||||
|
||||
|
||||
LogLevel(String name) {
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package com.iqser.red.service.redaction.v1.server.logger;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.service.WebSocketService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class RulesLogger {
|
||||
|
||||
private final WebSocketService webSocketService;
|
||||
|
||||
public void info(Context context, String message, Object... args) {
|
||||
|
||||
log(LogLevel.INFO, context, message, args);
|
||||
}
|
||||
|
||||
|
||||
public void warn(Context context, String message, Object... args) {
|
||||
|
||||
log(LogLevel.WARN, context, message, args);
|
||||
}
|
||||
|
||||
|
||||
public void error(Context context, String message, Throwable throwable, Object... args) {
|
||||
|
||||
log(LogLevel.ERROR, context, message + " Exception: " + throwable.toString(), args);
|
||||
}
|
||||
|
||||
|
||||
private void log(LogLevel logLevel, Context context, String message, Object... args) {
|
||||
|
||||
var formattedMessage = formatMessage(message, args);
|
||||
var ruleLog = RuleLogEvent.builder()
|
||||
.tenantId(context.getTenantId())
|
||||
.ruleVersion(context.getRuleVersion())
|
||||
.fileId(context.getFileId())
|
||||
.analysisNumber(context.getAnalysisNumber())
|
||||
.dossierId(context.getDossierId())
|
||||
.dossierTemplateId(context.getDossierTemplateId())
|
||||
.message(formattedMessage)
|
||||
.logLevel(logLevel)
|
||||
.timeStamp(OffsetDateTime.now())
|
||||
.build();
|
||||
|
||||
webSocketService.sendLogEvent(ruleLog);
|
||||
}
|
||||
|
||||
|
||||
private String formatMessage(String message, Object... args) {
|
||||
|
||||
if (args == null || args.length == 0) {
|
||||
return message;
|
||||
}
|
||||
|
||||
var pattern = Pattern.compile("\\{}");
|
||||
var matcher = pattern.matcher(message);
|
||||
var sb = new StringBuilder();
|
||||
int i = 0;
|
||||
|
||||
while (matcher.find() && i < args.length) {
|
||||
matcher.appendReplacement(sb, args[i] != null ? args[i].toString() : "null");
|
||||
i++;
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -27,6 +27,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
|
||||
import com.iqser.red.service.redaction.v1.server.RedactionServiceSettings;
|
||||
import com.iqser.red.service.redaction.v1.server.client.model.NerEntitiesModel;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.KieWrapper;
|
||||
import com.iqser.red.service.redaction.v1.server.model.NerEntities;
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Component;
|
||||
@ -46,6 +47,7 @@ import com.iqser.red.service.redaction.v1.server.service.drools.EntityDroolsExec
|
||||
import com.iqser.red.service.redaction.v1.server.service.drools.KieContainerCreationService;
|
||||
import com.iqser.red.service.redaction.v1.server.storage.ObservedStorageService;
|
||||
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import io.micrometer.observation.annotation.Observed;
|
||||
@ -93,6 +95,8 @@ public class AnalyzeService {
|
||||
ImportedRedactions importedRedactions = redactionStorageService.getImportedRedactions(analyzeRequest.getDossierId(), analyzeRequest.getFileId());
|
||||
log.info("Loaded Imported Redactions for file {} in dossier {}", analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
Context context = new Context(analyzeRequest.getFileId(), analyzeRequest.getDossierId(), analyzeRequest.getDossierTemplateId(), 0, analyzeRequest.getAnalysisNumber(), TenantContext.getTenantId());
|
||||
|
||||
// not yet ready for reanalysis
|
||||
if (entityLogWithoutEntries == null || document == null || document.getNumberOfPages() == 0) {
|
||||
return analyze(analyzeRequest);
|
||||
@ -128,12 +132,15 @@ public class AnalyzeService {
|
||||
document,
|
||||
document.getNumberOfPages(),
|
||||
true,
|
||||
Collections.emptySet());
|
||||
Collections.emptySet(),
|
||||
context);
|
||||
}
|
||||
|
||||
KieWrapper kieWrapperEntityRules = kieContainerCreationService.getLatestKieContainer(analyzeRequest.getDossierTemplateId(), RuleFileType.ENTITY);
|
||||
log.info("Updated entity rules to version {} for file {} in dossier {}", kieWrapperEntityRules.rulesVersion(), analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
context.setRuleVersion(kieWrapperEntityRules.rulesVersion());
|
||||
|
||||
NerEntities nerEntities = getEntityRecognitionEntitiesFilteredBySectionIds(analyzeRequest, document, sectionsToReanalyseIds);
|
||||
log.info("Loaded Ner Entities for file {} in dossier {}", analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
@ -158,7 +165,8 @@ public class AnalyzeService {
|
||||
dictionary,
|
||||
analyzeRequest.getFileAttributes(),
|
||||
analyzeRequest.getManualRedactions(),
|
||||
nerEntities);
|
||||
nerEntities,
|
||||
context);
|
||||
log.info("Finished entity rule execution for file {} in dossier {}", analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
EntityLogChanges entityLogChanges = entityLogCreatorService.updatePreviousEntityLog(analyzeRequest,
|
||||
@ -177,7 +185,8 @@ public class AnalyzeService {
|
||||
document,
|
||||
document.getNumberOfPages(),
|
||||
true,
|
||||
new HashSet<>(allFileAttributes));
|
||||
new HashSet<>(allFileAttributes),
|
||||
context);
|
||||
}
|
||||
|
||||
|
||||
@ -193,6 +202,8 @@ public class AnalyzeService {
|
||||
var kieWrapperComponentRules = kieContainerCreationService.getLatestKieContainer(analyzeRequest.getDossierTemplateId(), RuleFileType.COMPONENT);
|
||||
log.info("Updated Rules to Version {} for file {} in dossier {}", kieWrapperEntityRules.rulesVersion(), analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
Context context = new Context(analyzeRequest.getFileId(), analyzeRequest.getDossierId(), analyzeRequest.getDossierTemplateId(), kieWrapperEntityRules.rulesVersion(), analyzeRequest.getAnalysisNumber(), TenantContext.getTenantId());
|
||||
|
||||
Document document = DocumentGraphMapper.toDocumentGraph(observedStorageService.getDocumentData(analyzeRequest.getDossierId(), analyzeRequest.getFileId()));
|
||||
log.info("Loaded Document Graph for file {} in dossier {}", analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
@ -223,7 +234,8 @@ public class AnalyzeService {
|
||||
dictionary,
|
||||
analyzeRequest.getFileAttributes(),
|
||||
analyzeRequest.getManualRedactions(),
|
||||
nerEntities);
|
||||
nerEntities,
|
||||
context);
|
||||
log.info("Finished entity rule execution for file {} in dossier {}", analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
EntityLogChanges entityLogChanges = entityLogCreatorService.createInitialEntityLog(analyzeRequest,
|
||||
@ -241,7 +253,8 @@ public class AnalyzeService {
|
||||
document,
|
||||
document.getNumberOfPages(),
|
||||
false,
|
||||
new HashSet<>(allFileAttributes));
|
||||
new HashSet<>(allFileAttributes),
|
||||
context);
|
||||
}
|
||||
|
||||
|
||||
@ -252,7 +265,8 @@ public class AnalyzeService {
|
||||
Document document,
|
||||
int numberOfPages,
|
||||
boolean isReanalysis,
|
||||
Set<FileAttribute> addedFileAttributes) {
|
||||
Set<FileAttribute> addedFileAttributes,
|
||||
Context context) {
|
||||
|
||||
EntityLog entityLog = entityLogChanges.getEntityLog();
|
||||
|
||||
@ -274,7 +288,7 @@ public class AnalyzeService {
|
||||
|
||||
log.info("Created entity log for file {} in dossier {}", analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
computeComponentsWhenRulesArePresent(analyzeRequest, kieWrapperComponentRules, document, addedFileAttributes, entityLog);
|
||||
computeComponentsWhenRulesArePresent(analyzeRequest, kieWrapperComponentRules, document, addedFileAttributes, entityLog, context);
|
||||
|
||||
long duration = System.currentTimeMillis() - startTime;
|
||||
|
||||
@ -305,7 +319,8 @@ public class AnalyzeService {
|
||||
KieWrapper kieWrapperComponentRules,
|
||||
Document document,
|
||||
Set<FileAttribute> addedFileAttributes,
|
||||
EntityLog entityLog) {
|
||||
EntityLog entityLog,
|
||||
Context context) {
|
||||
|
||||
if (!kieWrapperComponentRules.isPresent()) {
|
||||
return;
|
||||
@ -318,7 +333,8 @@ public class AnalyzeService {
|
||||
entityLog,
|
||||
document,
|
||||
addedFileAttributes,
|
||||
analyzeRequest.getComponentMappings());
|
||||
analyzeRequest.getComponentMappings(),
|
||||
context);
|
||||
|
||||
log.info("Finished component rule execution for file {} in dossier {}", analyzeRequest.getFileId(), analyzeRequest.getDossierId());
|
||||
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
package com.iqser.red.service.redaction.v1.server.service;
|
||||
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RuleLogEvent;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class WebSocketService {
|
||||
|
||||
private final SimpMessagingTemplate template;
|
||||
|
||||
public void sendLogEvent(RuleLogEvent ruleLogEvent) {
|
||||
|
||||
String destination = "/topic/" + ruleLogEvent.getTenantId() + "/rule-log-events";
|
||||
log.info("Sending message to url {}", destination);
|
||||
template.convertAndSend(destination, ruleLogEvent);
|
||||
}
|
||||
}
|
||||
@ -22,9 +22,12 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentMappingMetadata;
|
||||
import com.iqser.red.service.redaction.v1.server.RedactionServiceSettings;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Component;
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Entity;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.nodes.Document;
|
||||
import com.iqser.red.service.redaction.v1.server.service.WebSocketService;
|
||||
import com.iqser.red.service.redaction.v1.server.service.components.ComponentMappingMemoryCache;
|
||||
import com.iqser.red.service.redaction.v1.server.service.components.ComponentMappingService;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.ComponentComparator;
|
||||
@ -47,19 +50,24 @@ public class ComponentDroolsExecutionService {
|
||||
|
||||
RedactionServiceSettings settings;
|
||||
ComponentMappingMemoryCache componentMappingMemoryCache;
|
||||
WebSocketService webSocketService;
|
||||
|
||||
|
||||
public List<Component> executeRules(KieContainer kieContainer,
|
||||
EntityLog entityLog,
|
||||
Document document,
|
||||
Set<FileAttribute> fileAttributes,
|
||||
List<ComponentMappingMetadata> componentMappings) {
|
||||
List<ComponentMappingMetadata> componentMappings,
|
||||
Context context) {
|
||||
|
||||
KieSession kieSession = kieContainer.newKieSession();
|
||||
ComponentCreationService componentCreationService = new ComponentCreationService(kieSession);
|
||||
ComponentMappingService componentMappingService = new ComponentMappingService(componentMappingMemoryCache, componentMappings);
|
||||
RulesLogger logger = new RulesLogger(webSocketService);
|
||||
|
||||
kieSession.setGlobal("componentCreationService", componentCreationService);
|
||||
kieSession.setGlobal("logger", logger);
|
||||
kieSession.setGlobal("context", context);
|
||||
|
||||
if (hasComponentMappingServiceGlobal(kieSession)) {
|
||||
kieSession.setGlobal(COMPONENT_MAPPING_SERVICE_GLOBAL, componentMappingService);
|
||||
@ -73,9 +81,7 @@ public class ComponentDroolsExecutionService {
|
||||
entities.add(Entity.fromEntityLogEntry(entry, document, entry.getStartOffset(), entry.getEndOffset()));
|
||||
if (entry.getDuplicatedTextRanges() != null && !entry.getDuplicatedTextRanges().isEmpty()) {
|
||||
entry.getDuplicatedTextRanges()
|
||||
.forEach(duplicatedTextRange -> {
|
||||
entities.add(Entity.fromEntityLogEntry(entry, document, duplicatedTextRange.getStart(), duplicatedTextRange.getEnd()));
|
||||
});
|
||||
.forEach(duplicatedTextRange -> entities.add(Entity.fromEntityLogEntry(entry, document, duplicatedTextRange.getStart(), duplicatedTextRange.getEnd())));
|
||||
}
|
||||
return entities.stream();
|
||||
})
|
||||
@ -97,12 +103,14 @@ public class ComponentDroolsExecutionService {
|
||||
completableFuture.orTimeout(settings.getDroolsExecutionTimeoutSecs(document.getNumberOfPages()), TimeUnit.SECONDS)
|
||||
.get();
|
||||
} catch (ExecutionException e) {
|
||||
logger.error(context, "Exception during rule execution", e);
|
||||
kieSession.dispose();
|
||||
if (e.getCause() instanceof TimeoutException) {
|
||||
throw new DroolsTimeoutException(e, false, RuleFileType.COMPONENT);
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(context, "Exception during rule execution", e);
|
||||
kieSession.dispose();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@ -21,11 +21,14 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileTyp
|
||||
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.redaction.v1.server.RedactionServiceSettings;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.model.NerEntities;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.Dictionary;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.nodes.Document;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.nodes.SemanticNode;
|
||||
import com.iqser.red.service.redaction.v1.server.service.ManualChangesApplicationService;
|
||||
import com.iqser.red.service.redaction.v1.server.service.WebSocketService;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.EntityCreationService;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.EntityEnrichmentService;
|
||||
import com.iqser.red.service.redaction.v1.server.utils.exception.DroolsTimeoutException;
|
||||
@ -48,6 +51,7 @@ public class EntityDroolsExecutionService {
|
||||
ObservationRegistry observationRegistry;
|
||||
ManualChangesApplicationService manualChangesApplicationService;
|
||||
RedactionServiceSettings settings;
|
||||
WebSocketService webSocketService;
|
||||
|
||||
|
||||
@Timed("redactmanager_executeRules")
|
||||
@ -57,7 +61,8 @@ public class EntityDroolsExecutionService {
|
||||
Dictionary dictionary,
|
||||
List<FileAttribute> fileAttributes,
|
||||
ManualRedactions manualRedactions,
|
||||
NerEntities nerEntities) {
|
||||
NerEntities nerEntities,
|
||||
Context context) {
|
||||
|
||||
return executeRules(kieContainer,
|
||||
document,
|
||||
@ -66,7 +71,8 @@ public class EntityDroolsExecutionService {
|
||||
dictionary,
|
||||
fileAttributes,
|
||||
manualRedactions,
|
||||
nerEntities);
|
||||
nerEntities,
|
||||
context);
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +84,8 @@ public class EntityDroolsExecutionService {
|
||||
Dictionary dictionary,
|
||||
List<FileAttribute> fileAttributes,
|
||||
ManualRedactions manualRedactions,
|
||||
NerEntities nerEntities) {
|
||||
NerEntities nerEntities,
|
||||
Context context) {
|
||||
|
||||
addNumberOfPagesAndSectionsToAnalyseToTrace(document.getNumberOfPages(), sectionsToAnalyze.size());
|
||||
|
||||
@ -88,11 +95,14 @@ public class EntityDroolsExecutionService {
|
||||
.count() ? Collections.emptySet() : buildSet(sectionsToAnalyze, document);
|
||||
|
||||
EntityCreationService entityCreationService = new EntityCreationService(entityEnrichmentService, kieSession, nodesInKieSession);
|
||||
RulesLogger logger = new RulesLogger(webSocketService);
|
||||
|
||||
kieSession.setGlobal("document", document);
|
||||
kieSession.setGlobal("entityCreationService", entityCreationService);
|
||||
kieSession.setGlobal("manualChangesApplicationService", manualChangesApplicationService);
|
||||
kieSession.setGlobal("dictionary", dictionary);
|
||||
kieSession.setGlobal("logger", logger);
|
||||
kieSession.setGlobal("context", context);
|
||||
|
||||
kieSession.insert(document);
|
||||
|
||||
@ -132,12 +142,14 @@ public class EntityDroolsExecutionService {
|
||||
completableFuture.orTimeout(settings.getDroolsExecutionTimeoutSecs(document.getNumberOfPages()), TimeUnit.SECONDS)
|
||||
.get();
|
||||
} catch (ExecutionException e) {
|
||||
logger.error(context, "Exception during rule execution", e);
|
||||
kieSession.dispose();
|
||||
if (e.getCause() instanceof TimeoutException) {
|
||||
throw new DroolsTimeoutException(e, false, RuleFileType.ENTITY);
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(context, "Exception during rule execution", e);
|
||||
kieSession.dispose();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@ -16,6 +16,14 @@ project.version: 1.0-SNAPSHOT
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
fforesight:
|
||||
keycloak:
|
||||
enabled: true
|
||||
ignored-endpoints: [ '/redaction-gateway-v1', '/actuator/health/**',"/api/rules-logging/rulesocket","/api/rules-logging/rulesocket/**", '/redaction-gateway-v1/async/download/with-ott/**',
|
||||
'/internal-api/**', '/redaction-gateway-v1/docs/swagger-ui',
|
||||
'/redaction-gateway-v1/docs/**','/redaction-gateway-v1/docs',
|
||||
'/api', '/api/','/api/docs/**','/api/docs','/api/docs/swagger-ui' ]
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: redaction-service
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.IEntity;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.EntityType;
|
||||
@ -52,6 +54,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,8 +12,12 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Component;
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Entity;
|
||||
import com.iqser.red.service.redaction.v1.server.service.components.ComponentMappingService;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.ComponentCreationService;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Change;
|
||||
@ -26,6 +30,9 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribute;
|
||||
|
||||
global ComponentCreationService componentCreationService
|
||||
global ComponentMappingService componentMappingService
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
/**
|
||||
The imports, globals, queries and rules from this file are required for any component rule file.
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -59,6 +61,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
/**
|
||||
The imports, globals, queries and rules from this file are required for any entity rule file.
|
||||
|
||||
@ -59,6 +59,7 @@ import com.iqser.red.service.redaction.v1.server.utils.ResourceLoader;
|
||||
import com.iqser.red.service.redaction.v1.server.utils.TextNormalizationUtilities;
|
||||
import com.iqser.red.storage.commons.service.StorageService;
|
||||
import com.iqser.red.storage.commons.utils.FileSystemBackedStorageService;
|
||||
import com.knecon.fforesight.keycloakcommons.security.TenantAuthenticationManagerResolver;
|
||||
import com.knecon.fforesight.mongo.database.commons.liquibase.TenantMongoLiquibaseExecutor;
|
||||
import com.knecon.fforesight.mongo.database.commons.service.MongoConnectionProvider;
|
||||
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingFinishedEvent;
|
||||
@ -191,6 +192,9 @@ public abstract class AbstractRedactionIntegrationTest {
|
||||
@MockBean
|
||||
protected DictionaryClient dictionaryClient;
|
||||
|
||||
@MockBean
|
||||
protected TenantAuthenticationManagerResolver tenantAuthenticationManagerResolver;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
|
||||
@ -15,6 +15,7 @@ import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.kie.api.runtime.KieContainer;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@ -38,6 +39,7 @@ import com.iqser.red.service.redaction.v1.server.model.dictionary.DictionaryVers
|
||||
import com.iqser.red.service.redaction.v1.server.service.DictionaryService;
|
||||
import com.iqser.red.storage.commons.service.StorageService;
|
||||
import com.iqser.red.storage.commons.utils.FileSystemBackedStorageService;
|
||||
import com.knecon.fforesight.keycloakcommons.security.TenantAuthenticationManagerResolver;
|
||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||
import com.knecon.fforesight.tenantcommons.TenantsClient;
|
||||
|
||||
@ -55,6 +57,9 @@ public class DictionaryServiceTest {
|
||||
@MockBean
|
||||
protected KieContainer kieContainer;
|
||||
|
||||
@MockBean
|
||||
protected TenantAuthenticationManagerResolver tenantAuthenticationManagerResolver;
|
||||
|
||||
@MockBean
|
||||
protected DictionaryClient dictionaryClient;
|
||||
|
||||
|
||||
@ -87,6 +87,7 @@ import com.iqser.red.service.redaction.v1.server.utils.TextNormalizationUtilitie
|
||||
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.keycloakcommons.security.TenantAuthenticationManagerResolver;
|
||||
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingFinishedEvent;
|
||||
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingType;
|
||||
import com.knecon.fforesight.service.layoutparser.processor.LayoutParsingPipeline;
|
||||
@ -253,6 +254,8 @@ public class RulesTest {
|
||||
private LegalBasisClient legalBasisClient;
|
||||
@MockBean
|
||||
private TenantsClient tenantsClient;
|
||||
@MockBean
|
||||
private TenantAuthenticationManagerResolver tenantAuthenticationManagerResolver;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
|
||||
@ -34,6 +34,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileTyp
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.Type;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.NerEntities;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.Dictionary;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.DictionaryModel;
|
||||
@ -154,12 +155,14 @@ public class DocumentPerformanceIntegrationTest extends BuildDocumentIntegration
|
||||
System.out.printf("Inserting entities into the graph took %d ms\n", System.currentTimeMillis() - graphInsertionStart);
|
||||
|
||||
long droolsStart = System.currentTimeMillis();
|
||||
Context context = new Context("fileId", "dossierId", "dossierTemplateId", 1, 1, "redaction");
|
||||
List<FileAttribute> fileAttributes = entityDroolsExecutionService.executeRules(kieContainer,
|
||||
document,
|
||||
dictionary,
|
||||
Collections.emptyList(),
|
||||
new ManualRedactions(),
|
||||
new NerEntities());
|
||||
new NerEntities(),
|
||||
context);
|
||||
System.out.printf("Firing rules took %d ms\n", System.currentTimeMillis() - droolsStart);
|
||||
|
||||
System.out.printf("Total time %d ms\n", System.currentTimeMillis() - dictionarySearchStart);
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
package com.iqser.red.service.redaction.v1.server.logger;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.drools.io.ClassPathResource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.kie.api.KieServices;
|
||||
import org.kie.api.builder.KieBuilder;
|
||||
import org.kie.api.builder.KieFileSystem;
|
||||
import org.kie.api.builder.ReleaseId;
|
||||
import org.kie.api.runtime.KieContainer;
|
||||
import org.kie.api.runtime.KieSession;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.service.WebSocketService;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class RulesLoggerTest {
|
||||
|
||||
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
|
||||
private final PrintStream originalOut = System.out;
|
||||
|
||||
@Mock
|
||||
private WebSocketService webSocketService;
|
||||
|
||||
@InjectMocks
|
||||
private RulesLogger logger;
|
||||
|
||||
|
||||
@Test
|
||||
void testRulesLogging() {
|
||||
|
||||
System.setOut(new PrintStream(outContent));
|
||||
RulesLogger logger = new RulesLogger(webSocketService);
|
||||
|
||||
KieServices ks = KieServices.Factory.get();
|
||||
KieFileSystem kfs = ks.newKieFileSystem();
|
||||
|
||||
kfs.write(new ClassPathResource("logs/rules_logging.drl"));
|
||||
|
||||
KieBuilder kieBuilder = ks.newKieBuilder(kfs).buildAll();
|
||||
ReleaseId releaseId = kieBuilder.getKieModule().getReleaseId();
|
||||
KieContainer kContainer = ks.newKieContainer(releaseId);
|
||||
KieSession kSession = kContainer.newKieSession();
|
||||
|
||||
Context context = new Context("fileId", "dossierId", "dossierTemplateId", 1, 1, "redaction");
|
||||
kSession.setGlobal("logger", logger);
|
||||
kSession.setGlobal("context", context);
|
||||
|
||||
try {
|
||||
kSession.fireAllRules();
|
||||
} catch (Exception e) {
|
||||
logger.error(context, "Exception during rule execution", e);
|
||||
} finally {
|
||||
kSession.dispose();
|
||||
}
|
||||
|
||||
System.setOut(originalOut);
|
||||
System.out.println(outContent);
|
||||
ArgumentCaptor<RuleLogEvent> argument = ArgumentCaptor.forClass(RuleLogEvent.class);
|
||||
verify(webSocketService, times(3)).sendLogEvent(argument.capture());
|
||||
assertEquals(argument.getAllValues().get(0).getLogLevel(), LogLevel.INFO);
|
||||
assertEquals(argument.getAllValues().get(0).getRuleVersion(), 1);
|
||||
assertEquals(argument.getAllValues().get(0).getTenantId(), "redaction");
|
||||
assertEquals(argument.getAllValues().get(0).getFileId(), "fileId");
|
||||
assertEquals(argument.getAllValues().get(0).getDossierId(), "dossierId");
|
||||
assertEquals(argument.getAllValues().get(0).getAnalysisNumber(), 1);
|
||||
assertEquals(argument.getAllValues().get(0).getDossierTemplateId(), "dossierTemplateId");
|
||||
assertEquals(argument.getAllValues().get(0).getMessage(), "This is a test log placeholder");
|
||||
assertEquals(argument.getAllValues().get(1).getLogLevel(), LogLevel.WARN);
|
||||
assertEquals(argument.getAllValues().get(1).getMessage(), "This is a warning log with multiple placeholders p1 p2 p3");
|
||||
assertEquals(argument.getAllValues().get(2).getLogLevel(), LogLevel.ERROR);
|
||||
assertEquals(argument.getAllValues().get(2).getMessage(), "Exception during rule execution Exception: Exception executing consequence for rule \"LOG.0.2: Test log error\" in drools: java.lang.NullPointerException: Cannot invoke \"String.toString()\" because \"result\" is null");
|
||||
}
|
||||
|
||||
}
|
||||
@ -56,6 +56,7 @@ import com.iqser.red.service.redaction.v1.server.utils.ExceptionProvider;
|
||||
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.keycloakcommons.security.TenantAuthenticationManagerResolver;
|
||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||
import com.knecon.fforesight.tenantcommons.TenantsClient;
|
||||
|
||||
@ -91,6 +92,9 @@ public class LiveDataIntegrationTest {
|
||||
@MockBean
|
||||
private LegalBasisClient legalBasisClient;
|
||||
|
||||
@MockBean
|
||||
protected TenantAuthenticationManagerResolver tenantAuthenticationManagerResolver;
|
||||
|
||||
@Autowired
|
||||
private ResourcePatternResolver resourcePatternResolver;
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.IEntity;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.EntityType;
|
||||
@ -52,6 +54,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,9 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Component;
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Entity;
|
||||
import com.iqser.red.service.redaction.v1.server.service.components.ComponentMappingService;
|
||||
@ -28,6 +31,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribu
|
||||
|
||||
global ComponentCreationService componentCreationService
|
||||
global ComponentMappingService componentMappingService
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,9 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Component;
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Entity;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.ComponentCreationService;
|
||||
@ -26,6 +29,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribute;
|
||||
|
||||
global ComponentCreationService componentCreationService
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,9 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Component;
|
||||
import com.iqser.red.service.redaction.v1.server.model.component.Entity;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.ComponentCreationService;
|
||||
@ -26,6 +29,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribute;
|
||||
|
||||
global ComponentCreationService componentCreationService
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package drools
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
|
||||
rule "LOG.0.0: Test log info"
|
||||
salience 1
|
||||
when
|
||||
eval(true)
|
||||
then
|
||||
logger.info(context, "This is a test log {}", "placeholder");
|
||||
end
|
||||
|
||||
rule "LOG.0.1: Test log warn"
|
||||
salience 1
|
||||
when
|
||||
eval(true)
|
||||
then
|
||||
logger.warn(context, "This is a warning log with multiple placeholders {} {} {}", "p1", "p2", "p3");
|
||||
end
|
||||
|
||||
rule "LOG.0.2: Test log error"
|
||||
when
|
||||
eval(true)
|
||||
then
|
||||
String result = null;
|
||||
result.toString();
|
||||
end
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.document.graph.*;
|
||||
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.*;
|
||||
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.Section;
|
||||
@ -55,6 +57,8 @@ global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global NerEntitiesAdapter nerEntitiesAdapter
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.*;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.*;
|
||||
@ -60,6 +62,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
|
||||
import com.iqser.red.service.redaction.v1.server.logger.Context;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.TextRange;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.IEntity;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.EntityType;
|
||||
@ -52,6 +54,8 @@ global Document document
|
||||
global EntityCreationService entityCreationService
|
||||
global ManualChangesApplicationService manualChangesApplicationService
|
||||
global Dictionary dictionary
|
||||
global RulesLogger logger
|
||||
global Context context
|
||||
|
||||
//------------------------------------ queries ------------------------------------
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user