Pull request #197: RED-3243
Merge in RED/persistence-service from RED-3243 to master * commit 'd8d9b1c2a7b4ff6db0727e89931280b861ac7305': RED-3243: Fixed not working tests RED-3243 Added db and api for ImportedAnnotations (either finished nor working) RED-3243: Read redaction annotation from preview documents
This commit is contained in:
commit
420e380d4a
@ -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;
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
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 ImportedAnnotation {
|
||||
|
||||
private String annotationId;
|
||||
private String fileId;
|
||||
private List<Rectangle> positions = new ArrayList<>();
|
||||
private ImportedAnnotationStatus status;
|
||||
private String user;
|
||||
private String comment;
|
||||
private OffsetDateTime processedDate;
|
||||
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.model.annotations;
|
||||
|
||||
public enum ImportedAnnotationStatus {
|
||||
NEW,
|
||||
APPROVED,
|
||||
DECLINED,
|
||||
ADDED
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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 = "fileId";
|
||||
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_PATH_PARAM) String annotationId);
|
||||
|
||||
|
||||
@PostMapping(value = IMPORTED_ANNOTATION_PATH + FILE_ID_PATH_PARAM)
|
||||
void insert(@PathVariable(FILE_ID_PARAM) String fileId,
|
||||
@RequestBody AddImportedAnnotationRequest annotation);
|
||||
|
||||
|
||||
@PostMapping(value = IMPORTED_ANNOTATION_PATH + FILE_ID_PATH_PARAM + ANNOTATION_ID_PATH_PARAM)
|
||||
void updateStatus(@PathVariable(FILE_ID_PARAM) String fileId,
|
||||
@PathVariable(ANNOTATION_ID_PATH_PARAM) String annotationId,
|
||||
@RequestBody UpdateImportedAnnotationStatusRequest UpdateImportedAnnotationRequest);
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
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) {
|
||||
|
||||
return importedAnnotationRepository.findByIdFileId(fileId);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
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.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);
|
||||
}
|
||||
|
||||
|
||||
@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_PATH_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_PATH_PARAM) String annotationId) {
|
||||
|
||||
importedAnnotationPersistenceService.delete(fileId, annotationId);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
@ -47,6 +49,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 +71,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");
|
||||
}
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
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: TODO-positions
|
||||
type: TIMESTAMP WITHOUT TIME ZONE
|
||||
- column:
|
||||
name: TODO-file_status_id
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: comment
|
||||
type: VARCHAR(255)
|
||||
tableName: imported_annotation
|
||||
@ -7,3 +7,5 @@ databaseChangeLog:
|
||||
file: db/changelog/3-added-annotation-modification-date.changelog.yaml
|
||||
- include:
|
||||
file: db/changelog/4-archived-dossier.changelog.yaml
|
||||
- include:
|
||||
file: db/changelog/5-imported-annotation.changelog.yaml
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<properties>
|
||||
<redaction-service.version>3.56.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.28.0</pdftron-redaction-service.version>
|
||||
<redaction-report-service.version>3.19.0</redaction-report-service.version>
|
||||
</properties>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user