Merge branch 'DM-285' into 'master'

DM-285: minor fixes to previous version

See merge request redactmanager/persistence-service!117
This commit is contained in:
Kilian Schüttler 2023-09-13 17:30:39 +02:00
commit 2fc912d414
26 changed files with 156 additions and 91 deletions

View File

@ -31,6 +31,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.Audit
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.RuleSyntaxErrorMessage;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequestModel;
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation; import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
@ -51,9 +52,10 @@ public class RulesController implements RulesResource {
@Override @Override
@PreAuthorize("hasAuthority('" + WRITE_RULES + "')") @PreAuthorize("hasAuthority('" + WRITE_RULES + "')")
public ResponseEntity<?> upload(@RequestBody RulesUploadRequest rules) { public ResponseEntity<?> upload(@RequestBody RulesUploadRequestModel rules) {
DroolsSyntaxValidation droolsSyntaxValidation = rulesValidationService.validateRules(rules.getRuleFileType(), rules.getRules()); RulesUploadRequest rulesUploadRequest = RulesUploadRequest.fromModel(rules);
DroolsSyntaxValidation droolsSyntaxValidation = rulesValidationService.validateRules(rulesUploadRequest.getRuleFileType(), rulesUploadRequest.getRules());
if (!droolsSyntaxValidation.isCompiled()) { if (!droolsSyntaxValidation.isCompiled()) {
var rulesSyntaxErrorMessages = droolsSyntaxValidation.getDroolsSyntaxErrorMessages() var rulesSyntaxErrorMessages = droolsSyntaxValidation.getDroolsSyntaxErrorMessages()
.stream() .stream()
@ -61,13 +63,13 @@ public class RulesController implements RulesResource {
.toList(); .toList();
return new ResponseEntity<>(rulesSyntaxErrorMessages, HttpStatus.BAD_REQUEST); return new ResponseEntity<>(rulesSyntaxErrorMessages, HttpStatus.BAD_REQUEST);
} }
rulesPersistenceService.setRules(rules.getRules(), rules.getDossierTemplateId(), rules.getRuleFileType()); rulesPersistenceService.setRules(rulesUploadRequest.getRules(), rulesUploadRequest.getDossierTemplateId(), rulesUploadRequest.getRuleFileType());
auditPersistenceService.audit(AuditRequest.builder() auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(rules.getDossierTemplateId()) .objectId(rulesUploadRequest.getDossierTemplateId())
.category(AuditCategory.DOSSIER_TEMPLATE.name()) .category(AuditCategory.DOSSIER_TEMPLATE.name())
.message("Rules have been updated") .message(String.format("%s Rules have been updated", rulesUploadRequest.getRuleFileType()))
.build()); .build());
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
@ -107,7 +109,7 @@ public class RulesController implements RulesResource {
@RequestPart(name = "file") MultipartFile file) { @RequestPart(name = "file") MultipartFile file) {
try { try {
return upload(new RulesUploadRequest(new String(file.getBytes(), StandardCharsets.UTF_8), dossierTemplateId, ruleFileType)); return upload(new RulesUploadRequestModel(new String(file.getBytes(), StandardCharsets.UTF_8), dossierTemplateId, ruleFileType));
} catch (IOException e) { } catch (IOException e) {
throw new FileUploadException("Could not upload file.", e); throw new FileUploadException("Could not upload file.", e);
} }

View File

@ -33,8 +33,7 @@ public class VersionsController implements VersionsResource {
var result = new HashMap<String, VersionsResponse>(); var result = new HashMap<String, VersionsResponse>();
dossierTemplateIds.forEach(rsId -> { dossierTemplateIds.forEach(rsId -> {
VersionsResponse response = new VersionsResponse(dictionaryPersistenceService.getVersion(rsId), VersionsResponse response = new VersionsResponse(dictionaryPersistenceService.getVersion(rsId), rulesPersistenceService.getVersion(rsId, RuleFileType.ENTITY));
rulesPersistenceService.getRules(rsId, RuleFileType.ENTITY).getVersion());
result.put(rsId, response); result.put(rsId, response);
}); });

View File

@ -14,7 +14,7 @@ import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequestModel;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
@ -42,7 +42,7 @@ public interface RulesResource {
@PostMapping(value = RULES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = RULES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.") @Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")}) @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
ResponseEntity<?> upload(@RequestBody RulesUploadRequest rules); ResponseEntity<?> upload(@RequestBody RulesUploadRequestModel rules);
@ResponseBody @ResponseBody

View File

@ -3,7 +3,6 @@ package com.iqser.red.service.persistence.v1.internal.api.controller;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.exception.RulesTimeoutDetectedException; import com.iqser.red.service.persistence.management.v1.processor.exception.RulesTimeoutDetectedException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.internal.resources.RulesResource; import com.iqser.red.service.persistence.service.v1.api.internal.resources.RulesResource;
@ -30,17 +29,13 @@ public class RulesInternalController implements RulesResource {
@Override @Override
public long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType) { public long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType) {
try { var rules = rulesPersistenceService.getRules(dossierTemplateId, ruleFileType);
var rules = rulesPersistenceService.getRules(dossierTemplateId, ruleFileType);
if (rules.isTimeoutDetected()) { if (rules.isTimeoutDetected()) {
throw new RulesTimeoutDetectedException(dossierTemplateId); throw new RulesTimeoutDetectedException(dossierTemplateId);
}
return rules.getVersion();
} catch (NotFoundException e) {
return 0;
} }
return rules.getVersion();
} }

View File

@ -128,8 +128,11 @@ public class DossierTemplateCloneService {
private void cloneRules(String dossierTemplateId, String clonedDossierTemplateId) { private void cloneRules(String dossierTemplateId, String clonedDossierTemplateId) {
for (RuleFileType ruleFileType : RuleFileType.values()) { for (RuleFileType ruleFileType : RuleFileType.values()) {
try {
rulesPersistenceService.setRules(rulesPersistenceService.getRules(dossierTemplateId, ruleFileType).getValue(), clonedDossierTemplateId, ruleFileType); rulesPersistenceService.setRules(rulesPersistenceService.getRules(dossierTemplateId, ruleFileType).getValue(), clonedDossierTemplateId, ruleFileType);
} catch (NotFoundException e) {
log.debug("No {} rules found, will not be cloned!", ruleFileType);
}
} }
} }

View File

@ -305,7 +305,9 @@ public class DossierTemplateImportService {
// set rules // set rules
rulesPersistenceService.setRules(request.getRuleSet(), dossierTemplateId, RuleFileType.ENTITY); rulesPersistenceService.setRules(request.getRuleSet(), dossierTemplateId, RuleFileType.ENTITY);
rulesPersistenceService.setRules(request.getComponentRuleSet(), dossierTemplateId, RuleFileType.COMPONENT); if (request.getComponentRuleSet() != null) {
rulesPersistenceService.setRules(request.getComponentRuleSet(), dossierTemplateId, RuleFileType.COMPONENT);
}
existingDossierTemplate.setDossierTemplateStatus(DossierTemplateStatus.valueOf(dossierTemplatePersistenceService.computeDossierTemplateStatus(existingDossierTemplate) existingDossierTemplate.setDossierTemplateStatus(DossierTemplateStatus.valueOf(dossierTemplatePersistenceService.computeDossierTemplateStatus(existingDossierTemplate)
.name())); .name()));
@ -409,7 +411,9 @@ public class DossierTemplateImportService {
dossierTemplateEntity.setCreatedBy(request.getUserId()); dossierTemplateEntity.setCreatedBy(request.getUserId());
//set rules //set rules
rulesPersistenceService.setRules(request.getRuleSet(), dossierTemplateEntity.getId(), RuleFileType.ENTITY); rulesPersistenceService.setRules(request.getRuleSet(), dossierTemplateEntity.getId(), RuleFileType.ENTITY);
rulesPersistenceService.setRules(request.getComponentRuleSet(), dossierTemplateEntity.getId(), RuleFileType.COMPONENT); if (request.getComponentRuleSet() != null) {
rulesPersistenceService.setRules(request.getComponentRuleSet(), dossierTemplateEntity.getId(), RuleFileType.COMPONENT);
}
var loadedDossierTemplate = dossierTemplateRepository.save(dossierTemplateEntity); var loadedDossierTemplate = dossierTemplateRepository.save(dossierTemplateEntity);
loadedDossierTemplate.setDossierTemplateStatus(dossierTemplatePersistenceService.computeDossierTemplateStatus(loadedDossierTemplate)); loadedDossierTemplate.setDossierTemplateStatus(dossierTemplatePersistenceService.computeDossierTemplateStatus(loadedDossierTemplate));

View File

@ -435,6 +435,7 @@ public class FileStatusService {
analyzeResult.getNumberOfPages(), analyzeResult.getNumberOfPages(),
analyzeResult.getDictionaryVersion(), analyzeResult.getDictionaryVersion(),
analyzeResult.getRulesVersion(), analyzeResult.getRulesVersion(),
analyzeResult.getComponentRulesVersion(),
analyzeResult.getLegalBasisVersion(), analyzeResult.getLegalBasisVersion(),
analyzeResult.getDuration(), analyzeResult.getDuration(),
analyzeResult.getDossierDictionaryVersion(), analyzeResult.getDossierDictionaryVersion(),

View File

@ -152,8 +152,8 @@ public class ReanalysisRequiredStatusService {
var versions = new HashMap<VersionType, Long>(); var versions = new HashMap<VersionType, Long>();
versions.put(RULES, rulesPersistenceService.getRules(dossierTemplateId, RuleFileType.ENTITY).getVersion()); versions.put(RULES, rulesPersistenceService.getVersion(dossierTemplateId, RuleFileType.ENTITY));
versions.put(COMPONENT_RULES, rulesPersistenceService.getRules(dossierTemplateId, RuleFileType.COMPONENT).getVersion()); versions.put(COMPONENT_RULES, rulesPersistenceService.getVersion(dossierTemplateId, RuleFileType.COMPONENT));
versions.put(DICTIONARY, dictionaryPersistenceService.getVersion(dossierTemplateId)); versions.put(DICTIONARY, dictionaryPersistenceService.getVersion(dossierTemplateId));
versions.put(LEGAL_BASIS, legalBasisMappingPersistenceService.getVersion(dossierTemplateId)); versions.put(LEGAL_BASIS, legalBasisMappingPersistenceService.getVersion(dossierTemplateId));

View File

@ -177,10 +177,14 @@ public class DossierTemplateExportService {
objectMapper.writeValueAsBytes(ruleSet.getValue()))); objectMapper.writeValueAsBytes(ruleSet.getValue())));
// add component rule set // add component rule set
var componentRuleSet = rulesPersistenceService.getRules(dossierTemplateId, RuleFileType.COMPONENT); try {
fileSystemBackedArchiver.addEntries(new FileSystemBackedArchiver.ArchiveModel(null, var componentRuleSet = rulesPersistenceService.getRules(dossierTemplateId, RuleFileType.COMPONENT);
getFilename(ExportFilename.COMPONENT_RULES, TXT_EXT), fileSystemBackedArchiver.addEntries(new FileSystemBackedArchiver.ArchiveModel(null,
objectMapper.writeValueAsBytes(componentRuleSet.getValue()))); getFilename(ExportFilename.COMPONENT_RULES, TXT_EXT),
objectMapper.writeValueAsBytes(componentRuleSet.getValue())));
} catch (NotFoundException e) {
log.debug("No component rules present.");
}
//N files with the related report templates //N files with the related report templates
var reportTemplateList = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplate.getId()); var reportTemplateList = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplate.getId());

View File

@ -123,7 +123,6 @@ public class ManualRedactionDictionaryUpdateHandler {
removeFromDictionary(entry.getTypeId(), entry.getValue(), dossierId, fileId, dictionaryEntryType); removeFromDictionary(entry.getTypeId(), entry.getValue(), dossierId, fileId, dictionaryEntryType);
}); });
} else { } else {
removeFromDictionary(dossierDictionaryTypeId, manualRequestWithRemoveFromDictionary.getValue(), dossierId, fileId, dictionaryEntryType); removeFromDictionary(dossierDictionaryTypeId, manualRequestWithRemoveFromDictionary.getValue(), dossierId, fileId, dictionaryEntryType);
typeIdsOfModifiedDictionaries.add(dossierDictionaryTypeId); typeIdsOfModifiedDictionaries.add(dossierDictionaryTypeId);
} }

