Merged master into current branch

This commit is contained in:
Timo Bejan 2022-01-31 09:26:07 +02:00
commit 7a72d04ccd
77 changed files with 1122 additions and 430 deletions

View File

@ -0,0 +1,25 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
import com.iqser.red.service.redaction.v1.model.Rectangle;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AddImportedAnnotationRequest {
private String annotationId;
private List<Rectangle> positions = new ArrayList<>();
private ImportedAnnotationStatus status;
private String userId;
private String comment;
}

View File

@ -13,19 +13,14 @@ import lombok.NoArgsConstructor;
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ManualResizeRedaction {
public class ImportedAnnotation {
private String annotationId;
private String fileId;
private String user;
private AnnotationStatus status;
private OffsetDateTime requestDate;
private OffsetDateTime processedDate;
private OffsetDateTime softDeletedTime;
private String value;
@Builder.Default
private List<Rectangle> positions = new ArrayList<>();
private String textBefore;
private String textAfter;
private ImportedAnnotationStatus status;
private String user;
private String comment;
private OffsetDateTime processedDate;
}

View File

@ -0,0 +1,8 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
public enum ImportedAnnotationStatus {
NEW,
APPROVED,
DECLINED,
ADDED
}

View File

@ -1,25 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ManualForceRedaction {
private String annotationId;
private String fileId;
private String user;
private AnnotationStatus status;
private String legalBasis;
private OffsetDateTime requestDate;
private OffsetDateTime processedDate;
private OffsetDateTime softDeletedTime;
}

View File

@ -1,24 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ManualImageRecategorization {
private String annotationId;
private String fileId;
private String user;
private AnnotationStatus status;
private String type;
private OffsetDateTime requestDate;
private OffsetDateTime processedDate;
private OffsetDateTime softDeletedTime;
}

View File

@ -1,27 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ManualLegalBasisChange {
private String annotationId;
private String fileId;
private String user;
private AnnotationStatus status;
private String section;
private String value;
private String legalBasis;
private OffsetDateTime requestDate;
private OffsetDateTime processedDate;
private OffsetDateTime softDeletedTime;
}

View File

@ -1,37 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ManualRedactionEntry {
private String annotationId;
private String fileId;
private String user;
private String type;
private String value;
private String reason;
private String legalBasis;
private AnnotationStatus status;
private String section;
private boolean rectangle;
private boolean addToDictionary;
private boolean addToDossierDictionary;
private OffsetDateTime requestDate;
private OffsetDateTime processedDate;
private OffsetDateTime softDeletedTime;
private List<Rectangle> positions = new ArrayList<>();
private String textBefore;
private String textAfter;
}

View File

@ -1,5 +1,6 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@ -0,0 +1,18 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UpdateImportedAnnotationStatusRequest {
private ImportedAnnotationStatus status;
private String user;
private String comment;
}

View File

@ -1,25 +1,22 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
package com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IdRemoval {
@AllArgsConstructor
public class BaseAnnotation {
private String annotationId;
private String fileId;
private String user;
private AnnotationStatus status;
private boolean removeFromDictionary;
private OffsetDateTime requestDate;
private OffsetDateTime processedDate;
private OffsetDateTime softDeletedTime;
}

View File

@ -0,0 +1,24 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@NoArgsConstructor
public class IdRemoval extends BaseAnnotation {
private boolean removeFromDictionary;
@Builder
public IdRemoval(String annotationId, String fileId,
String user, AnnotationStatus status,
OffsetDateTime requestDate, OffsetDateTime processedDate,
OffsetDateTime softDeletedTime, boolean removeFromDictionary) {
super(annotationId, fileId, user, status, requestDate, processedDate, softDeletedTime);
this.removeFromDictionary = removeFromDictionary;
}
}

View File

@ -0,0 +1,25 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@NoArgsConstructor
public class ManualForceRedaction extends BaseAnnotation {
private String legalBasis;
@Builder
public ManualForceRedaction(String annotationId, String fileId,
String user, AnnotationStatus status,
OffsetDateTime requestDate, OffsetDateTime processedDate,
OffsetDateTime softDeletedTime, String legalBasis) {
super(annotationId, fileId, user, status, requestDate, processedDate, softDeletedTime);
this.legalBasis = legalBasis;
}
}

View File

@ -0,0 +1,25 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@NoArgsConstructor
public class ManualImageRecategorization extends BaseAnnotation {
private String type;
@Builder
public ManualImageRecategorization(String annotationId, String fileId,
String user, AnnotationStatus status,
OffsetDateTime requestDate, OffsetDateTime processedDate,
OffsetDateTime softDeletedTime, String type) {
super(annotationId, fileId, user, status, requestDate, processedDate, softDeletedTime);
this.type = type;
}
}

View File

@ -0,0 +1,29 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
@Data
@NoArgsConstructor
public class ManualLegalBasisChange extends BaseAnnotation {
private String section;
private String value;
private String legalBasis;
@Builder
public ManualLegalBasisChange(String annotationId, String fileId,
String user, AnnotationStatus status,
OffsetDateTime requestDate, OffsetDateTime processedDate,
OffsetDateTime softDeletedTime, String legalBasis,
String section, String value) {
super(annotationId, fileId, user, status, requestDate, processedDate, softDeletedTime);
this.legalBasis = legalBasis;
this.section = section;
this.value = value;
}
}

View File

@ -0,0 +1,53 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Rectangle;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
public class ManualRedactionEntry extends BaseAnnotation {
private String type;
private String value;
private String reason;
private String legalBasis;
private String section;
private boolean rectangle;
private boolean addToDictionary;
private boolean addToDossierDictionary;
private List<Rectangle> positions = new ArrayList<>();
private String textBefore;
private String textAfter;
@Builder
public ManualRedactionEntry(String annotationId, String fileId,
String user, AnnotationStatus status,
OffsetDateTime requestDate, OffsetDateTime processedDate,
OffsetDateTime softDeletedTime, String value,
String textBefore, String textAfter,
boolean rectangle, boolean addToDictionary,
boolean addToDossierDictionary, String legalBasis,
String section, String reason, String type,
List<Rectangle> positions) {
super(annotationId, fileId, user, status, requestDate, processedDate, softDeletedTime);
this.textBefore = textBefore;
this.textAfter = textAfter;
this.value = value;
this.rectangle = rectangle;
this.addToDictionary = addToDictionary;
this.addToDossierDictionary = addToDossierDictionary;
this.legalBasis = legalBasis;
this.section = section;
this.reason = reason;
this.type = type;
this.positions = positions != null ? positions : new ArrayList<>();
}
}

View File

@ -0,0 +1,35 @@
package com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Rectangle;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
public class ManualResizeRedaction extends BaseAnnotation {
private String value;
private List<Rectangle> positions = new ArrayList<>();
private String textBefore;
private String textAfter;
@Builder
public ManualResizeRedaction(String annotationId, String fileId,
String user, AnnotationStatus status,
OffsetDateTime requestDate, OffsetDateTime processedDate,
OffsetDateTime softDeletedTime, String value,
String textBefore, String textAfter,
List<Rectangle> positions) {
super(annotationId, fileId, user, status, requestDate, processedDate, softDeletedTime);
this.textBefore = textBefore;
this.textAfter = textAfter;
this.value = value;
this.positions = positions != null ? positions : new ArrayList<>();
}
}

View File

@ -1,5 +1,5 @@
package com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate;
public enum DownloadFileType {
ORIGINAL, PREVIEW, REDACTED, ANNOTATED, FLATTEN
ORIGINAL, PREVIEW, REDACTED, ANNOTATED, FLATTEN, DELTA_PREVIEW
}

View File

@ -0,0 +1,46 @@
package com.iqser.red.service.persistence.service.v1.api.resources;
import java.util.List;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AddImportedAnnotationRequest;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotation;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.UpdateImportedAnnotationStatusRequest;
public interface ImportedAnnotationResource {
String IMPORTED_ANNOTATION_PATH = "/imported-annotation";
String FILE_ID_PARAM = "fileId";
String FILE_ID_PATH_PARAM = "/{" + FILE_ID_PARAM + "}";
String ANNOTATION_ID_PARAM = "annotationId";
String ANNOTATION_ID_PATH_PARAM = "/{" + ANNOTATION_ID_PARAM + "}";
@GetMapping(value = IMPORTED_ANNOTATION_PATH + FILE_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE)
List<ImportedAnnotation> getByFileId(@PathVariable(FILE_ID_PARAM) String fileId);
@DeleteMapping(value = IMPORTED_ANNOTATION_PATH + FILE_ID_PATH_PARAM + ANNOTATION_ID_PATH_PARAM)
void delete(@PathVariable(FILE_ID_PARAM) String fileId,
@PathVariable(ANNOTATION_ID_PARAM) String annotationId);
@PostMapping(value = IMPORTED_ANNOTATION_PATH + FILE_ID_PATH_PARAM, consumes = MediaType.APPLICATION_JSON_VALUE)
void insert(@PathVariable(FILE_ID_PARAM) String fileId,
@RequestBody AddImportedAnnotationRequest annotation);
@PostMapping(value = IMPORTED_ANNOTATION_PATH + FILE_ID_PATH_PARAM + ANNOTATION_ID_PATH_PARAM, consumes = MediaType.APPLICATION_JSON_VALUE)
void updateStatus(@PathVariable(FILE_ID_PARAM) String fileId,
@PathVariable(ANNOTATION_ID_PARAM) String annotationId,
@RequestBody UpdateImportedAnnotationStatusRequest UpdateImportedAnnotationRequest);
}

View File

@ -1,6 +1,7 @@
package com.iqser.red.service.persistence.service.v1.api.resources;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.*;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.*;
import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;

View File

@ -21,29 +21,31 @@ public interface ReanalysisResource {
@PostMapping(value = REANALYZE_PATH + DOSSIER_ID_PATH_PARAM)
void reanalyzeDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser,
@RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force);
@PostMapping(value = REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_PARAM)
void reanalyzeFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId,
@RequestBody Set<Integer> sectionsToReanalyse);
@PostMapping(value = REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + BULK_REST_PATH)
void reanalyzeFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set<String> fileIds,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser,
@RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force);
@PostMapping(value = OCR_REANALYZE_PATH + DOSSIER_ID_PATH_PARAM)
void ocrDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId);
void ocrDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser);
@PostMapping(value = OCR_REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_PARAM)
void ocrFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId, @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force);
void ocrFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser,
@RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force);
@PostMapping(value = OCR_REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + BULK_REST_PATH)
void ocrFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set<String> fileIds);
void ocrFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser,
@RequestBody Set<String> fileIds);
@PostMapping(value = REINDEX_PATH)