View File

@ -112,7 +112,6 @@ public class ManualRedactionService {
var manualRedactions = manualRedactionProviderService.getManualRedactions(fileId); var manualRedactions = manualRedactionProviderService.getManualRedactions(fileId);
//validate removing from dossier template dictionary //validate removing from dossier template dictionary
for (RemoveRedactionRequest removeRedactionRequest : removeRedactionRequests) { for (RemoveRedactionRequest removeRedactionRequest : removeRedactionRequests) {
manualRedactionDictionaryUpdateHandler.validateDictionariesForDelete(removeRedactionRequest, manualRedactionDictionaryUpdateHandler.validateDictionariesForDelete(removeRedactionRequest,
removeRedactionRequest.getTypeToRemove(), removeRedactionRequest.getTypeToRemove(),
@ -368,7 +367,7 @@ public class ManualRedactionService {
if (manualRedactions.getLegalBasisChanges() != null) { if (manualRedactions.getLegalBasisChanges() != null) {
manualRedactions.getLegalBasisChanges().forEach(e -> { manualRedactions.getLegalBasisChanges().forEach(e -> {
if (!e.getStatus().equals(AnnotationStatus.REQUESTED) && e.getProcessedDate() == null) { if (!e.getStatus().equals(AnnotationStatus.REQUESTED) && e.getProcessedDate() == null) {
resizeRedactionPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId()); legalBasisChangePersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
} }
}); });
} }

View File

@ -8,6 +8,7 @@ import java.util.UUID;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
@ -28,6 +29,9 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor @RequiredArgsConstructor
public class DossierTemplatePersistenceService { public class DossierTemplatePersistenceService {
@Value("${application.type}")
private String applicationType;
public static final String DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE = "DossierTemplate with Id %s not found."; public static final String DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE = "DossierTemplate with Id %s not found.";
private final DossierTemplateRepository dossierTemplateRepository; private final DossierTemplateRepository dossierTemplateRepository;
@ -69,7 +73,6 @@ public class DossierTemplatePersistenceService {
dossierTemplate.setDateAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); dossierTemplate.setDateAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
dossierTemplate.setCreatedBy(createOrUpdateDossierRequest.getRequestingUser()); dossierTemplate.setCreatedBy(createOrUpdateDossierRequest.getRequestingUser());
rulesPersistenceService.setRules(RulesPersistenceService.DEFAULT_RULES, dossierTemplate.getId(), RuleFileType.ENTITY); rulesPersistenceService.setRules(RulesPersistenceService.DEFAULT_RULES, dossierTemplate.getId(), RuleFileType.ENTITY);
rulesPersistenceService.setRules(RulesPersistenceService.DEFAULT_RULES, dossierTemplate.getId(), RuleFileType.COMPONENT);
var loadedDossierTemplate = dossierTemplateRepository.save(dossierTemplate); var loadedDossierTemplate = dossierTemplateRepository.save(dossierTemplate);
loadedDossierTemplate.setDossierTemplateStatus(computeDossierTemplateStatus(loadedDossierTemplate)); loadedDossierTemplate.setDossierTemplateStatus(computeDossierTemplateStatus(loadedDossierTemplate));
@ -102,12 +105,18 @@ public class DossierTemplatePersistenceService {
if (legalBasis == null || legalBasis.isEmpty()) { if (legalBasis == null || legalBasis.isEmpty()) {
return DossierTemplateStatus.INCOMPLETE; return DossierTemplateStatus.INCOMPLETE;
} }
try {
var rules = rulesPersistenceService.getRules(dossierTemplate.getId(), RuleFileType.ENTITY); rulesPersistenceService.getRules(dossierTemplate.getId(), RuleFileType.ENTITY);
var componentRules = rulesPersistenceService.getRules(dossierTemplate.getId(), RuleFileType.COMPONENT); } catch (NotFoundException e) {
if (rules == null || componentRules == null) {
return DossierTemplateStatus.INCOMPLETE; return DossierTemplateStatus.INCOMPLETE;
} }
if (applicationType.equals("DocuMine")) {
try {
rulesPersistenceService.getRules(dossierTemplate.getId(), RuleFileType.COMPONENT);
} catch (NotFoundException e) {
return DossierTemplateStatus.INCOMPLETE;
}
}
var now = OffsetDateTime.now(); var now = OffsetDateTime.now();
boolean isNotInRange = !now.isAfter(dossierTemplate.getValidFrom() != null ? dossierTemplate.getValidFrom() : OffsetDateTime.MIN) || !now.isBefore(dossierTemplate.getValidTo() != null ? dossierTemplate.getValidTo() : OffsetDateTime.MAX); boolean isNotInRange = !now.isAfter(dossierTemplate.getValidFrom() != null ? dossierTemplate.getValidFrom() : OffsetDateTime.MIN) || !now.isBefore(dossierTemplate.getValidTo() != null ? dossierTemplate.getValidTo() : OffsetDateTime.MAX);

View File

@ -104,6 +104,7 @@ public class FileStatusPersistenceService {
int numberOfPages, int numberOfPages,
long dictionaryVersion, long dictionaryVersion,
long rulesVersion, long rulesVersion,
long componentRulesVersion,
long legalBasisVersion, long legalBasisVersion,
long duration, long duration,
long dossierDictionaryVersion, long dossierDictionaryVersion,
@ -118,6 +119,7 @@ public class FileStatusPersistenceService {
ProcessingStatus.PROCESSED, ProcessingStatus.PROCESSED,
dictionaryVersion, dictionaryVersion,
rulesVersion, rulesVersion,
componentRulesVersion,
legalBasisVersion, legalBasisVersion,
duration, duration,
dossierDictionaryVersion, dossierDictionaryVersion,

View File

@ -8,6 +8,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@Service @Service
@ -100,37 +101,26 @@ public class RulesPersistenceService {
end end
// --------------------------------------- Your rules below this line -------------------------------------------------- // --------------------------------------- Your rules below this line --------------------------------------------------
"""; """;
private final RuleSetRepository ruleSetRepository; private final RuleSetRepository ruleSetRepository;
@Transactional @Transactional(Transactional.TxType.REQUIRES_NEW)
public RuleSetEntity getRules(String dossierTemplateId, RuleFileType ruleFileType) { public RuleSetEntity getRules(String dossierTemplateId, RuleFileType ruleFileType) {
if (ruleFileType.equals(RuleFileType.ENTITY)) {
return ruleSetRepository.findByDossierTemplateIdAndRuleFileType(dossierTemplateId, ruleFileType.name())
.orElseGet(() -> createAndGetDefaultRuleSet(dossierTemplateId, ruleFileType));
}
return ruleSetRepository.findByDossierTemplateIdAndRuleFileType(dossierTemplateId, ruleFileType.name()) return ruleSetRepository.findByDossierTemplateIdAndRuleFileType(dossierTemplateId, ruleFileType.name())
.orElseThrow(() -> new NotFoundException(String.format("No rule file of type %s found for dossierTemplateId %s", ruleFileType, dossierTemplateId))); .orElseThrow(() -> new NotFoundException(String.format("No rule file of type %s found for dossierTemplateId %s", ruleFileType, dossierTemplateId)));
} }
private RuleSetEntity createAndGetDefaultRuleSet(String dossierTemplateId, RuleFileType ruleFileType) { public long getVersion(String dossierTemplateId, RuleFileType ruleFileType) {
RuleSetEntity ruleSet = new RuleSetEntity(); return ruleSetRepository.findVersionByDossierTemplateIdAndRuleFileType(dossierTemplateId, ruleFileType.name()).orElse(-1L);
ruleSet.setDossierTemplateId(dossierTemplateId);
ruleSet.setRuleFileType(ruleFileType.name());
ruleSet.setValue(DEFAULT_RULES);
ruleSet.setVersion(1);
ruleSet.setTimeoutDetected(false);
return ruleSetRepository.save(ruleSet);
} }
@Transactional @Transactional
public void setRules(String rules, String dossierTemplateId, RuleFileType ruleFileType) { public void setRules(@NonNull String rules, String dossierTemplateId, RuleFileType ruleFileType) {
ruleSetRepository.findByDossierTemplateIdAndRuleFileType(dossierTemplateId, ruleFileType.name()).ifPresentOrElse(ruleSet -> { ruleSetRepository.findByDossierTemplateIdAndRuleFileType(dossierTemplateId, ruleFileType.name()).ifPresentOrElse(ruleSet -> {
ruleSet.setDossierTemplateId(dossierTemplateId); ruleSet.setDossierTemplateId(dossierTemplateId);

View File

@ -84,4 +84,10 @@ public class LegalBasisChangePersistenceService {
} }
public void markAsProcessed(String annotationId, String fileId) {
legalBasisChangeRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
} }

View File

@ -3,8 +3,6 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
@ -16,6 +14,8 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
import jakarta.transaction.Transactional;
public interface FileRepository extends JpaRepository<FileEntity, String> { public interface FileRepository extends JpaRepository<FileEntity, String> {
boolean existsByDossierIdAndLastUpdatedIsAfter(String dossierId, OffsetDateTime since); boolean existsByDossierIdAndLastUpdatedIsAfter(String dossierId, OffsetDateTime since);
@ -40,12 +40,13 @@ public interface FileRepository extends JpaRepository<FileEntity, String> {
@Modifying @Modifying
@Query("update FileEntity f set f.numberOfPages = :numberOfPages, f.processingStatus = :processingStatus, " + "f.dictionaryVersion = :dictionaryVersion, f.rulesVersion = :rulesVersion, f.legalBasisVersion = :legalBasisVersion, " + "f.analysisDuration = :analysisDuration, f.dossierDictionaryVersion = :dossierDictionaryVersion, " + "f.analysisVersion = :analysisVersion, f.numberOfAnalyses = :analysisNumber, f.lastUpdated = :lastUpdated, " + "f.lastProcessed = :lastProcessed, f.processingErrorCounter = :processingErrorCounter " + "where f.id = :fileId") @Query("update FileEntity f set f.numberOfPages = :numberOfPages, f.processingStatus = :processingStatus, " + "f.dictionaryVersion = :dictionaryVersion, f.rulesVersion = :rulesVersion, f.componentRulesVersion = :componentRulesVersion, f.legalBasisVersion = :legalBasisVersion, " + "f.analysisDuration = :analysisDuration, f.dossierDictionaryVersion = :dossierDictionaryVersion, " + "f.analysisVersion = :analysisVersion, f.numberOfAnalyses = :analysisNumber, f.lastUpdated = :lastUpdated, " + "f.lastProcessed = :lastProcessed, f.processingErrorCounter = :processingErrorCounter " + "where f.id = :fileId")
void updateProcessingStatus(String fileId, void updateProcessingStatus(String fileId,
int numberOfPages, int numberOfPages,
ProcessingStatus processingStatus, ProcessingStatus processingStatus,
long dictionaryVersion, long dictionaryVersion,
long rulesVersion, long rulesVersion,
long componentRulesVersion,
long legalBasisVersion, long legalBasisVersion,
long analysisDuration, long analysisDuration,
long dossierDictionaryVersion, long dossierDictionaryVersion,
@ -80,6 +81,7 @@ public interface FileRepository extends JpaRepository<FileEntity, String> {
@Query("update FileEntity f set f.processingStatus = :processingStatus, f.lastUpdated = :lastUpdated, f.processingErrorCounter = :processingErrorCounter " + "where f.id = :fileId") @Query("update FileEntity f set f.processingStatus = :processingStatus, f.lastUpdated = :lastUpdated, f.processingErrorCounter = :processingErrorCounter " + "where f.id = :fileId")
void updateProcessingStatus(String fileId, ProcessingStatus processingStatus, OffsetDateTime lastUpdated, int processingErrorCounter); void updateProcessingStatus(String fileId, ProcessingStatus processingStatus, OffsetDateTime lastUpdated, int processingErrorCounter);
@Modifying @Modifying
@Query("update FileEntity f set f.errorCause = :cause, f.errorQueue = :queue, f.errorService = :service, f.errorTimestamp = :timestamp where f.id = :fileId") @Query("update FileEntity f set f.errorCause = :cause, f.errorQueue = :queue, f.errorService = :service, f.errorTimestamp = :timestamp where f.id = :fileId")
void updateStatusErrorInfo(String fileId, String cause, String queue, String service, OffsetDateTime timestamp); void updateStatusErrorInfo(String fileId, String cause, String queue, String service, OffsetDateTime timestamp);
@ -183,10 +185,7 @@ public interface FileRepository extends JpaRepository<FileEntity, String> {
void setLastManualChangeDate(String fileId, OffsetDateTime lastManualChangeDate, OffsetDateTime lastUpdated); void setLastManualChangeDate(String fileId, OffsetDateTime lastManualChangeDate, OffsetDateTime lastUpdated);
@Query("select f from FileEntity f join DossierEntity d on d.id = f.dossierId where f.excluded = false and f.workflowStatus <> 'APPROVED' and f.excludedFromAutomaticAnalysis = false " @Query("select f from FileEntity f join DossierEntity d on d.id = f.dossierId where f.excluded = false and f.workflowStatus <> 'APPROVED' and f.excludedFromAutomaticAnalysis = false " + " and ( f.processingStatus = 'PROCESSED' or f.processingStatus = 'ERROR' )" + " and d.softDeletedTime is null and d.hardDeletedTime is null and d.archivedTime is null " + " and f.deleted is null and f.hardDeletedTime is null and f.processingErrorCounter <= :maxRetries")
+ " and ( f.processingStatus = 'PROCESSED' or f.processingStatus = 'ERROR' )"
+ " and d.softDeletedTime is null and d.hardDeletedTime is null and d.archivedTime is null "
+ " and f.deleted is null and f.hardDeletedTime is null and f.processingErrorCounter <= :maxRetries")
List<FileEntity> getAllRelevantStatusesForReanalysisScheduler(int maxRetries); List<FileEntity> getAllRelevantStatusesForReanalysisScheduler(int maxRetries);

View File

@ -18,4 +18,8 @@ public interface RuleSetRepository extends JpaRepository<RuleSetEntity, RuleSetE
Optional<RuleSetEntity> findByDossierTemplateIdAndRuleFileType(String dossierTemplateId, String ruleFileType); Optional<RuleSetEntity> findByDossierTemplateIdAndRuleFileType(String dossierTemplateId, String ruleFileType);
@Query("select r.version from RuleSetEntity r where r.dossierTemplateId = :dossierTemplateId and r.ruleFileType = :ruleFileType")
Optional<Long> findVersionByDossierTemplateIdAndRuleFileType(String dossierTemplateId, String ruleFileType);
} }

View File

@ -31,4 +31,9 @@ public interface LegalBasisChangeRepository extends JpaRepository<ManualLegalBas
@Query("select mlbc from ManualLegalBasisChangeEntity mlbc where mlbc.id.fileId = :fileId and (:includeDeletions = true or mlbc.softDeletedTime is null)") @Query("select mlbc from ManualLegalBasisChangeEntity mlbc where mlbc.id.fileId = :fileId and (:includeDeletions = true or mlbc.softDeletedTime is null)")
List<ManualLegalBasisChangeEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions); List<ManualLegalBasisChangeEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions);
@Modifying
@Query("update ManualLegalBasisChangeEntity mlbc set mlbc.processedDate = :processedDate where mlbc.id = :annotationEntityId")
void markAsProcessed(AnnotationEntityId annotationEntityId, OffsetDateTime processedDate);
} }

View File

@ -160,4 +160,6 @@ databaseChangeLog:
- include: - include:
file: db/changelog/tenant/109-add-rules-timeout-detected-column.yaml file: db/changelog/tenant/109-add-rules-timeout-detected-column.yaml
- include: - include:
file: db/changelog/tenant/110-add-rules-file-type.yaml file: db/changelog/tenant/110-add-rules-file-type.yaml
- include:
file: db/changelog/tenant/111-make-rule-values-non-nullable.yaml

View File

@ -0,0 +1,8 @@
databaseChangeLog:
- changeSet:
id: make-rule-values-non-nullable
author: kilian
changes:
- addNotNullConstraint:
columnName: value
tableName: rule_set

View File

@ -15,10 +15,11 @@ import com.iqser.red.service.peristence.v1.server.integration.client.DossierTemp
import com.iqser.red.service.peristence.v1.server.integration.client.LegalBasisClient; import com.iqser.red.service.peristence.v1.server.integration.client.LegalBasisClient;
import com.iqser.red.service.peristence.v1.server.integration.client.RulesClient; import com.iqser.red.service.peristence.v1.server.integration.client.RulesClient;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.Colors; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.Colors;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.legalbasis.LegalBasis; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.legalbasis.LegalBasis;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequestModel;
@Service @Service
public class DossierTemplateTesterAndProvider { public class DossierTemplateTesterAndProvider {
@ -78,7 +79,7 @@ public class DossierTemplateTesterAndProvider {
assertThat(loadedTemplate).isEqualTo(result); assertThat(loadedTemplate).isEqualTo(result);
rulesClient.upload(new RulesUploadRequest("ABCD", loadedTemplate.getDossierTemplateId())); rulesClient.upload(new RulesUploadRequestModel("ABCD", loadedTemplate.getDossierTemplateId(), RuleFileType.ENTITY));
legalBasisClient.setLegalBasisMapping(List.of(new LegalBasis("name", "description", "reason")), loadedTemplate.getDossierTemplateId()); legalBasisClient.setLegalBasisMapping(List.of(new LegalBasis("name", "description", "reason")), loadedTemplate.getDossierTemplateId());
loadedTemplate = dossierTemplateClient.getDossierTemplate(result.getDossierTemplateId()); loadedTemplate = dossierTemplateClient.getDossierTemplate(result.getDossierTemplateId());

View File

@ -286,20 +286,20 @@ public class DossierTemplateStatsTest extends AbstractPersistenceServerServiceTe
for (int k = 0; k < 6; k++) { for (int k = 0; k < 6; k++) {
var fileId = fileTesterAndProvider.testAndProvideFileQuick(dossier, "file: " + k); var fileId = fileTesterAndProvider.testAndProvideFileQuick(dossier, "file: " + k);
if (k == 1){ if (k == 1) {
fileStatusPersistenceService.updateProcessingStatus(fileId, k, 0L, 0L, 0L, 0L, 0L, 1, 1); fileStatusPersistenceService.updateProcessingStatus(fileId, k, 0L, 0L, 0L, 0L, 0L, 0L, 1, 1);
reanalysisClient.excludePages(dossier.getId(), fileId, new PageExclusionRequest(List.of(new PageRange(k, k)))); reanalysisClient.excludePages(dossier.getId(), fileId, new PageExclusionRequest(List.of(new PageRange(k, k))));
} }
if (k ==2) { if (k == 2) {
fileManagementClient.deleteFile(dossier.getId(), fileId); fileManagementClient.deleteFile(dossier.getId(), fileId);
} }
if (k == 3){ if (k == 3) {
fileManagementClient.hardDeleteFiles(dossier.getId(), Set.of(fileId)); fileManagementClient.hardDeleteFiles(dossier.getId(), Set.of(fileId));
} }
if (k == 4){ if (k == 4) {
fileClient.setStatusUnderReview(dossier.getId(), fileId, userId); fileClient.setStatusUnderReview(dossier.getId(), fileId, userId);
} }
if (k == 5){ if (k == 5) {
fileClient.setStatusUnderApproval(dossier.getId(), fileId, userId); fileClient.setStatusUnderApproval(dossier.getId(), fileId, userId);
} }
} }

View File

@ -1,16 +1,18 @@
package com.iqser.red.service.peristence.v1.server.integration.tests; package com.iqser.red.service.peristence.v1.server.integration.tests;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.iqser.red.service.peristence.v1.server.integration.client.RulesClient; import com.iqser.red.service.peristence.v1.server.integration.client.RulesClient;
import com.iqser.red.service.peristence.v1.server.integration.client.VersionClient; import com.iqser.red.service.peristence.v1.server.integration.client.VersionClient;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTemplateTesterAndProvider; import com.iqser.red.service.peristence.v1.server.integration.service.DossierTemplateTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest; import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
import org.junit.jupiter.api.Test; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequestModel;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class RulesTest extends AbstractPersistenceServerServiceTest { public class RulesTest extends AbstractPersistenceServerServiceTest {
@ -29,13 +31,13 @@ public class RulesTest extends AbstractPersistenceServerServiceTest {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate(); var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
rulesClient.upload(new RulesUploadRequest("lorem ipsum", dossierTemplate.getId())); rulesClient.upload(new RulesUploadRequestModel("lorem ipsum", dossierTemplate.getId(), RuleFileType.ENTITY));
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId())) assertThat(versionClient.getVersions(List.of(dossierTemplate.getId()))
.get(dossierTemplate.getId()) .get(dossierTemplate.getId())
.getRulesVersion()).isEqualTo(3); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate(), damit es ACTIVE ist .getRulesVersion()).isEqualTo(3); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate(), damit es ACTIVE ist
assertThat(rulesClient.download(dossierTemplate.getId()).getRules()).isEqualTo("lorem ipsum"); assertThat(rulesClient.download(dossierTemplate.getId()).getRules()).isEqualTo("lorem ipsum");
rulesClient.upload(new RulesUploadRequest("lorem ipsum dolor sit amet", dossierTemplate.getId())); rulesClient.upload(new RulesUploadRequestModel("lorem ipsum dolor sit amet", dossierTemplate.getId(), RuleFileType.ENTITY));
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId())).get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(4); assertThat(versionClient.getVersions(List.of(dossierTemplate.getId())).get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(4);
assertThat(rulesClient.download(dossierTemplate.getId()).getRules()).isEqualTo("lorem ipsum dolor sit amet"); assertThat(rulesClient.download(dossierTemplate.getId()).getRules()).isEqualTo("lorem ipsum dolor sit amet");

View File

@ -25,6 +25,7 @@ public class AnalyzeResult {
private long dictionaryVersion; private long dictionaryVersion;
private long dossierDictionaryVersion; private long dossierDictionaryVersion;
private long rulesVersion; private long rulesVersion;
private long componentRulesVersion;
private long legalBasisVersion; private long legalBasisVersion;
private boolean wasReanalyzed; private boolean wasReanalyzed;

View File

@ -2,32 +2,34 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertem
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
import io.swagger.v3.oas.annotations.media.Schema; import lombok.AccessLevel;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
@Data @Data
@Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@Schema(description = "Object containing a string of Drools rules.") @FieldDefaults(level = AccessLevel.PRIVATE)
public class RulesUploadRequest { public class RulesUploadRequest {
public RulesUploadRequest(String rules, String dossierTemplateId) { public static RulesUploadRequest fromModel(RulesUploadRequestModel rulesUploadRequestModel) {
this.rules = rules; return RulesUploadRequest.builder()
this.dossierTemplateId = dossierTemplateId; .rules(rulesUploadRequestModel.getRules())
this.ruleFileType = RuleFileType.ENTITY; .dossierTemplateId(rulesUploadRequestModel.getDossierTemplateId())
.ruleFileType(rulesUploadRequestModel.getRuleFileType() != null ? rulesUploadRequestModel.getRuleFileType() : RuleFileType.ENTITY)
.build();
} }
@Schema(description = "The actual string of rules.") String rules;
private String rules;
@Schema(description = "The DossierTemplate Id for these rules") String dossierTemplateId;
private String dossierTemplateId;
@Schema(description = "The Rule file type of these rules", allowableValues = {"ENTITY", "COMPONENT"}) RuleFileType ruleFileType;
private RuleFileType ruleFileType;
} }

View File

@ -0,0 +1,28 @@
package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules;
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "Object containing a string of Drools rules.")
public class RulesUploadRequestModel {
@NonNull
@Schema(description = "The actual string of rules.")
private String rules;
@NonNull
@Schema(description = "The DossierTemplate Id for these rules")
private String dossierTemplateId;
@Schema(description = "The Rule file type of these rules", allowableValues = {"ENTITY", "COMPONENT"})
private RuleFileType ruleFileType = RuleFileType.ENTITY;
}