View File

@ -24,6 +24,8 @@ public interface StatusResource {
String EXCLUDED_STATUS_PARAM = "excluded";
String EXCLUDED_FROM_AUTOMATIC_ANALYSIS_PARAM = "excludedFromAutomaticAnalysis";
String APPROVER_ID_REQUEST_PARAM = "approverId";
String ASSIGNEE_ID_REQUEST_PARAM = "assigneeId";
String USER_ID_REQUEST_PARAM = "userId";
@ -74,6 +76,9 @@ public interface StatusResource {
@PostMapping(value = STATUS_PATH + "/toggle-analysis" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE)
void toggleExclusion(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestParam(EXCLUDED_STATUS_PARAM) boolean excluded);
@PostMapping(value = STATUS_PATH + "/toggle-automatic-analysis" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE)
void toggleAutomaticAnalysis(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestParam(EXCLUDED_STATUS_PARAM) boolean excludedFromAutomaticAnalysis);
@PostMapping(value = STATUS_PATH + "/exclude-pages" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE)
void excludePages(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set<Integer> pages);

View File

@ -0,0 +1,24 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.annotations;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import java.time.OffsetDateTime;
public interface IBaseAnnotation {
AnnotationEntityId getId();
AnnotationStatus getStatus();
OffsetDateTime getRequestDate();
void setRequestDate(OffsetDateTime requestedDate);
OffsetDateTime getProcessedDate();
void setProcessedDate(OffsetDateTime processedDate);
OffsetDateTime getSoftDeletedTime();
void setSoftDeletedTime(OffsetDateTime softDeletedTime);
}

View File

@ -16,7 +16,7 @@ import java.time.OffsetDateTime;
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IdRemovalEntity {
public class IdRemovalEntity implements IBaseAnnotation {
@EmbeddedId
private AnnotationEntityId id;

View File

@ -0,0 +1,54 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.annotations;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotationStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "imported_annotation")
public class ImportedAnnotationEntity {
@EmbeddedId
private AnnotationEntityId id;
@Column(name = "user_id")
private String user;
@Column
@Enumerated(EnumType.STRING)
private ImportedAnnotationStatus status;
@Column
private OffsetDateTime processedDate;
@ElementCollection
private List<RectangleEntity> positions = new ArrayList<>();
@ManyToOne
private FileEntity fileStatus;
@Column
private String comment;
}

View File

@ -16,7 +16,7 @@ import java.time.OffsetDateTime;
@NoArgsConstructor
@Entity
@Table(name = "manual_force_redaction")
public class ManualForceRedactionEntity {
public class ManualForceRedactionEntity implements IBaseAnnotation {
@EmbeddedId
private AnnotationEntityId id;

View File

@ -16,7 +16,7 @@ import java.time.OffsetDateTime;
@NoArgsConstructor
@Entity
@Table(name = "manual_image_recategorization")
public class ManualImageRecategorizationEntity {
public class ManualImageRecategorizationEntity implements IBaseAnnotation {
@EmbeddedId
private AnnotationEntityId id;

View File

@ -16,7 +16,7 @@ import java.time.OffsetDateTime;
@NoArgsConstructor
@Entity
@Table(name = "manual_legal_basis_change")
public class ManualLegalBasisChangeEntity {
public class ManualLegalBasisChangeEntity implements IBaseAnnotation {
@EmbeddedId
private AnnotationEntityId id;

View File

@ -18,7 +18,7 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "manual_redaction")
public class ManualRedactionEntryEntity {
public class ManualRedactionEntryEntity implements IBaseAnnotation {
@EmbeddedId
private AnnotationEntityId id;

View File

@ -1,33 +1,24 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.annotations;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "manual_resize_redaction")
public class ManualResizeRedactionEntity {
public class ManualResizeRedactionEntity implements IBaseAnnotation {
@EmbeddedId
private AnnotationEntityId id;

View File

@ -118,6 +118,9 @@ public class FileEntity {
@Column
private boolean excluded;
@Column
private boolean excludedFromAutomaticAnalysis;
@Column
private OffsetDateTime hardDeletedTime;

View File

@ -21,9 +21,10 @@ public class EntryPersistenceService {
private final TypeRepository typeRepository;
public void addEntry(String typeId, List<String> entries, long version) {
var type = typeRepository.getOne(typeId);
var type = typeRepository.getById(typeId);
var dictionaryEntries = entries.stream().map(word -> {
DictionaryEntryEntity entry = new DictionaryEntryEntity();

View File

@ -71,7 +71,7 @@ public class FileStatusPersistenceService {
if (isFileDeleted(fileId)) {
return;
}
fileRepository.updateFlags(fileId, OffsetDateTime.now(), hasRedactions, hasHints, hasImages, hasSuggestions, hasComments, hasUpdates);
fileRepository.updateFlags(fileId, OffsetDateTime.now(), hasRedactions, hasHints, hasImages, hasSuggestions, hasComments, hasUpdates);
}
@ -81,9 +81,8 @@ public class FileStatusPersistenceService {
if (isFileDeleted(fileId)) {
return;
}
fileRepository.updateWorkflowStatus(fileId, workflowStatus,
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
approval ? OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS) : null);
fileRepository.updateWorkflowStatus(fileId, workflowStatus, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
approval ? OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS) : null, approval);
}
@ -97,9 +96,9 @@ public class FileStatusPersistenceService {
if (processingStatus == ProcessingStatus.PROCESSED) {
// In case the file is updated to "processed", "lastProcessed" date should be updated to "now"
fileRepository.updateProcessingStatus(fileId, processingStatus, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
} else {
fileRepository.updateProcessingStatus(fileId, processingStatus, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
fileRepository.updateProcessingStatus(fileId, processingStatus, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
}
@ -112,7 +111,7 @@ public class FileStatusPersistenceService {
}
fileRepository.setUpdateStatusIndexingSuccessful(fileId, ProcessingStatus.PROCESSED,
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
@ -122,7 +121,7 @@ public class FileStatusPersistenceService {
if (isFileDeleted(fileId)) {
return;
}
fileRepository.updateLastOCRTime(fileId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), time);
fileRepository.updateLastOCRTime(fileId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), time);
}
@ -132,7 +131,7 @@ public class FileStatusPersistenceService {
if (isFileDeleted(fileId)) {
return;
}
fileRepository.updateHasComments(fileId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), hasComments);
fileRepository.updateHasComments(fileId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), hasComments);
}
@ -142,7 +141,7 @@ public class FileStatusPersistenceService {
if (isFileDeleted(fileId)) {
return;
}
fileRepository.updateLastManualRedaction(fileId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), date);
fileRepository.updateLastManualRedaction(fileId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), date);
}
@ -154,7 +153,7 @@ public class FileStatusPersistenceService {
return;
}
fileRepository.setUpdateLastManualRedactionAndHasSuggestions(fileId,
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), date, hasSuggestions);
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), date, hasSuggestions);
}
@ -171,7 +170,7 @@ public class FileStatusPersistenceService {
var fileAttributeEntities = convertFileAttributes(dossierId, file, fileAttributes);
file.setLastFileAttributeChange(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
file.setFileAttributes(fileAttributeEntities);
file.setFileAttributes(fileAttributeEntities);
}, () -> {
throw new NotFoundException("Unknown file=" + fileId);
});
@ -188,7 +187,7 @@ public class FileStatusPersistenceService {
file.setLastManualRedaction(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
file.setExcludedPages(excludedPages);
file.setExcludedPages(excludedPages);
}, () -> {
throw new NotFoundException("Unknown file=" + fileId);
});
@ -224,7 +223,7 @@ public class FileStatusPersistenceService {
public void softDelete(String fileId, OffsetDateTime softDeletedTime) {
int countUpdate = fileRepository.setSoftDelete(fileId, ProcessingStatus.DELETED,
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), softDeletedTime);
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), softDeletedTime);
if (countUpdate == 0) {
throw new NotFoundException("Unknown file=" + fileId);
}
@ -237,7 +236,7 @@ public class FileStatusPersistenceService {
int countUpdate = fileRepository.setHardDelete(fileId, ProcessingStatus.DELETED,
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
if (countUpdate == 0) {
throw new NotFoundException("Unknown file=" + fileId);
}
@ -279,7 +278,18 @@ public class FileStatusPersistenceService {
if (isFileDeleted(fileId)) {
return;
}
int countUpdate = fileRepository.toggleExclusion(fileId, excluded, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
int countUpdate = fileRepository.toggleExclusion(fileId, excluded, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
if (countUpdate == 0) {
throw new NotFoundException("Unknown file=" + fileId);
}
}
@Transactional
public void toggleAutomaticAnalysis(String fileId, boolean excludedFromAutomaticAnalysis) {
if (isFileDeleted(fileId)) {
return;
}
int countUpdate = fileRepository.toggleAutomaticAnalysis(fileId, excludedFromAutomaticAnalysis, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
if (countUpdate == 0) {
throw new NotFoundException("Unknown file=" + fileId);
}
@ -296,7 +306,7 @@ public class FileStatusPersistenceService {
int countUpdate = fileRepository.overwriteFile(fileId, filename, uploader, ProcessingStatus.FULLREPROCESS,
WorkflowStatus.NEW,
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
if (countUpdate == 0) {
throw new NotFoundException("Unknown file=" + fileId);
}

View File

@ -0,0 +1,108 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.stereotype.Service;
import com.iqser.red.service.pdftron.redaction.v1.api.model.Annotation;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ImportedAnnotationEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ImportedAnnotationRepository;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AddImportedAnnotationRequest;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotationStatus;
import com.iqser.red.service.redaction.v1.model.Rectangle;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class ImportedAnnotationPersistenceService {
private final ImportedAnnotationRepository importedAnnotationRepository;
@Transactional
public void insert(String fileId, AddImportedAnnotationRequest annotation) {
ImportedAnnotationEntity importedAnnotationEntity = new ImportedAnnotationEntity();
importedAnnotationEntity.setId(new AnnotationEntityId(annotation.getAnnotationId(), fileId));
importedAnnotationEntity.setStatus(annotation.getStatus() != null ? annotation.getStatus() : ImportedAnnotationStatus.NEW);
importedAnnotationEntity.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
importedAnnotationEntity.setPositions(convert(annotation.getPositions()));
importedAnnotationEntity.setUser(annotation.getUserId());
importedAnnotationEntity.setComment(annotation.getComment());
importedAnnotationRepository.save(importedAnnotationEntity);
}
@Transactional
public void insert(String fileId, List<Annotation> annotations) {
annotations.forEach(annotation -> insert(fileId, annotation, ImportedAnnotationStatus.NEW, null, null));
}
@Transactional
public void insert(String fileId, Annotation annotation, ImportedAnnotationStatus status, String userId,
String comment) {
ImportedAnnotationEntity importedAnnotationEntity = new ImportedAnnotationEntity();
importedAnnotationEntity.setId(new AnnotationEntityId(annotation.getId(), fileId));
importedAnnotationEntity.setStatus(status);
importedAnnotationEntity.setProcessedDate(status == ImportedAnnotationStatus.ADDED ? OffsetDateTime.now()
.truncatedTo(ChronoUnit.MILLIS) : null);
importedAnnotationEntity.setUser(userId);
importedAnnotationEntity.setComment(comment);
importedAnnotationEntity.setPositions(convert(annotation.getPositions()));
importedAnnotationRepository.save(importedAnnotationEntity);
}
@Transactional
public void updateStatus(String fileId, String annotationId, ImportedAnnotationStatus annotationStatus,
String comment, String userId) {
importedAnnotationRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now()
.truncatedTo(ChronoUnit.MILLIS), annotationStatus, comment, userId);
}
@Transactional
public void delete(String fileId, String annotationId) {
importedAnnotationRepository.deleteById(new AnnotationEntityId(annotationId, fileId));
}
public List<ImportedAnnotationEntity> findImportedAnnotations(String fileId) {
try {
return importedAnnotationRepository.findByIdFileId(fileId);
} catch (Exception e){
return new ArrayList<>();
}
}
private List<RectangleEntity> convert(List<Rectangle> positions) {
List<RectangleEntity> rectangleEntities = new ArrayList<>();
positions.forEach(p -> {
RectangleEntity re = new RectangleEntity();
re.setTopLeftX(p.getTopLeft().getX());
re.setTopLeftY(p.getTopLeft().getY());
re.setWidth(p.getWidth());
re.setHeight(p.getHeight());
re.setPage(p.getPage());
rectangleEntities.add(re);
});
return rectangleEntities;
}
}

View File

@ -1,4 +1,4 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
@ -16,9 +16,9 @@ import javax.transaction.Transactional;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@ -28,7 +28,7 @@ public class AddRedactionPersistenceService {
private final ManualRedactionRepository manualRedactionRepository;
public void insert(String fileId, String annotationId, AddRedactionRequest addRedactionRequest) {
public ManualRedactionEntryEntity insert(String fileId, String annotationId, AddRedactionRequest addRedactionRequest) {
ManualRedactionEntryEntity manualRedactionEntry = new ManualRedactionEntryEntity();
manualRedactionEntry.setId(new AnnotationEntityId(annotationId, fileId));
@ -37,13 +37,18 @@ public class AddRedactionPersistenceService {
manualRedactionEntry.setPositions(convert(addRedactionRequest.getPositions()));
manualRedactionEntry.setTypeId(addRedactionRequest.getTypeId());
manualRedactionRepository.save(manualRedactionEntry);
if (addRedactionRequest.getStatus() == AnnotationStatus.APPROVED) {
manualRedactionEntry.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
return manualRedactionRepository.save(manualRedactionEntry);
}
@Transactional
public void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter){
public void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter) {
manualRedactionRepository.updateSurroundingText(id, textBefore, textAfter);
}
@ -69,7 +74,7 @@ public class AddRedactionPersistenceService {
public Set<ManualRedactionEntryEntity> findAddRedactions(String fileId, boolean includeDeletions) {
return manualRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions).stream().collect(Collectors.toSet());
return new HashSet<>(manualRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions));
}
@ -94,19 +99,13 @@ public class AddRedactionPersistenceService {
@Transactional
public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) {
manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId),
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
annotationStatus);
manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
}
@Transactional
public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary
, boolean isAddOrRemoveFromDossierDictionary) {
public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary, boolean isAddOrRemoveFromDossierDictionary) {
manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId),
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
annotationStatus,
isAddOrRemoveFromDictionary, isAddOrRemoveFromDossierDictionary);
manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus, isAddOrRemoveFromDictionary, isAddOrRemoveFromDossierDictionary);
}
}

View File

@ -1,4 +1,4 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.CommentEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;

View File

@ -1,12 +1,13 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualForceRedaction;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@ -33,17 +34,12 @@ public class ForceRedactionPersistenceService {
manualForceRedaction.setId(new AnnotationEntityId(forceRedactionRequest.getAnnotationId(), fileId));
BeanUtils.copyProperties(forceRedactionRequest, manualForceRedaction);
manualForceRedaction.setRequestDate(OffsetDateTime.now());
if(manualForceRedaction.getStatus().equals(AnnotationStatus.APPROVED)) {
manualForceRedaction.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
forceRedactionRepository.save(manualForceRedaction);
}
@Transactional
public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) {
forceRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus,
OffsetDateTime.now());
forceRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
}
@ -72,7 +68,10 @@ public class ForceRedactionPersistenceService {
public Set<ManualForceRedactionEntity> findForceRedactions(String fileId, boolean includeDeletions) {
return forceRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions).stream().collect(Collectors.toSet());
return new HashSet<>(forceRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions));
}
public void markAsProcessed(ManualForceRedaction e) {
forceRedactionRepository.markAsProcessed(new AnnotationEntityId(e.getAnnotationId(), e.getFileId()), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
}

View File

@ -1,4 +1,4 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualImageRecategorizationEntity;
@ -6,12 +6,14 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.NotFo
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ImageRecategorizationRepository;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImageRecategorizationRequest;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualImageRecategorization;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
@Service
@ -34,8 +36,7 @@ public class ImageRecategorizationPersistenceService {
@Transactional
public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) {
imageRecategorizationRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus,
OffsetDateTime.now());
imageRecategorizationRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
}
@Transactional
@ -68,5 +69,7 @@ public class ImageRecategorizationPersistenceService {
}
public void markAsProcessed(ManualImageRecategorization e) {
imageRecategorizationRepository.markAsProcessed(new AnnotationEntityId(e.getAnnotationId(), e.getFileId()), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
}

View File

@ -1,4 +1,4 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualLegalBasisChangeEntity;
@ -12,6 +12,7 @@ import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Set;
import java.util.stream.Collectors;
@ -22,13 +23,18 @@ public class LegalBasisChangePersistenceService {
private final LegalBasisChangeRepository legalBasisChangeRepository;
public void insert(String fileId, LegalBasisChangeRequest legalBasisChangeRequest) {
public ManualLegalBasisChangeEntity insert(String fileId, LegalBasisChangeRequest legalBasisChangeRequest) {
ManualLegalBasisChangeEntity manualLegalBasisChange = new ManualLegalBasisChangeEntity();
manualLegalBasisChange.setId(new AnnotationEntityId(legalBasisChangeRequest.getAnnotationId(), fileId));
BeanUtils.copyProperties(legalBasisChangeRequest, manualLegalBasisChange);
manualLegalBasisChange.setRequestDate(OffsetDateTime.now());
legalBasisChangeRepository.save(manualLegalBasisChange);
manualLegalBasisChange.setRequestDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
if(legalBasisChangeRequest.getStatus() == AnnotationStatus.APPROVED) {
manualLegalBasisChange.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
return legalBasisChangeRepository.save(manualLegalBasisChange);
}

View File

@ -1,10 +1,11 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.IdRemovalEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.RemoveRedactionRepository;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.IdRemoval;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.RemoveRedactionRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
@ -12,6 +13,7 @@ import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Set;
import java.util.stream.Collectors;
@ -74,5 +76,8 @@ public class RemoveRedactionPersistenceService {
annotationStatus, OffsetDateTime.now(), isAddOrRemoveFromDictionary);
}
@Transactional
public void markAsProcessed(IdRemoval e) {
removeRedactionRepository.markAsProcessed(new AnnotationEntityId(e.getAnnotationId(), e.getFileId()), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
}

View File

@ -1,4 +1,4 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence;
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
import static com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter.convert;
@ -29,18 +29,19 @@ public class ResizeRedactionPersistenceService {
@Transactional
public void insert(String fileId, ResizeRedactionRequest resizeRedactionRequest) {
public ManualResizeRedactionEntity insert(String fileId, ResizeRedactionRequest resizeRedactionRequest) {
ManualResizeRedactionEntity manualResizeRedaction = new ManualResizeRedactionEntity();
manualResizeRedaction.setId(new AnnotationEntityId(resizeRedactionRequest.getAnnotationId(), fileId));
BeanUtils.copyProperties(resizeRedactionRequest, manualResizeRedaction);
manualResizeRedaction.setPositions(convert(resizeRedactionRequest.getPositions(), RectangleEntity.class));
manualResizeRedaction.setRequestDate(OffsetDateTime.now());
if(manualResizeRedaction.getStatus().equals(AnnotationStatus.APPROVED)) {
manualResizeRedaction.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
}
resizeRedactionRepository.save(manualResizeRedaction);
return resizeRedactionRepository.save(manualResizeRedaction);
}

View File

@ -45,9 +45,9 @@ public interface FileRepository extends JpaRepository<FileEntity, String> {
int analysisVersion, OffsetDateTime lastUpdated, OffsetDateTime lastProcessed, int analysisNumber);
@Modifying
@Query("update FileEntity f set f.workflowStatus = :workflowStatus, f.lastUpdated = :lastUpdated, f.approvalDate = :approvalDate " +
"where f.id = :fileId")
void updateWorkflowStatus(String fileId, WorkflowStatus workflowStatus, OffsetDateTime lastUpdated, OffsetDateTime approvalDate);
@Query("update FileEntity f set f.workflowStatus = :workflowStatus, f.lastUpdated = :lastUpdated, f.approvalDate = :approvalDate," +
" f.excludedFromAutomaticAnalysis = :excludedFromAutomaticAnalysis where f.id = :fileId")
void updateWorkflowStatus(String fileId, WorkflowStatus workflowStatus, OffsetDateTime lastUpdated, OffsetDateTime approvalDate, boolean excludedFromAutomaticAnalysis);
@Modifying(clearAutomatically = true)
@Query("update FileEntity f set f.processingStatus = :processingStatus, f.lastUpdated = :lastUpdated " +
@ -109,6 +109,10 @@ public interface FileRepository extends JpaRepository<FileEntity, String> {
@Query("update FileEntity f set f.excluded = :excluded, f.lastUpdated = :lastUpdated where f.id = :fileId")
int toggleExclusion(String fileId, boolean excluded, OffsetDateTime lastUpdated);
@Modifying(clearAutomatically = true)
@Query("update FileEntity f set f.excludedFromAutomaticAnalysis = :excludedFromAutomaticAnalysis, f.lastUpdated = :lastUpdated where f.id = :fileId")
int toggleAutomaticAnalysis(String fileId, boolean excludedFromAutomaticAnalysis, OffsetDateTime lastUpdated);
@Modifying(clearAutomatically = true)
@Query("update FileEntity f set f.filename = :filename, f.uploader = :uploader, f.processingStatus = :processingStatus, " +
"f.workflowStatus = :workflowStatus, f.lastUploaded = :lastUploaded, f.lastUpdated = :lastUpdated, " +

View File

@ -16,9 +16,9 @@ public interface ForceRedactionRepository extends JpaRepository<ManualForceRedac
List<ManualForceRedactionEntity> findByIdFileId(String fileId);
@Modifying
@Query("update ManualForceRedactionEntity mfr set mfr.status = :annotationStatus, mfr.processedDate = :processedDate " +
@Query("update ManualForceRedactionEntity mfr set mfr.status = :annotationStatus " +
"where mfr.id = :annotationEntityId")
void updateStatus(AnnotationEntityId annotationEntityId, AnnotationStatus annotationStatus, OffsetDateTime processedDate);
void updateStatus(AnnotationEntityId annotationEntityId, AnnotationStatus annotationStatus);
@Modifying
@Query("update ManualForceRedactionEntity mfr set mfr.softDeletedTime = :softDeletedTime " +
@ -31,4 +31,7 @@ public interface ForceRedactionRepository extends JpaRepository<ManualForceRedac
@Query("select mfr from ManualForceRedactionEntity mfr where mfr.id.fileId = :fileId and (:includeDeletions = true or mfr.softDeletedTime is null)")
List<ManualForceRedactionEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions);
@Modifying
@Query("update ManualForceRedactionEntity mfr set mfr.processedDate = :processedDate where mfr.id = :annotationEntityId")
void markAsProcessed(AnnotationEntityId annotationEntityId, OffsetDateTime processedDate);
}

View File

@ -15,9 +15,9 @@ public interface ImageRecategorizationRepository extends JpaRepository<ManualIma
List<ManualImageRecategorizationEntity> findByIdFileId(String fileId);
@Modifying
@Query("update ManualImageRecategorizationEntity mir set mir.status = :annotationStatus, mir.processedDate = :processedDate " +
@Query("update ManualImageRecategorizationEntity mir set mir.status = :annotationStatus " +
"where mir.id = :annotationEntityId")
void updateStatus(AnnotationEntityId annotationEntityId, AnnotationStatus annotationStatus, OffsetDateTime processedDate);
void updateStatus(AnnotationEntityId annotationEntityId, AnnotationStatus annotationStatus);
@Modifying
@Query("update ManualImageRecategorizationEntity mir set mir.softDeletedTime = :softDeletedTime " +
@ -29,4 +29,8 @@ public interface ImageRecategorizationRepository extends JpaRepository<ManualIma
@Query("select mir from ManualImageRecategorizationEntity mir where mir.id.fileId = :fileId and (:includeDeletions = true or mir.softDeletedTime is null)")
List<ManualImageRecategorizationEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions);
@Modifying
@Query("update ManualImageRecategorizationEntity mir set mir.processedDate = :processedDate where mir.id = :annotationEntityId")
void markAsProcessed(AnnotationEntityId annotationEntityId, OffsetDateTime processedDate);
}

View File

@ -0,0 +1,24 @@
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository;
import java.time.OffsetDateTime;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ImportedAnnotationEntity;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotationStatus;
public interface ImportedAnnotationRepository extends JpaRepository<ImportedAnnotationEntity, AnnotationEntityId> {
List<ImportedAnnotationEntity> findByIdFileId(String fileId);
@Modifying
@Query("update ImportedAnnotationEntity m set m.processedDate = :processedDate, m.status = :annotationStatus, m.comment = :comment, m.user = :userId where m.id = :id")
void updateStatus(AnnotationEntityId id, OffsetDateTime processedDate, ImportedAnnotationStatus annotationStatus,
String comment, String userId);
}

View File

@ -13,8 +13,6 @@ import java.util.Optional;
public interface LegalBasisChangeRepository extends JpaRepository<ManualLegalBasisChangeEntity, AnnotationEntityId> {
List<ManualLegalBasisChangeEntity> findByIdFileId(String fileId);
@Modifying
@Query("update ManualLegalBasisChangeEntity mlbc set mlbc.status = :annotationStatus, mlbc.processedDate = :processedDate " +
"where mlbc.id = :annotationEntityId")

View File

@ -20,14 +20,13 @@ public interface ManualRedactionRepository extends JpaRepository<ManualRedaction
void updateSoftDelete(AnnotationEntityId id, OffsetDateTime softDeleteTime);
@Modifying
@Query("update ManualRedactionEntryEntity m set m.processedDate = :processedDate, m.status = :annotationStatus" +
" where m.id = :id")
void updateStatus(AnnotationEntityId id, OffsetDateTime processedDate, AnnotationStatus annotationStatus);
@Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus where m.id = :id")
void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus);
@Modifying
@Query("update ManualRedactionEntryEntity m set m.processedDate = :processedDate, m.status = :annotationStatus," +
@Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus," +
" m.addToDictionary = :isAddOrRemoveFromDictionary, m.addToDossierDictionary = :isAddOrRemoveFromDossierDictionary where m.id = :id")
void updateStatus(AnnotationEntityId id, OffsetDateTime processedDate, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary,
void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary,
boolean isAddOrRemoveFromDossierDictionary);
@Query("select m from ManualRedactionEntryEntity m where m.id = :id and m.softDeletedTime is null")

View File

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

View File

@ -149,6 +149,13 @@ public class FileStatusController implements StatusResource {
}
public void toggleAutomaticAnalysis(@PathVariable(DOSSIER_ID_PARAM) String dossierId,
@PathVariable(FILE_ID) String fileId, @RequestParam(EXCLUDED_STATUS_PARAM) boolean excludedFromAutomaticAnalysis) {
excludeFromAnalysis.toggleAutomaticAnalysis(dossierId, fileId, excludedFromAutomaticAnalysis);
}
public void excludePages(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set<Integer> pages) {
FileEntity fileStatus = fileStatusService.getStatus(fileId);

View File

@ -0,0 +1,58 @@
package com.iqser.red.service.peristence.v1.server.controller;
import static com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter.convert;
import java.util.List;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.peristence.v1.server.utils.ImportedRedactionMapper;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ImportedAnnotationPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AddImportedAnnotationRequest;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotation;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.UpdateImportedAnnotationStatusRequest;
import com.iqser.red.service.persistence.service.v1.api.resources.ImportedAnnotationResource;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
public class ImportedAnnotationController implements ImportedAnnotationResource {
private final ImportedAnnotationPersistenceService importedAnnotationPersistenceService;
@Override
public List<ImportedAnnotation> getByFileId(@PathVariable(FILE_ID_PARAM) String fileId) {
return convert(importedAnnotationPersistenceService.findImportedAnnotations(fileId), ImportedAnnotation.class, new ImportedRedactionMapper());
}
@Override
public void insert(@PathVariable(FILE_ID_PARAM) String fileId,
@RequestBody AddImportedAnnotationRequest annotation) {
importedAnnotationPersistenceService.insert(fileId, annotation);
}
@Override
public void updateStatus(@PathVariable(FILE_ID_PARAM) String fileId,
@PathVariable(ANNOTATION_ID_PARAM) String annotationId,
@RequestBody UpdateImportedAnnotationStatusRequest updateImportedAnnotationStatusRequest) {
importedAnnotationPersistenceService.updateStatus(fileId, annotationId, updateImportedAnnotationStatusRequest.getStatus(), updateImportedAnnotationStatusRequest.getComment(), updateImportedAnnotationStatusRequest.getUser());
}
@Override
public void delete(@PathVariable(FILE_ID_PARAM) String fileId,
@PathVariable(ANNOTATION_ID_PARAM) String annotationId) {
importedAnnotationPersistenceService.delete(fileId, annotationId);
}
}

View File

@ -5,6 +5,7 @@ import com.iqser.red.service.peristence.v1.server.utils.ManualImageRecategorizat
import com.iqser.red.service.peristence.v1.server.utils.ManualRedactionMapper;
import com.iqser.red.service.peristence.v1.server.utils.ManualResizeRedactionMapper;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.*;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.*;
import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive;
import com.iqser.red.service.persistence.service.v1.api.resources.ManualRedactionResource;
import lombok.RequiredArgsConstructor;

View File

@ -41,51 +41,35 @@ public class ReanalysisController implements ReanalysisResource {
@Override
public void reanalyzeDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser,
@RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force) {
var relevantFiles = getRelevantFiles(dossierId);
var relevantFiles = getRelevantFiles(dossierId, triggeredByUser);
reanalyseFiles(dossierId, force, relevantFiles);
}
@Override
public void reanalyzeFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId,
@PathVariable(FILE_ID_PARAM) String fileId,
@RequestBody Set<Integer> sectionsToReanalyse) {
log.info("Reanalyse: {} / {} with sections: {}", dossierId, fileId, sectionsToReanalyse);
if (sectionsToReanalyse != null) {
var relevantFiles = getRelevantFiles(dossierId, Sets.newHashSet(fileId));
relevantFiles.forEach(file -> {
fileStatusService.setStatusReprocess(dossierId, fileId, 10, sectionsToReanalyse);
});
} else {
this.reanalyzeFiles(dossierId, Sets.newHashSet(fileId), false);
}
}
@Override
public void reanalyzeFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set<String> fileIds,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser,
@RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force) {
var relevantFiles = getRelevantFiles(dossierId, fileIds);
var relevantFiles = getRelevantFiles(dossierId, fileIds, triggeredByUser);
reanalyseFiles(dossierId, force, relevantFiles);
}
public void ocrDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId) {
public void ocrDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser) {
var relevantFiles = getRelevantFiles(dossierId);
var relevantFiles = getRelevantFiles(dossierId, triggeredByUser);
relevantFiles.stream().filter(fileStatus -> fileStatus.getLastOCRTime() == null).forEach(fileStatus -> fileStatusService.setStatusOcrProcessing(dossierId, fileStatus.getId()));
}
public void ocrFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set<String> fileIds) {
public void ocrFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser, @RequestBody Set<String> fileIds) {
var relevantFiles = getRelevantFiles(dossierId, fileIds);
var relevantFiles = getRelevantFiles(dossierId, fileIds, triggeredByUser);
relevantFiles.stream().filter(fileStatus -> fileStatus.getLastOCRTime() == null).forEach(fileStatus -> fileStatusService.setStatusOcrProcessing(dossierId, fileStatus.getId()));
}
@ -96,7 +80,9 @@ public class ReanalysisController implements ReanalysisResource {
}
public void ocrFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId, @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force) {
public void ocrFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId,
@RequestParam(value = "triggeredByUser", required = false, defaultValue = FALSE) boolean triggeredByUser,
@RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force) {
dossierPersistenceService.getAndValidateDossier(dossierId);
@ -110,26 +96,27 @@ public class ReanalysisController implements ReanalysisResource {
if (dossierFile.getLastOCRTime() != null) {
throw new ConflictException("File already has been OCR processed");
}
ocrFiles(dossierId, Sets.newHashSet(fileId));
ocrFiles(dossierId,triggeredByUser, Sets.newHashSet(fileId));
}
}
private List<FileEntity> getRelevantFiles(String dossierId) {
private List<FileEntity> getRelevantFiles(String dossierId, boolean triggeredByUser) {
var dossier = dossierPersistenceService.getAndValidateDossier(dossierId);
return fileStatusService.getDossierStatus(dossier.getId())
.stream()
.filter(fileStatus -> !fileStatus.getProcessingStatus().equals(ProcessingStatus.DELETED))
.filter(fileStatus -> !fileStatus.getWorkflowStatus().equals(WorkflowStatus.APPROVED))
.filter(fileStatus -> triggeredByUser || !fileStatus.isExcludedFromAutomaticAnalysis())
.collect(Collectors.toList());
}
private List<FileEntity> getRelevantFiles(String dossierId, Collection<String> fileIds) {
private List<FileEntity> getRelevantFiles(String dossierId, Collection<String> fileIds, boolean triggeredByUser) {
var relevantDossierFiles = getRelevantFiles(dossierId);
var relevantDossierFiles = getRelevantFiles(dossierId, triggeredByUser);
var relevantFiles = new ArrayList<FileEntity>();
for (var fileId : fileIds) {
@ -140,10 +127,6 @@ public class ReanalysisController implements ReanalysisResource {
var dossierFile = dossierFileOptional.get();
if (dossierFile.getProcessingStatus().equals(ProcessingStatus.DELETED) || dossierFile.getWorkflowStatus().equals(WorkflowStatus.APPROVED)) {
throw new ConflictException("Cannot analyse a deleted/approved file");
}
relevantFiles.add(dossierFile);
}
@ -155,14 +138,14 @@ public class ReanalysisController implements ReanalysisResource {
if (force) {
filesToReanalyse.forEach(file -> {
fileStatusService.setStatusReprocess(dossierId, file.getId(), 2);
fileStatusService.setStatusReprocess(dossierId, file.getId(), 2, true);
});
} else {
var enhancedAndConvertedFiles = reanalysisRequiredStatusService.enhanceFileStatusWithAnalysisRequirements(convert(
fileStatusService.getAllStatuses(), FileModel.class, new FileModelMapper()));
enhancedAndConvertedFiles.forEach(file -> {
fileStatusService.setStatusReprocess(dossierId, file.getId(), 2);
fileStatusService.setStatusReprocess(dossierId, file.getId(), 2, true);
});
}

View File

@ -226,16 +226,10 @@ public class MigrationService {
.redacted(oldRedactionLogEntry.isRedacted())
.isHint(oldRedactionLogEntry.isHint())
.isRecommendation(oldRedactionLogEntry.isRecommendation())
.hasBeenResized(false) // Will be added during merge of manual
.hasBeenRecategorized(false) // Will be added during merge of manual
.section(oldRedactionLogEntry.getSection())
.color(oldRedactionLogEntry.getColor())
.positions(oldRedactionLogEntry.getPositions())
.sectionNumber(oldRedactionLogEntry.getSectionNumber())
.manual(oldRedactionLogEntry.isManual())
.status(oldRedactionLogEntry.getStatus())
.manualRedactionType(oldRedactionLogEntry.getManualRedactionType())
.manualRedactionUserId(null) // Will be added during merge of manual
.isDictionaryEntry(oldRedactionLogEntry.isDictionaryEntry())
.textBefore(oldRedactionLogEntry.getTextBefore())
.textAfter(oldRedactionLogEntry.getTextAfter())
@ -249,8 +243,6 @@ public class MigrationService {
.imageHasTransparency(oldRedactionLogEntry.isImageHasTransparency())
.isDossierDictionaryEntry(oldRedactionLogEntry.isDictionaryEntry())
.excluded(oldRedactionLogEntry.isExcluded())
.recategorizationType(oldRedactionLogEntry.getRecategorizationType())
.legalBasisChangeValue(oldRedactionLogEntry.getLegalBasisChangeValue())
.changes(List.of(new Change(analysisNumber, ChangeType.ADDED, lastProcessed)))
.engines(getEngine(oldRedactionLogEntry))
.reference(null)

View File

@ -4,6 +4,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus;
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
import lombok.RequiredArgsConstructor;
@ -53,8 +54,7 @@ public class AnalysisFlagsCalculationService {
String type = getType(entry.getType());
if (!hasRedactions && (entry.isRedacted() && !entry.isManual() || entry.isManual() && entry.getStatus()
.equals(AnnotationStatus.APPROVED))) {
if (!hasRedactions && entry.isRedacted()) {
hasRedactions = true;
}
@ -66,7 +66,7 @@ public class AnalysisFlagsCalculationService {
hasImages = true;
}
if (!hasSuggestions && entry.isManual() && entry.getStatus().equals(AnnotationStatus.REQUESTED)) {
if (!hasSuggestions && entry.getManualChanges().stream().anyMatch(e -> e.getAnnotationStatus() == AnnotationStatus.REQUESTED)) {
hasSuggestions = true;
}
@ -82,12 +82,13 @@ public class AnalysisFlagsCalculationService {
var viewedPage = entry.getPositions().isEmpty() ? null : viewedPages.get(entry.getPositions().get(0).getPage());
if (lastChange != null && lastChange.getDateTime() != null && viewedPage != null && viewedPage.isBefore(lastChange.getDateTime())) {
if (file.getWorkflowStatus() != WorkflowStatus.APPROVED && lastChange != null && lastChange.getDateTime() != null && viewedPage != null && viewedPage.isBefore(lastChange.getDateTime())) {
hasUpdates = true;
}
}
log.info("Flag Calculations for file: {} took: {}ms", fileId, System.currentTimeMillis() - startTime);
if (file.isHasRedactions() == hasRedactions &&
@ -102,7 +103,7 @@ public class AnalysisFlagsCalculationService {
}
OffsetDateTime lastManualRedactionTime = file.getLastManualRedaction();
if(lastModification == null || lastManualRedactionTime.isAfter(lastModification)){
if(lastModification == null || lastManualRedactionTime != null && lastManualRedactionTime.isAfter(lastModification)){
lastModification = lastManualRedactionTime;
}

View File

@ -1,65 +0,0 @@
package com.iqser.red.service.peristence.v1.server.service;
import com.iqser.red.service.peristence.v1.server.client.SearchClient;
import com.iqser.red.service.peristence.v1.server.controller.ReanalysisController;
import com.iqser.red.service.search.v1.model.MatchedSection;
import com.iqser.red.service.search.v1.model.SearchRequest;
import lombok.Builder;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class DictionarySearchAndNotifyService {
private final ReanalysisController reanalysisClient;
private final SearchClient searchClient;
public void dictionaryEntriesUpdated(String dossierTemplateId, Collection<String> changedEntries) {
log.info("Detect Changes for dossierTemplateId: {} and entries: {}", dossierTemplateId, changedEntries);
Map<SearchKey, Set<Integer>> searchResultMap = new HashMap<>();
for (var entry : changedEntries) {
var searchResult = searchClient.getDossierStatus(SearchRequest.builder()
.dossierTemplateIds(Collections.singletonList(dossierTemplateId)).page(1).pageSize(10_000)
.returnSections(true)
.queryString(entry)
.build());
log.info("Got changes: {} for entry: {}", searchResult.getTotal(), entry);
searchResult.getMatchedDocuments().forEach(document -> {
var currentSections = searchResultMap.computeIfAbsent(SearchKey.builder().fileId(document.getFileId()).dossierId(document.getDossierId()).build(), (data) -> new HashSet<>());
currentSections.addAll(document.getMatchedSections().stream().map(MatchedSection::getSectionNumber).collect(Collectors.toList()));
});
}
log.info("Should reanalyse: {}", searchResultMap);
searchResultMap.forEach((searchKey, sectionNumbers) -> {
log.info("Reanalyse: {} / {} ", searchKey, sectionNumbers);
reanalysisClient.reanalyzeFile(searchKey.getDossierId(), searchKey.getFileId(), sectionNumbers);
});
}
@Data
@Builder
public static class SearchKey {
private String fileId;
private String dossierId;
}
}

View File

@ -9,10 +9,8 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class ExcludeFromAnalysisService {
private final FileStatusService fileStatusService;
public void toggleExclusion(String dossierId, String fileId, boolean excluded) {
var status = fileStatusService.getStatus(fileId);
@ -31,4 +29,16 @@ public class ExcludeFromAnalysisService {
}
public void toggleAutomaticAnalysis(String dossierId, String fileId, boolean excludedFromAutomaticAnalysis) {
// toggle status
fileStatusService.toggleAutomaticAnalysis(fileId, excludedFromAutomaticAnalysis);
if (!excludedFromAutomaticAnalysis) {
// if file has been re-enabled - process it
fileStatusService.setStatusFullReprocess(dossierId, fileId, 2);
}
}
}

View File

@ -2,6 +2,8 @@ package com.iqser.red.service.peristence.v1.server.service;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import com.iqser.red.service.pdftron.redaction.v1.api.model.AnnotationExtractionResponse;
import com.iqser.red.service.pdftron.redaction.v1.api.model.DocumentRequest;
import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronOptimizeRequest;
import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronOptimizeResponse;
import com.iqser.red.service.persistence.management.v1.processor.client.PDFTronRedactionClient;
@ -10,6 +12,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.BadRe
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.*;
import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.BinaryFileRequest;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileType;
@ -47,6 +50,7 @@ public class FileService {
private final LegalBasisChangePersistenceService legalBasisChangePersistenceService;
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
private final IndexingService indexingService;
private final ImportedAnnotationPersistenceService importedAnnotationPersistenceService;
public JSONPrimitive<String> upload(BinaryFileRequest request) {
@ -68,7 +72,9 @@ public class FileService {
}
try {
PdfTronOptimizeResponse optimized = pdfTronRedactionClient.optimize(new PdfTronOptimizeRequest(request.getData()));
AnnotationExtractionResponse optimized = pdfTronRedactionClient.optimizeGetAndRemoveAnnotations(new DocumentRequest(request.getData()));
importedAnnotationPersistenceService.insert(fileId, optimized.getAnnotations());
if (optimized.getNumberOfPages() == 0) {
throw new BadRequestException("Empty document");
}
@ -155,8 +161,13 @@ public class FileService {
}
public void hardDeleteFile(String dossierId, String fileId) {
Arrays.stream(FileType.values()).forEach(fileType ->
fileManagementStorageService.deleteObject(dossierId, fileId, fileType)
Arrays.stream(FileType.values()).forEach(fileType -> {
try {
fileManagementStorageService.deleteObject(dossierId, fileId, fileType);
} catch (Exception e) {
log.warn("Failed to physically delete file: {} with type {}", fileId, fileType);
}
}
);
forceRedactionPersistenceService.findForceRedactions(fileId, true).forEach(annotation -> {

View File

@ -31,7 +31,7 @@ public class FileStatusProcessingUpdateService {
case SURROUNDING_TEXT:
fileStatusService.setStatusProcessed(analyzeResult.getFileId());
manualRedactionService.updateManualRedactions(fileId, analyzeResult.getManualRedactions());
manualRedactionService.updateSurroundingText(fileId, analyzeResult.getManualRedactions());
break;
case REANALYSE:
case FULL_ANALYSE:
@ -47,6 +47,7 @@ public class FileStatusProcessingUpdateService {
indexingService.addToIndexingQueue(IndexMessageType.INSERT, dossier.getDossierTemplateId(), dossierId, fileId, 2);
}
manualRedactionService.updateProcessedDate(fileId, analyzeResult.getManualRedactions());
analysisFlagsCalculationService.calculateFlags(dossierId, fileId);
}

View File

@ -8,17 +8,20 @@ import com.iqser.red.service.peristence.v1.server.configuration.MessagingConfigu
import com.iqser.red.service.peristence.v1.server.controller.RulesController;
import com.iqser.red.service.peristence.v1.server.model.image.ImageServiceRequest;
import com.iqser.red.service.peristence.v1.server.settings.FileManagementServiceSettings;
import com.iqser.red.service.peristence.v1.server.utils.ImportedRedactionMapper;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileAttributeEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.UserNotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.*;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotation;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus;
import com.iqser.red.service.redaction.v1.model.AnalyzeRequest;
import com.iqser.red.service.redaction.v1.model.AnalyzeResult;
import com.iqser.red.service.redaction.v1.model.MessageType;
import com.iqser.red.service.search.v1.model.IndexMessageType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -51,6 +54,7 @@ public class FileStatusService {
private final AddRedactionPersistenceService addRedactionPersistenceService;
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
private final FileManagementServiceSettings settings;
private final ImportedAnnotationPersistenceService importedAnnotationPersistenceService;
public List<FileEntity> getActiveFiles(String dossierId) {
@ -128,12 +132,18 @@ public class FileStatusService {
@Transactional
public void setStatusReprocess(String dossierId, String fileId, int priority) {
setStatusReprocess(dossierId, fileId, priority, Sets.newHashSet());
setStatusReprocess(dossierId, fileId, priority, Sets.newHashSet(), false);
}
@Transactional
public void setStatusReprocess(String dossierId, String fileId, int priority, boolean triggeredManually) {
setStatusReprocess(dossierId, fileId, priority, Sets.newHashSet(), triggeredManually);
}
@Transactional
public void setStatusReprocess(String dossierId, String fileId, int priority, Set<Integer> sectionsToReanalyse) {
public void setStatusReprocess(String dossierId, String fileId, int priority, Set<Integer> sectionsToReanalyse, boolean triggeredManually) {
log.info("Reprocessing file: {} from dossier {}", fileId, dossierId);
@ -144,6 +154,11 @@ public class FileStatusService {
return;
}
if(fileStatus.isExcludedFromAutomaticAnalysis() && !triggeredManually){
log.debug("File {} is excluded from automatic analysis", fileStatus.getId());
return;
}
fileStatusPersistenceService.updateProcessingStatus(fileId, ProcessingStatus.REPROCESS);
addToAnalysisQueue(dossierId, fileId, priority, sectionsToReanalyse);
}
@ -241,7 +256,14 @@ public class FileStatusService {
}
public void toggleAutomaticAnalysis(String fileId, boolean excludedFromAutomaticAnalysis) {
fileStatusPersistenceService.toggleAutomaticAnalysis(fileId, excludedFromAutomaticAnalysis);
}
@Transactional
@SuppressWarnings("PMD")
protected void addToAnalysisQueue(String dossierId, String fileId, int priority, Set<Integer> sectionsToReanalyse) {
var dossier = dossierPersistenceService.getAndValidateDossier(dossierId);
@ -264,6 +286,8 @@ public class FileStatusService {
return;
}
List<ImportedAnnotation> importedAnnotations = MagicConverter.convert(importedAnnotationPersistenceService.findImportedAnnotations(fileId), ImportedAnnotation.class, new ImportedRedactionMapper());
var analyseRequest = AnalyzeRequest.builder()
.messageType(reanalyse ? MessageType.REANALYSE : MessageType.FULL_ANALYSE)
.dossierId(dossierId)
@ -275,6 +299,7 @@ public class FileStatusService {
.lastProcessed(fileStatus.getLastProcessed())
.fileAttributes(convert(fileAttributes))
.excludedPages(fileStatus.getExcludedPages())
.importedAnnotations(importedAnnotations)
.build();
setStatusProcessing(fileId);

View File

@ -5,8 +5,10 @@ import com.iqser.red.service.peristence.v1.server.utils.ManualRedactionMapper;
import com.iqser.red.service.peristence.v1.server.utils.ManualResizeRedactionMapper;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.CommentEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.*;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.*;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Comment;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

View File

@ -13,21 +13,24 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.*;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.*;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualResizeRedaction;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.redaction.v1.model.AnalyzeRequest;
import com.iqser.red.service.redaction.v1.model.MessageType;
import com.iqser.red.service.redaction.v1.model.RedactionLog;
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
import feign.FeignException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.nio.charset.StandardCharsets;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
@ -83,6 +86,7 @@ public class ManualRedactionService {
String annotationId = hashFunction.hashString(fileId + addRedactionRequest, StandardCharsets.UTF_8).toString();
OffsetDateTime now = OffsetDateTime.now();
addRedactionPersistenceService.insert(fileId, annotationId, addRedactionRequest);
Long commentId = null;
@ -110,7 +114,6 @@ public class ManualRedactionService {
return ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build();
}
public ManualAddResponse addRemoveRedaction(String dossierId, String fileId,
RemoveRedactionRequest removeRedactionRequest) {
@ -138,7 +141,7 @@ public class ManualRedactionService {
}
if (removeRedactionRequest.getStatus().equals(AnnotationStatus.APPROVED)) {
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
}
return ManualAddResponse.builder()
@ -171,7 +174,7 @@ public class ManualRedactionService {
analysisFlagsCalculationService.calculateFlags(dossierId, fileId);
if (forceRedactionRequest.getStatus().equals(AnnotationStatus.APPROVED)) {
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
}
return ManualAddResponse.builder()
@ -228,7 +231,7 @@ public class ManualRedactionService {
fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, now, true);
} else {
fileStatusPersistenceService.updateLastManualRedaction(fileId, now);
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
}
analysisFlagsCalculationService.calculateFlags(dossierId, fileId);
@ -240,17 +243,6 @@ public class ManualRedactionService {
}
public CommentEntity addComment(String fileId, String annotationId, CommentRequest commentRequest) {
var createdComment = addComment(fileId, annotationId, commentRequest.getText(), commentRequest.getUser());
fileStatusPersistenceService.updateLastManualRedaction(fileId, OffsetDateTime.now());
fileStatusPersistenceService.updateHasComments(fileId, true);
return createdComment;
}
public ManualAddResponse addResizeRedaction(String dossierId, String fileId,
ResizeRedactionRequest resizeRedactionRequest) {
@ -283,6 +275,16 @@ public class ManualRedactionService {
.build();
}
public CommentEntity addComment(String fileId, String annotationId, CommentRequest commentRequest) {
var createdComment = addComment(fileId, annotationId, commentRequest.getText(), commentRequest.getUser());
fileStatusPersistenceService.updateLastManualRedaction(fileId, OffsetDateTime.now());
fileStatusPersistenceService.updateHasComments(fileId, true);
return createdComment;
}
public ManualRedactionEntryEntity getAddRedaction(String fileId, String annotationId) {
@ -408,7 +410,7 @@ public class ManualRedactionService {
fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions);
} else {
fileStatusPersistenceService.updateLastManualRedaction(fileId, OffsetDateTime.now());
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
}
analysisFlagsCalculationService.calculateFlags(dossierId, fileId);
}
@ -456,7 +458,7 @@ public class ManualRedactionService {
.filter(entry -> entry.getId().equals(idRemoval.getId().getAnnotationId()))
.findFirst();
if (!redactionLogEntryOptional.isPresent()) {
if (redactionLogEntryOptional.isEmpty()) {
throw new NotFoundException("Annotation does not exist in redaction log.");
}
@ -482,16 +484,6 @@ public class ManualRedactionService {
}
private String buildTypeId(RedactionLogEntry redactionLogEntry, DossierEntity dossier) {
if (redactionLogEntry.isDossierDictionaryEntry()) {
return toTypeId(redactionLogEntry.getType(), dossier.getDossierTemplateId(), dossier.getId());
} else {
return toTypeId(redactionLogEntry.getType(), dossier.getDossierTemplateId());
}
}
public void updateForceRedactionStatus(String dossierId, String fileId, String annotationId,
AnnotationStatus annotationStatus) {
@ -503,6 +495,7 @@ public class ManualRedactionService {
}
@Transactional
public void updateLegalBasisChangeStatus(String dossierId, String fileId, String annotationId,
AnnotationStatus annotationStatus) {
@ -523,10 +516,10 @@ public class ManualRedactionService {
// if it was previously approved, revert the delete
if (imageRecategorization.getStatus() == AnnotationStatus.APPROVED) {
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
}
} else if (annotationStatus.equals(AnnotationStatus.APPROVED)) {
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
}
dossierPersistenceService.getAndValidateDossier(dossierId);
@ -581,6 +574,40 @@ public class ManualRedactionService {
}
@Transactional
public void updateSurroundingText(String fileId, ManualRedactions manualRedactions) {
// These are marked as processed once surrounding text is computed ( TBD if this is correct ? )
manualRedactions.getEntriesToAdd().forEach(e -> addRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter()));
manualRedactions.getResizeRedactions().forEach(e -> resizeRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter()));
}
@Transactional
public void updateProcessedDate(String fileId, ManualRedactions manualRedactions) {
// These are marked as processed once analysis completes, not when they are set as approved
manualRedactions.getIdsToRemove().forEach(removeRedactionPersistenceService::markAsProcessed);
manualRedactions.getForceRedactions().forEach(forceRedactionPersistenceService::markAsProcessed);
manualRedactions.getImageRecategorization().forEach(recategorizationPersistenceService::markAsProcessed);
}
private void reprocess(String dossierId, String fileId) {
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
}
private String buildTypeId(RedactionLogEntry redactionLogEntry, DossierEntity dossier) {
if (redactionLogEntry.isDossierDictionaryEntry()) {
return toTypeId(redactionLogEntry.getType(), dossier.getDossierTemplateId(), dossier.getId());
} else {
return toTypeId(redactionLogEntry.getType(), dossier.getDossierTemplateId());
}
}
private void handleAddToDictionary(String fileId, String annotationId, String typeId, String value,
AnnotationStatus status, boolean addToDictionary, boolean addToDossierDictionary,
boolean revert, String dossierId) {
@ -615,7 +642,7 @@ public class ManualRedactionService {
.filter(entry -> entry.getId().equals(annotationId))
.findFirst();
if (!redactionLogEntryOptional.isPresent()) {
if (redactionLogEntryOptional.isEmpty()) {
throw new NotFoundException("Annotation does not exist in redaction log.");
}
@ -635,10 +662,10 @@ public class ManualRedactionService {
private void addToDictionary(String typeId, String value, String dossierId, String fileId) {
try {
log.debug("Adding entries to {} for {} / {}", typeId, dossierId, fileId);
log.debug("Adding entry: {} to {} for {} / {}", value, typeId, dossierId, fileId);
dictionaryController.addEntries(typeId, List.of(value), false, false);
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
} catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
@ -650,7 +677,7 @@ public class ManualRedactionService {
try {
log.debug("Deleting entries to {} for {} / {}", typeId, dossierId, fileId);
dictionaryController.deleteEntries(typeId, List.of(value));
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
reprocess(dossierId, fileId);
} catch (FeignException e) {
throw new BadRequestException(e.getMessage());
}
@ -711,18 +738,6 @@ public class ManualRedactionService {
}
public void updateManualRedactions(String fileId, ManualRedactions manualRedactions) {
manualRedactions.getEntriesToAdd().forEach(e -> {
addRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter());
});
manualRedactions.getResizeRedactions().forEach(e -> {
resizeRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter());
});
}
private void addManualRedactionToAnalysisQueue(String dossierId, String fileId, ManualRedactions manualRedactions) {
fileStatusPersistenceService.updateProcessingStatus(fileId, ProcessingStatus.SURROUNDING_TEXT_PROCESSING);

View File

@ -95,6 +95,10 @@ public class DownloadPreparationService {
fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Preview", addSuffix(fileStatus.getFilename(), "highlighted"),
getPreview(original, redactionLog, dossier.getDossierTemplateId(), dossier.isWatermarkPreviewEnabled())));
}
if (downloadFileType.name().equals(DownloadFileType.DELTA_PREVIEW.name())) {
fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Delta Preview", addSuffix(fileStatus.getFilename(), "delta_highlighted"),
getDeltaPreview(original, redactionLog, dossier.getDossierTemplateId(), dossier.isWatermarkPreviewEnabled())));
}
if (downloadFileType.name().equals(DownloadFileType.REDACTED.name())) {
fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Redacted", addSuffix(fileStatus.getFilename(), "redacted"),
getRedacted(original, redactionLog, dossier.getDossierTemplateId(), dossier.isWatermarkEnabled())));
@ -207,6 +211,17 @@ public class DownloadPreparationService {
}
private byte[] getDeltaPreview(byte[] original, RedactionLog redactionLog, String dossierTemplateId, boolean watermarkEnabled) {
return pdfTronRedactionClient.redactionPreviewDiff(PdfTronRedactionRequest.builder()
.document(original)
.dossierTemplateId(dossierTemplateId)
.redactionLog(redactionLog)
.applyWatermark(watermarkEnabled)
.build()).getDocument();
}
private RedactionLog getRedactionLog(String dossierId, String fileId, boolean isExcluded) {
if (isExcluded) {

View File

@ -67,7 +67,7 @@ public class AutomaticAnalysisScheduler {
if (next.isFullAnalysisRequired()) {
log.info("Queued file: {} for automatic full analysis! ", next.getFilename());
fileStatusService.setStatusFullReprocess(next.getDossierId(), next.getId(), 1);
} else if(next.isReanalysisRequired()){
} else if (next.isReanalysisRequired()) {
log.info("Queued file: {} for automatic reanalysis! ", next.getFilename());
fileStatusService.setStatusReprocess(next.getDossierId(), next.getId(), 1);
}
@ -86,6 +86,7 @@ public class AutomaticAnalysisScheduler {
.stream()
.filter(f -> !f.getProcessingStatus().equals(ProcessingStatus.DELETED))
.filter(f -> !f.getWorkflowStatus().equals(WorkflowStatus.APPROVED))
.filter(f -> !f.isExcludedFromAutomaticAnalysis())
.filter(f -> !isProcessing(f))
.filter(f -> f.getDossier().getSoftDeletedTime() == null && f.getDossier().getHardDeletedTime() == null && f.getDossier().getArchivedTime() == null)
.collect(Collectors.toList()), FileModel.class, new FileModelMapper()))

View File

@ -0,0 +1,18 @@
package com.iqser.red.service.peristence.v1.server.utils;
import static com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter.convert;
import java.util.function.BiConsumer;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ImportedAnnotationEntity;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotation;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Rectangle;
public class ImportedRedactionMapper implements BiConsumer<ImportedAnnotationEntity, ImportedAnnotation> {
@Override
public void accept(ImportedAnnotationEntity manualRedactionEntryEntity, ImportedAnnotation manualRedactionEntry) {
manualRedactionEntry.setPositions(convert(manualRedactionEntryEntity.getPositions(), Rectangle.class));
}
}

View File

@ -1,7 +1,7 @@
package com.iqser.red.service.peristence.v1.server.utils;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualImageRecategorizationEntity;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualImageRecategorization;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualImageRecategorization;
import java.util.function.BiConsumer;

View File

@ -1,7 +1,7 @@
package com.iqser.red.service.peristence.v1.server.utils;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Rectangle;
import java.util.function.BiConsumer;

View File

@ -5,7 +5,7 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ma
import java.util.function.BiConsumer;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualResizeRedactionEntity;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualResizeRedaction;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualResizeRedaction;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Rectangle;
public class ManualResizeRedactionMapper implements BiConsumer<ManualResizeRedactionEntity, ManualResizeRedaction> {

View File

@ -0,0 +1,109 @@
databaseChangeLog:
- changeSet:
id: imported-annotation
author: philipp
changes:
- createTable:
columns:
- column:
constraints:
nullable: false
primaryKey: true
primaryKeyName: imported_annotation_pkey
name: annotation_id
type: VARCHAR(255)
- column:
constraints:
nullable: false
primaryKey: true
primaryKeyName: imported_annotation_pkey
name: file_id
type: VARCHAR(255)
- column:
name: user_id
type: VARCHAR(255)
- column:
name: status
type: VARCHAR(255)
- column:
name: processed_date
type: TIMESTAMP WITHOUT TIME ZONE
- column:
name: file_status_id
type: VARCHAR(255)
- column:
name: comment
type: VARCHAR(255)
tableName: imported_annotation
- changeSet:
id: imported-annotation_positions
author: generated
changes:
- createTable:
columns:
- column:
constraints:
nullable: false
name: imported_annotation_entity_annotation_id
type: VARCHAR(255)
- column:
constraints:
nullable: false
name: imported_annotation_entity_file_id
type: VARCHAR(255)
- column:
constraints:
nullable: false
name: height
type: FLOAT4
- column:
constraints:
nullable: false
name: page
type: INTEGER
- column:
constraints:
nullable: false
name: top_leftx
type: FLOAT4
- column:
constraints:
nullable: false
name: top_lefty
type: FLOAT4
- column:
constraints:
nullable: false
name: width
type: FLOAT4
tableName: imported_annotation_entity_positions
- changeSet:
id: imported-annotation-file-fk
author: dom
changes:
- addForeignKeyConstraint:
baseColumnNames: file_status_id
baseTableName: imported_annotation
constraintName: fkeur9q7l2tp5n12c2t9dfp3a10
deferrable: false
initiallyDeferred: false
onDelete: NO ACTION
onUpdate: NO ACTION
referencedColumnNames: id
referencedTableName: file
validate: true
- changeSet:
id: imported-annotation-file-positions
author: dom
changes:
- addForeignKeyConstraint:
baseColumnNames: imported_annotation_entity_annotation_id,imported_annotation_entity_file_id
baseTableName: imported_annotation_entity_positions
constraintName: fkol1r7vwjc1uvu36p5ju7cj28j
deferrable: false
initiallyDeferred: false
onDelete: NO ACTION
onUpdate: NO ACTION
referencedColumnNames: annotation_id,file_id
referencedTableName: imported_annotation
validate: true

View File

@ -0,0 +1,24 @@
databaseChangeLog:
- changeSet:
id: add-excluded-from-automatic-analysis-column
author: timo
changes:
- addColumn:
columns:
- column:
name: excluded_from_automatic_analysis
type: BOOLEAN
defaultValue: false
tableName: file
- changeSet:
id: updated-excluded-from-automatic-analysis-column
author: timo
changes:
- update:
columns:
- column:
name: excluded_from_automatic_analysis
value: true
schemaName: public
tableName: file
where: workflow_status = 'APPROVED'

View File

@ -8,4 +8,8 @@ databaseChangeLog:
- include:
file: db/changelog/4-archived-dossier.changelog.yaml
- include:
file: db/changelog/5-dossier-status-table.changelog.yaml
file: db/changelog/5-imported-annotation.changelog.yaml
- include:
file: db/changelog/6-excluded-from-automatic-analysis-file-column.changelog.yaml
- include:
file: db/changelog/7-dossier-status-table.changelog.yaml

View File

@ -0,0 +1,10 @@
package com.iqser.red.service.peristence.v1.server.integration.client;
import org.springframework.cloud.openfeign.FeignClient;
import com.iqser.red.service.persistence.service.v1.api.resources.ImportedAnnotationResource;
@FeignClient(name = "ImportedRedactionClient", url = "http://localhost:${server.port}")
public interface ImportedRedactionClient extends ImportedAnnotationResource {
}

View File

@ -1,20 +1,20 @@
package com.iqser.red.service.peristence.v1.server.integration.tests;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.iqser.red.service.peristence.v1.server.integration.client.FileClient;
import com.iqser.red.service.peristence.v1.server.integration.client.FileProcessingClient;
import com.iqser.red.service.peristence.v1.server.integration.client.UploadClient;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.service.FileTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus;
import com.iqser.red.service.redaction.v1.model.AnalyzeResult;
import com.iqser.red.service.redaction.v1.model.MessageType;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.assertj.core.api.Assertions.assertThat;
public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
@ -48,6 +48,7 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.ERROR);
fileProcessingClient.analysisSuccessful(dossier.getId(), file.getId(), AnalyzeResult.builder()
.manualRedactions(new ManualRedactions())
.messageType(MessageType.FULL_ANALYSE)
.analysisVersion(100)
.fileId(file.getId())
@ -97,6 +98,7 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.ERROR);
fileProcessingClient.analysisSuccessful(dossier.getId(), file.getId(), AnalyzeResult.builder()
.manualRedactions(new ManualRedactions())
.messageType(MessageType.FULL_ANALYSE)
.analysisVersion(100)
.fileId(file.getId())
@ -132,12 +134,13 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
@Test
public void testFileReanlyseAfterToggleExclusion(){
public void testFileReanlyseAfterToggleExclusion() {
var dossier = dossierTesterAndProvider.provideTestDossier();
var file = fileTesterAndProvider.testAndProvideFile(dossier);
fileProcessingClient.analysisSuccessful(dossier.getId(), file.getId(), AnalyzeResult.builder()
.manualRedactions(new ManualRedactions())
.messageType(MessageType.FULL_ANALYSE)
.analysisVersion(100)
.fileId(file.getId())

View File

@ -0,0 +1,56 @@
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.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.iqser.red.service.peristence.v1.server.integration.client.ImportedRedactionClient;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTemplateTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.service.FileTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AddImportedAnnotationRequest;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImportedAnnotationStatus;
import com.iqser.red.service.redaction.v1.model.Point;
import com.iqser.red.service.redaction.v1.model.Rectangle;
public class ImportedRedactionTest extends AbstractPersistenceServerServiceTest {
@Autowired
private FileTesterAndProvider fileTesterAndProvider;
@Autowired
private DossierTesterAndProvider dossierTesterAndProvider;
@Autowired
private DossierTemplateTesterAndProvider dossierTemplateTesterAndProvider;
@Autowired
private ImportedRedactionClient importedRedactionClient;
@Test
public void testManualRedaction() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
importedRedactionClient.insert(file.getId(), AddImportedAnnotationRequest.builder()
.positions(List.of(new Rectangle(new Point(1, 1), 1, 1, 1)))
.annotationId("annotationId")
.status(ImportedAnnotationStatus.NEW)
.userId("userId")
.comment("comment")
.build());
var loadedImportedRedaction = importedRedactionClient.getByFileId(file.getId());
assertThat(loadedImportedRedaction.get(0).getPositions().size()).isEqualTo(1);
}
}

View File

@ -291,8 +291,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.build());
var loadedForceRedaction2 = manualRedactionClient.getForceRedaction(file.getId(), forceRedaction2.getAnnotationId());
assertThat(loadedForceRedaction2.getStatus()).isEqualTo(AnnotationStatus.APPROVED);
assertThat(loadedForceRedaction2.getProcessedDate()).isNotNull();
assertThat(loadedForceRedaction2.getProcessedDate()).isNull();
manualRedactionClient.updateForceRedactionStatus(dossier.getId(), file.getId(), forceRedaction2.getAnnotationId(), JSONPrimitive.of(AnnotationStatus.REQUESTED));
loadedForceRedaction2 = manualRedactionClient.getForceRedaction(file.getId(), forceRedaction2.getAnnotationId());

View File

@ -42,33 +42,28 @@ public class ReanalysisTest extends AbstractPersistenceServerServiceTest {
var file = fileTesterAndProvider.testAndProvideFile(dossier);
reanalysisClient.ocrDossier(dossier.getId());
reanalysisClient.ocrDossier(dossier.getId(),true);
var loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.OCR_PROCESSING);
resetProcessingStatus(file);
reanalysisClient.ocrFile(dossier.getId(), file.getId(), true);
reanalysisClient.ocrFile(dossier.getId(), file.getId(),true, true);
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.OCR_PROCESSING);
resetProcessingStatus(file);
reanalysisClient.ocrFiles(dossier.getId(), Set.of(file.getId()));
reanalysisClient.ocrFiles(dossier.getId(),true, Set.of(file.getId()));
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.OCR_PROCESSING);
resetProcessingStatus(file);
reanalysisClient.reanalyzeFiles(dossier.getId(), Set.of(file.getId()), true);
reanalysisClient.reanalyzeFiles(dossier.getId(), Set.of(file.getId()), true,true);
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.PROCESSING);
resetProcessingStatus(file);
reanalysisClient.reanalyzeFile(dossier.getId(), file.getId(), Sets.newHashSet());
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.PROCESSING);
resetProcessingStatus(file);
reanalysisClient.reanalyzeDossier(dossier.getId(), true);
reanalysisClient.reanalyzeDossier(dossier.getId(), true,true);
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.PROCESSING);
resetProcessingStatus(file);

View File

@ -36,6 +36,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import java.util.List;
import java.util.TimeZone;
@RunWith(SpringRunner.class)
@ -114,10 +115,11 @@ public abstract class AbstractPersistenceServerServiceTest {
doNothing().when(pdfTronRedactionClient).testDigitalCurrentSignature(Mockito.any());
when(amqpAdmin.getQueueInfo(Mockito.any())).thenReturn(null);
when(pdfTronRedactionClient.optimize(Mockito.any())).thenAnswer((args) -> {
PdfTronOptimizeRequest request = (PdfTronOptimizeRequest) args.getArguments()[0];
when(pdfTronRedactionClient.optimizeGetAndRemoveAnnotations(Mockito.any())).thenAnswer((args) -> {
DocumentRequest request = (DocumentRequest) args.getArguments()[0];
int numberOfPages = (request.getDocument().length == 0? 0: 10);
return new PdfTronOptimizeResponse(request.getDocument(), numberOfPages);
return new AnnotationExtractionResponse(request.getDocument(), numberOfPages, List.of());
});
when(pdfTronRedactionClient.redact(Mockito.any())).thenAnswer((args) ->
new PdfTronRedactionResult(((PdfTronRedactionRequest) args.getArguments()[0]).getDocument()));

View File

@ -25,9 +25,9 @@
</modules>
<properties>
<redaction-service.version>3.56.0</redaction-service.version>
<redaction-service.version>3.68.0</redaction-service.version>
<search-service.version>2.18.0</search-service.version>
<pdftron-redaction-service.version>3.17.0</pdftron-redaction-service.version>
<pdftron-redaction-service.version>3.30.0</pdftron-redaction-service.version>
<redaction-report-service.version>3.19.0</redaction-report-service.version>
</properties>
@ -36,7 +36,7 @@
<dependency>
<groupId>com.iqser.red</groupId>
<artifactId>platform-commons-dependency</artifactId>
<version>1.8.0</version>
<version>1.10.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>