RED-8339: Component Overrides in DocuMine
This commit is contained in:
parent
9e70d9e199
commit
9079ae18af
@ -3,30 +3,21 @@ package com.iqser.red.persistence.service.v1.external.api.impl.controller;
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_RSS;
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_REDACTION_LOG;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
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 org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentLogService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentOverrideService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.external.resource.ComponentLogResource;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntryValue;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -35,15 +26,15 @@ import lombok.experimental.FieldDefaults;
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
@Deprecated(forRemoval = true)
|
||||
public class ComponentLogController implements ComponentLogResource {
|
||||
|
||||
ComponentLogService componentLogService;
|
||||
ComponentOverrideService componentOverrideService;
|
||||
AuditPersistenceService auditPersistenceService;
|
||||
AccessControlService accessControlService;
|
||||
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@PreAuthorize("hasAuthority('" + READ_REDACTION_LOG + "')")
|
||||
public ComponentLog getComponentLog(String dossierId, String fileId, boolean includeOverrides) {
|
||||
|
||||
@ -54,134 +45,42 @@ public class ComponentLogController implements ComponentLogResource {
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void addOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody ComponentsOverrides componentsOverrides) {
|
||||
public RedirectView addOverride(String dossierTemplateId,
|
||||
@PathVariable(DOSSIER_ID) String dossierId,
|
||||
@PathVariable(FILE_ID) String fileId,
|
||||
@RequestBody ComponentLogEntry override) {
|
||||
|
||||
accessControlService.checkDossierExistenceAndAccessPermissionsToDossier(dossierId);
|
||||
accessControlService.validateFileResourceExistence(fileId);
|
||||
|
||||
if (componentsOverrides.getComponentOverrides() == null || componentsOverrides.getComponentOverrides().isEmpty()) {
|
||||
throw new BadRequestException("Request body cannot be empty!");
|
||||
}
|
||||
var componentLog = componentLogService.getComponentLog(dossierId, fileId);
|
||||
var allComponents = componentLog.getComponentLogEntries();
|
||||
|
||||
componentOverrideService.addOverrides(dossierId, fileId, componentsOverrides);
|
||||
|
||||
componentsOverrides.getComponentOverrides()
|
||||
.forEach((componentName, overrideValue) -> auditOverride(dossierId, fileId, componentName, overrideValue, allComponents));
|
||||
return new RedirectView(String.format("/api/dossier-templates/{%s}/dossiers/{%s}/files/{%s}/overrides", dossierTemplateId, dossierId, fileId), true);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public ComponentsOverrides getOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId) {
|
||||
public RedirectView getOverrides(String dossierTemplateId, @PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId) {
|
||||
|
||||
accessControlService.checkDossierExistenceAndViewPermissionsToDossier(dossierId);
|
||||
accessControlService.validateFileResourceExistence(fileId);
|
||||
return componentOverrideService.getOverrides(dossierId, fileId);
|
||||
|
||||
return new RedirectView(String.format("/api/dossier-templates/{%s}/dossiers/{%s}/files/{%s}/overrides", dossierTemplateId, dossierId, fileId), true);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + "/revert" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void revertOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest) {
|
||||
public RedirectView revertOverrides(String dossierTemplateId,
|
||||
@PathVariable(DOSSIER_ID) String dossierId,
|
||||
@PathVariable(FILE_ID) String fileId,
|
||||
@RequestBody RevertOverrideRequest revertOverrideRequest) {
|
||||
|
||||
accessControlService.checkDossierExistenceAndAccessPermissionsToDossier(dossierId);
|
||||
accessControlService.validateFileResourceExistence(fileId);
|
||||
|
||||
if (revertOverrideRequest.getComponents() == null || revertOverrideRequest.getComponents().isEmpty()) {
|
||||
throw new BadRequestException("Request body cannot be empty!");
|
||||
}
|
||||
var componentLog = componentLogService.getComponentLog(dossierId, fileId);
|
||||
var allComponents = componentLog.getComponentLogEntries();
|
||||
|
||||
componentOverrideService.revertOverrides(dossierId, fileId, revertOverrideRequest);
|
||||
|
||||
revertOverrideRequest.getComponents()
|
||||
.forEach(componentNameToRevert -> auditOverrideRevert(dossierId, fileId, componentNameToRevert, allComponents));
|
||||
}
|
||||
|
||||
|
||||
private void auditOverride(String dossierId, String fileId, String componentName, String overrideValue, List<ComponentLogEntry> allComponentLogEntries) {
|
||||
|
||||
Optional<ComponentLogEntry> component = allComponentLogEntries.stream()
|
||||
.filter(c -> c.getName().equals(componentName))
|
||||
.findFirst();
|
||||
String originalValue = getOriginalValue(component);
|
||||
String value = getValue(component);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component is overwritten with value")
|
||||
.details(Map.of(DOSSIER_ID,
|
||||
dossierId,
|
||||
FILE_ID,
|
||||
fileId,
|
||||
"ComponentName",
|
||||
componentName,
|
||||
"Action",
|
||||
"MODIFY",
|
||||
"OriginalValue",
|
||||
originalValue,
|
||||
"OldValue",
|
||||
value,
|
||||
"NewValue",
|
||||
overrideValue))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
private void auditOverrideRevert(String dossierId, String fileId, String componentNameToRevert, List<ComponentLogEntry> allComponentLogEntries) {
|
||||
|
||||
Optional<ComponentLogEntry> component = allComponentLogEntries.stream()
|
||||
.filter(c -> c.getName().equals(componentNameToRevert))
|
||||
.findFirst();
|
||||
String originalValue = getOriginalValue(component);
|
||||
String value = getValue(component);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component override for was reverted")
|
||||
.details(Map.of(DOSSIER_ID,
|
||||
dossierId,
|
||||
FILE_ID,
|
||||
fileId,
|
||||
"ComponentName",
|
||||
componentNameToRevert,
|
||||
"Action",
|
||||
"REVERT",
|
||||
"OriginalValue",
|
||||
originalValue,
|
||||
"OldValue",
|
||||
value,
|
||||
"NewValue",
|
||||
originalValue))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
private String getValue(Optional<ComponentLogEntry> component) {
|
||||
|
||||
return component.map(ComponentLogEntry::getComponentValues)
|
||||
.stream()
|
||||
.map(a -> a.stream()
|
||||
.map(ComponentLogEntryValue::getValue)
|
||||
.collect(Collectors.joining(", ")))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
|
||||
private static String getOriginalValue(Optional<ComponentLogEntry> component) {
|
||||
|
||||
return component.map(ComponentLogEntry::getComponentValues)
|
||||
.stream()
|
||||
.map(a -> a.stream()
|
||||
.map(ComponentLogEntryValue::getOriginalValue)
|
||||
.collect(Collectors.joining(", ")))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
return new RedirectView(String.format("/api/dossier-templates/{%s}/dossiers/{%s}/files/{%s}/overrides/revert", dossierTemplateId, dossierId, fileId), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,287 +0,0 @@
|
||||
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
|
||||
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_RSS;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentLogService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentOverrideService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.external.resource.RSSResource;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntityReference;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntryValue;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.rss.RSSFileResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.rss.RSSResponse;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.rss.DetailedRSSFileResponse;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.rss.DetailedRSSResponse;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.rss.SCMComponent;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.rss.ScmAnnotation;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "application.rss.component-log.enabled", havingValue = "true")
|
||||
public class RSSComponentLogController implements RSSResource {
|
||||
|
||||
private final ComponentOverrideService componentOverrideService;
|
||||
private final AuditPersistenceService auditPersistenceService;
|
||||
private final ComponentLogService componentLogService;
|
||||
private final StatusController statusController;
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public RSSResponse getRSS(@PathVariable(DOSSIER_ID) String dossierId, @RequestParam(value = "fileId", required = false) String fileId) {
|
||||
|
||||
List<FileStatus> dossierFiles;
|
||||
if (StringUtils.isBlank(fileId)) {
|
||||
dossierFiles = statusController.getDossierStatus(dossierId);
|
||||
} else {
|
||||
dossierFiles = List.of(statusController.getFileStatus(dossierId, fileId));
|
||||
}
|
||||
|
||||
List<RSSFileResponse> fileResponses = dossierFiles.stream()
|
||||
.map(this::getRssResponse)
|
||||
.toList();
|
||||
|
||||
return new RSSResponse(fileResponses);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private RSSFileResponse getRssResponse(FileStatus file) {
|
||||
|
||||
var componentLog = componentLogService.getComponentLog(file.getDossierId(), file.getId(), true);
|
||||
|
||||
Map<String, String> results = new LinkedHashMap<>();
|
||||
|
||||
componentLog.getComponentLogEntries()
|
||||
.forEach(entry -> {
|
||||
if (entry.getComponentValues().size() <= 1) {
|
||||
results.put(entry.getName(),
|
||||
entry.getComponentValues()
|
||||
.get(0).getValue());
|
||||
return;
|
||||
}
|
||||
|
||||
List<ComponentLogEntryValue> componentValues = entry.getComponentValues();
|
||||
for (int i = 0, componentValuesSize = componentValues.size(); i < componentValuesSize; i++) {
|
||||
ComponentLogEntryValue v = componentValues.get(i);
|
||||
results.put(entry.getName() + "_" + (i + 1), v.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
return RSSFileResponse.builder().filename(file.getFilename()).result(results).build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public DetailedRSSResponse getDetailedRSS(@PathVariable(DOSSIER_ID) String dossierId, @RequestParam(value = "fileId", required = false) String fileId) {
|
||||
|
||||
List<FileStatus> dossierFiles;
|
||||
if (StringUtils.isBlank(fileId)) {
|
||||
dossierFiles = statusController.getDossierStatus(dossierId);
|
||||
} else {
|
||||
dossierFiles = List.of(statusController.getFileStatus(dossierId, fileId));
|
||||
}
|
||||
|
||||
List<DetailedRSSFileResponse> fileResponses = dossierFiles.stream()
|
||||
.map(this::getDetailedRssResponse)
|
||||
.toList();
|
||||
|
||||
return new DetailedRSSResponse(fileResponses);
|
||||
}
|
||||
|
||||
|
||||
private DetailedRSSFileResponse getDetailedRssResponse(FileStatus file) {
|
||||
|
||||
var componentLog = componentLogService.getComponentLog(file.getDossierId(), file.getId(), true);
|
||||
|
||||
Map<String, SCMComponent> results = new LinkedHashMap<>();
|
||||
|
||||
componentLog.getComponentLogEntries()
|
||||
.forEach(entry -> {
|
||||
if (entry.getComponentValues().size() <= 1) {
|
||||
results.put(entry.getName(),
|
||||
toSCMComponent(entry.getComponentValues()
|
||||
.get(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
List<ComponentLogEntryValue> componentValues = entry.getComponentValues();
|
||||
for (int i = 0, componentValuesSize = componentValues.size(); i < componentValuesSize; i++) {
|
||||
ComponentLogEntryValue v = componentValues.get(i);
|
||||
results.put(entry.getName() + "_" + (i + 1), toSCMComponent(v));
|
||||
}
|
||||
});
|
||||
|
||||
return DetailedRSSFileResponse.builder().filename(file.getFilename()).result(results).build();
|
||||
}
|
||||
|
||||
|
||||
private SCMComponent toSCMComponent(ComponentLogEntryValue v) {
|
||||
|
||||
return SCMComponent.builder()
|
||||
.value(v.getValue().equals(v.getOriginalValue()) ? null : v.getValue())
|
||||
.originalValue(v.getOriginalValue())
|
||||
.transformation(v.getValueDescription())
|
||||
.scmAnnotations(v.getComponentLogEntityReferences()
|
||||
.stream()
|
||||
.map(this::toScmAnnotation)
|
||||
.toList())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
private ScmAnnotation toScmAnnotation(ComponentLogEntityReference er) {
|
||||
|
||||
return ScmAnnotation.builder().type(er.getType()).pages(Set.of(er.getPage())).ruleIdentifier(er.getEntityRuleId()).reason(formatType(er.getType())).build();
|
||||
}
|
||||
|
||||
|
||||
private static String formatType(String type) {
|
||||
|
||||
return type.substring(0, 1).toUpperCase(Locale.ENGLISH) + type.substring(1).toLowerCase(Locale.ENGLISH).replaceAll("_", " ");
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void addOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody ComponentsOverrides componentsOverrides) {
|
||||
|
||||
var componentLog = componentLogService.getComponentLog(dossierId, fileId);
|
||||
var allComponents = componentLog.getComponentLogEntries();
|
||||
|
||||
componentOverrideService.addOverrides(dossierId, fileId, componentsOverrides);
|
||||
|
||||
componentsOverrides.getComponentOverrides()
|
||||
.forEach((componentName, overrideValue) -> auditOverride(dossierId, fileId, componentName, overrideValue, allComponents));
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public ComponentsOverrides getOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId) {
|
||||
|
||||
return componentOverrideService.getOverrides(dossierId, fileId);
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void revertOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest) {
|
||||
|
||||
var componentLog = componentLogService.getComponentLog(dossierId, fileId);
|
||||
var allComponents = componentLog.getComponentLogEntries();
|
||||
|
||||
componentOverrideService.revertOverrides(dossierId, fileId, revertOverrideRequest);
|
||||
|
||||
revertOverrideRequest.getComponents()
|
||||
.forEach(componentNameToRevert -> auditOverrideRevert(dossierId, fileId, componentNameToRevert, allComponents));
|
||||
}
|
||||
|
||||
|
||||
private void auditOverride(String dossierId, String fileId, String componentName, String overrideValue, List<ComponentLogEntry> allComponentLogEntries) {
|
||||
|
||||
Optional<ComponentLogEntry> component = allComponentLogEntries.stream()
|
||||
.filter(c -> c.getName().equals(componentName))
|
||||
.findFirst();
|
||||
String originalValue = getOriginalValue(component);
|
||||
String value = getValue(component);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component is overwritten with value")
|
||||
.details(Map.of(DOSSIER_ID,
|
||||
dossierId,
|
||||
FILE_ID,
|
||||
fileId,
|
||||
"ComponentName",
|
||||
componentName,
|
||||
"Action",
|
||||
"MODIFY",
|
||||
"OriginalValue",
|
||||
originalValue,
|
||||
"OldValue",
|
||||
value,
|
||||
"NewValue",
|
||||
overrideValue))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
private void auditOverrideRevert(String dossierId, String fileId, String componentNameToRevert, List<ComponentLogEntry> allComponentLogEntries) {
|
||||
|
||||
Optional<ComponentLogEntry> component = allComponentLogEntries.stream()
|
||||
.filter(c -> c.getName().equals(componentNameToRevert))
|
||||
.findFirst();
|
||||
String originalValue = getOriginalValue(component);
|
||||
String value = getValue(component);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component override for was reverted")
|
||||
.details(Map.of(DOSSIER_ID,
|
||||
dossierId,
|
||||
FILE_ID,
|
||||
fileId,
|
||||
"ComponentName",
|
||||
componentNameToRevert,
|
||||
"Action",
|
||||
"REVERT",
|
||||
"OriginalValue",
|
||||
originalValue,
|
||||
"OldValue",
|
||||
value,
|
||||
"NewValue",
|
||||
originalValue))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
private String getValue(Optional<ComponentLogEntry> component) {
|
||||
|
||||
return component.map(ComponentLogEntry::getComponentValues)
|
||||
.stream()
|
||||
.map(a -> a.stream()
|
||||
.map(ComponentLogEntryValue::getValue)
|
||||
.collect(Collectors.joining(", ")))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
|
||||
private static String getOriginalValue(Optional<ComponentLogEntry> component) {
|
||||
|
||||
return component.map(ComponentLogEntry::getComponentValues)
|
||||
.stream()
|
||||
.map(a -> a.stream()
|
||||
.map(ComponentLogEntryValue::getOriginalValue)
|
||||
.collect(Collectors.joining(", ")))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,148 +0,0 @@
|
||||
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
|
||||
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_RSS;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.client.redactionreportservice.RssReportClient;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentOverrideService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.external.resource.RSSResource;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.rss.RSSFileResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.rss.RSSResponse;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.rss.DetailedRSSResponse;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "application.rss.component-log.enabled", havingValue = "false")
|
||||
public class RSSController implements RSSResource {
|
||||
|
||||
private final RssReportClient rssReportClient;
|
||||
private final ComponentOverrideService componentOverrideService;
|
||||
private final AuditPersistenceService auditPersistenceService;
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public RSSResponse getRSS(@PathVariable(DOSSIER_ID) String dossierId, @RequestParam(value = "fileId", required = false) String fileId) {
|
||||
|
||||
return convert(rssReportClient.getRSS(dossierId, fileId));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
private RSSResponse convert(com.iqser.red.service.redaction.report.v1.api.model.rss.RSSResponse rssResponse) {
|
||||
|
||||
return new RSSResponse(rssResponse.getFiles()
|
||||
.stream()
|
||||
.map(this::convert)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
private RSSFileResponse convert(com.iqser.red.service.redaction.report.v1.api.model.rss.RSSFileResponse rssFileResponse) {
|
||||
|
||||
return new RSSFileResponse(rssFileResponse.getFilename(), rssFileResponse.getResult());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public DetailedRSSResponse getDetailedRSS(@PathVariable(DOSSIER_ID) String dossierId, @RequestParam(value = "fileId", required = false) String fileId) {
|
||||
|
||||
return rssReportClient.getDetailedRSS(dossierId, fileId);
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void addOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody ComponentsOverrides componentsOverrides) {
|
||||
|
||||
var rssReport = rssReportClient.getDetailedRSS(dossierId, fileId);
|
||||
var components = rssReport.getFiles()
|
||||
.get(0).getResult();
|
||||
|
||||
componentOverrideService.addOverrides(dossierId, fileId, componentsOverrides);
|
||||
|
||||
componentsOverrides.getComponentOverrides()
|
||||
.forEach((key, value) -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component is overwritten with value")
|
||||
.details(Map.of(DOSSIER_ID,
|
||||
dossierId,
|
||||
FILE_ID,
|
||||
fileId,
|
||||
"ComponentName",
|
||||
key,
|
||||
"Action",
|
||||
"MODIFY",
|
||||
"OriginalValue",
|
||||
components.get(key).getOriginalValue(),
|
||||
"OldValue",
|
||||
components.get(key).getValue() != null ? components.get(key)
|
||||
.getValue() : components.get(key).getOriginalValue(),
|
||||
"NewValue",
|
||||
value))
|
||||
.build()));
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public ComponentsOverrides getOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId) {
|
||||
|
||||
return componentOverrideService.getOverrides(dossierId, fileId);
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void revertOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest) {
|
||||
|
||||
var rssReport = rssReportClient.getDetailedRSS(dossierId, fileId);
|
||||
var components = rssReport.getFiles()
|
||||
.get(0).getResult();
|
||||
|
||||
componentOverrideService.revertOverrides(dossierId, fileId, revertOverrideRequest);
|
||||
|
||||
revertOverrideRequest.getComponents()
|
||||
.forEach(component -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component override for was reverted")
|
||||
.details(Map.of(DOSSIER_ID,
|
||||
dossierId,
|
||||
FILE_ID,
|
||||
fileId,
|
||||
"ComponentName",
|
||||
component,
|
||||
"Action",
|
||||
"REVERT",
|
||||
"OriginalValue",
|
||||
components.get(component).getOriginalValue(),
|
||||
"OldValue",
|
||||
components.get(component).getValue() != null ? components.get(component)
|
||||
.getValue() : components.get(component).getOriginalValue(),
|
||||
"NewValue",
|
||||
components.get(component).getOriginalValue()))
|
||||
.build()));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,27 +1,25 @@
|
||||
package com.iqser.red.persistence.service.v2.external.api.impl.controller;
|
||||
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_RSS;
|
||||
import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierResource.DOSSIER_ID_PARAM;
|
||||
import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.DOSSIER_TEMPLATE_ID_PARAM;
|
||||
import static com.iqser.red.service.persistence.service.v2.api.external.resource.FileResource.FILE_ID_PARAM;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierTemplateController;
|
||||
import com.iqser.red.persistence.service.v1.external.api.impl.controller.StatusController;
|
||||
import com.iqser.red.persistence.service.v2.external.api.impl.mapper.ComponentMapper;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentLogService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntityReference;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntryValue;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.Component;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentValue;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.EntityReference;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentOverrideModelList;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponents;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponentsList;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.resource.ComponentResource;
|
||||
@ -37,10 +35,12 @@ import lombok.experimental.FieldDefaults;
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
public class ComponentControllerV2 implements ComponentResource {
|
||||
|
||||
DossierTemplateController dossierTemplateController;
|
||||
ComponentLogService componentLogService;
|
||||
StatusController statusController;
|
||||
FileStatusService fileStatusService;
|
||||
DossierTemplatePersistenceService dossierTemplatePersistenceService;
|
||||
ComponentMapper componentMapper = ComponentMapper.INSTANCE;
|
||||
|
||||
|
||||
@Override
|
||||
@ -52,65 +52,7 @@ public class ComponentControllerV2 implements ComponentResource {
|
||||
dossierTemplatePersistenceService.checkDossierTemplateExistsOrElseThrow404(dossierTemplateId);
|
||||
var componentLog = componentLogService.getComponentLog(dossierId, fileId, true);
|
||||
|
||||
Map<String, List<String>> basicComponent = new LinkedHashMap<>();
|
||||
for (ComponentLogEntry componentLogEntry : componentLog.getComponentLogEntries()) {
|
||||
basicComponent.put(componentLogEntry.getName(),
|
||||
componentLogEntry.getComponentValues()
|
||||
.stream()
|
||||
.map(ComponentLogEntryValue::getValue)
|
||||
.toList());
|
||||
}
|
||||
|
||||
Map<String, Component> componentsDetails = new LinkedHashMap<>();
|
||||
if (includeDetails) {
|
||||
for (ComponentLogEntry entry : componentLog.getComponentLogEntries()) {
|
||||
componentsDetails.put(entry.getName(), Component.builder().name(entry.getName()).componentValues(toComponentList(entry)).build());
|
||||
}
|
||||
}
|
||||
|
||||
return FileComponents.builder()
|
||||
.dossierTemplateId(dossierTemplateId)
|
||||
.dossierId(dossierId)
|
||||
.filename(fileStatusService.getFileName(fileId))
|
||||
.fileId(fileId)
|
||||
.components(basicComponent)
|
||||
.componentDetails(componentsDetails)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
private List<ComponentValue> toComponentList(ComponentLogEntry componentLogEntry) {
|
||||
|
||||
return componentLogEntry.getComponentValues()
|
||||
.stream()
|
||||
.map(this::convert)
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
private ComponentValue convert(ComponentLogEntryValue componentValue) {
|
||||
|
||||
return ComponentValue.builder()
|
||||
.valueDescription(componentValue.getValueDescription())
|
||||
.componentRuleId(componentValue.getComponentRuleId())
|
||||
.entityReferences(componentValue.getComponentLogEntityReferences()
|
||||
.stream()
|
||||
.map(this::convertComponentEntityReference)
|
||||
.toList())
|
||||
.originalValue(componentValue.getOriginalValue())
|
||||
.value(componentValue.getValue())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
private EntityReference convertComponentEntityReference(ComponentLogEntityReference componentLogEntityReference) {
|
||||
|
||||
return EntityReference.builder()
|
||||
.id(componentLogEntityReference.getId())
|
||||
.entityRuleId(componentLogEntityReference.getEntityRuleId())
|
||||
.type(componentLogEntityReference.getType())
|
||||
.page(componentLogEntityReference.getPage())
|
||||
.build();
|
||||
return componentMapper.toFileComponents(componentLog, dossierTemplateId, dossierId, fileId, fileStatusService.getFileName(fileId), includeDetails);
|
||||
}
|
||||
|
||||
|
||||
@ -127,4 +69,44 @@ public class ComponentControllerV2 implements ComponentResource {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void addOverride(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@PathVariable(FILE_ID_PARAM) String fileId,
|
||||
@RequestBody Component override) {
|
||||
|
||||
dossierTemplateController.getDossierTemplate(dossierTemplateId);
|
||||
|
||||
componentLogService.addOverride(dossierId, fileId, componentMapper.toComponentLogEntry(override));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public ComponentOverrideModelList getOverrides(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@PathVariable(FILE_ID_PARAM) String fileId) {
|
||||
|
||||
dossierTemplateController.getDossierTemplate(dossierTemplateId);
|
||||
|
||||
var overrides = componentLogService.getOverrides(dossierId, fileId);
|
||||
var componentOverrides = componentMapper.toComponents(overrides);
|
||||
|
||||
return ComponentOverrideModelList.builder().dossierTemplateId(dossierTemplateId).dossierId(dossierId).fileId(fileId).componentOverrideModels(componentOverrides).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + GET_RSS + "')")
|
||||
public void revertOverrides(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@PathVariable(FILE_ID_PARAM) String fileId,
|
||||
@RequestBody RevertOverrideRequest revertOverrideRequest) {
|
||||
|
||||
dossierTemplateController.getDossierTemplate(dossierTemplateId);
|
||||
|
||||
componentLogService.revertOverrides(dossierId, fileId, revertOverrideRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
package com.iqser.red.persistence.service.v2.external.api.impl.mapper;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntryValue;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.Component;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentValue;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponents;
|
||||
|
||||
@Mapper
|
||||
public interface ComponentMapper {
|
||||
|
||||
ComponentMapper INSTANCE = Mappers.getMapper(ComponentMapper.class);
|
||||
|
||||
|
||||
@Mapping(source = "componentLogEntityReferences", target = "entityReferences")
|
||||
ComponentValue toComponentValue(ComponentLogEntryValue entry);
|
||||
|
||||
|
||||
@Mapping(source = "entityReferences", target = "componentLogEntityReferences")
|
||||
ComponentLogEntryValue toComponentLogEntry(ComponentValue value);
|
||||
|
||||
|
||||
List<ComponentValue> toComponentValues(List<ComponentLogEntryValue> entries);
|
||||
|
||||
|
||||
List<ComponentLogEntryValue> toComponentLogEntries(List<ComponentValue> values);
|
||||
|
||||
@Mapping(source = "componentValues", target = "componentValues")
|
||||
Component toComponent(ComponentLogEntry entry);
|
||||
|
||||
|
||||
List<Component> toComponents(List<ComponentLogEntry> entries);
|
||||
|
||||
@Mapping(source = "componentValues", target = "componentValues")
|
||||
ComponentLogEntry toComponentLogEntry(Component component);
|
||||
|
||||
|
||||
default FileComponents toFileComponents(ComponentLog componentLog, String dossierTemplateId, String dossierId, String fileId, String fileName, boolean includeDetails) {
|
||||
|
||||
Map<String, List<String>> basicComponent = new LinkedHashMap<>();
|
||||
for (ComponentLogEntry componentLogEntry : componentLog.getComponentLogEntries()) {
|
||||
basicComponent.put(componentLogEntry.getName(),
|
||||
componentLogEntry.getComponentValues()
|
||||
.stream()
|
||||
.map(ComponentLogEntryValue::getValue)
|
||||
.toList());
|
||||
}
|
||||
|
||||
Map<String, Component> componentsDetails = new LinkedHashMap<>();
|
||||
if (includeDetails) {
|
||||
for (ComponentLogEntry entry : componentLog.getComponentLogEntries()) {
|
||||
componentsDetails.put(entry.getName(), toComponent(entry));
|
||||
}
|
||||
}
|
||||
|
||||
return FileComponents.builder()
|
||||
.dossierTemplateId(dossierTemplateId)
|
||||
.dossierId(dossierId)
|
||||
.filename(fileName)
|
||||
.fileId(fileId)
|
||||
.components(basicComponent)
|
||||
.componentDetails(componentsDetails)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,9 +9,10 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -25,11 +26,13 @@ public interface ComponentLogResource {
|
||||
|
||||
String OVERRIDE_PATH = "/override";
|
||||
|
||||
String DOSSIER_TEMPLATE_ID = "dossierTemplateId";
|
||||
String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID + "}";
|
||||
|
||||
String DOSSIER_ID = "dossierId";
|
||||
String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID + "}";
|
||||
|
||||
String FILE_ID = "fileId";
|
||||
|
||||
String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}";
|
||||
|
||||
|
||||
@ -46,7 +49,7 @@ public interface ComponentLogResource {
|
||||
@PostMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Adds overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
void addOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody ComponentsOverrides componentsOverrides);
|
||||
RedirectView addOverride(String dossierTemplateId, @PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody ComponentLogEntry override);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ -54,7 +57,7 @@ public interface ComponentLogResource {
|
||||
@GetMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Gets overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
|
||||
ComponentsOverrides getOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
||||
RedirectView getOverrides(String dossierTemplateId, @PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ -62,6 +65,6 @@ public interface ComponentLogResource {
|
||||
@PostMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + "/revert" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Reverts overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
void revertOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest);
|
||||
RedirectView revertOverrides(String dossierTemplateId, @PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest);
|
||||
|
||||
}
|
||||
|
||||
@ -1,76 +0,0 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.external.resource;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
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 org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.rss.RSSResponse;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.rss.DetailedRSSResponse;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public interface RSSResource {
|
||||
|
||||
String RSS_PATH = ExternalApi.BASE_PATH + "/rss";
|
||||
String OVERRIDE_PATH = "/override";
|
||||
|
||||
String DOSSIER_ID = "dossierId";
|
||||
String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID + "}";
|
||||
|
||||
String FILE_ID = "fileId";
|
||||
String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}";
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@GetMapping(value = RSS_PATH + DOSSIER_ID_PATH_VARIABLE, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
|
||||
@Operation(summary = "Returns the RSS response for a dossier", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
RSSResponse getRSS(@PathVariable(DOSSIER_ID) String dossierId, @RequestParam(value = "fileId", required = false) String fileId);
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@GetMapping(value = RSS_PATH + "/detailed" + DOSSIER_ID_PATH_VARIABLE, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
|
||||
@Operation(summary = "Returns the RSS response with more details for a dossier", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
DetailedRSSResponse getDetailedRSS(@PathVariable(DOSSIER_ID) String dossierId, @RequestParam(value = "fileId", required = false) String fileId);
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
@PostMapping(value = RSS_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Adds overrides for RSS components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
void addOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody ComponentsOverrides componentsOverrides);
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
@GetMapping(value = RSS_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Gets overrides for RSS components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
ComponentsOverrides getOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
@PostMapping(value = RSS_PATH + OVERRIDE_PATH + "/revert" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Reverts overrides for RSS components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
void revertOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest);
|
||||
|
||||
}
|
||||
@ -19,5 +19,7 @@ public class Component {
|
||||
private String name;
|
||||
@JacksonXmlCData
|
||||
private List<ComponentValue> componentValues;
|
||||
@JacksonXmlCData
|
||||
private boolean overridden;
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.iqser.red.service.persistence.service.v2.api.external.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ComponentOverrideModelList {
|
||||
|
||||
String dossierTemplateId;
|
||||
String dossierId;
|
||||
String fileId;
|
||||
|
||||
List<Component> componentOverrideModels = new ArrayList<>();
|
||||
}
|
||||
@ -18,6 +18,7 @@ public class ComponentValue {
|
||||
@JacksonXmlCData
|
||||
String value;
|
||||
@JacksonXmlCData
|
||||
@Deprecated
|
||||
String originalValue;
|
||||
@JacksonXmlCData
|
||||
String valueDescription;
|
||||
|
||||
@ -11,26 +11,22 @@ import static com.iqser.red.service.persistence.service.v2.api.external.resource
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
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.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingMetadataModel;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingSummary;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.Component;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentOverrideModelList;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponents;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponentsList;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
|
||||
@ -49,10 +45,15 @@ public interface ComponentResource {
|
||||
|
||||
String INCLUDE_DETAILS_DESCRIPTION = """
|
||||
A toggle to decide whether to include detailed component information in the response:
|
||||
|
||||
- true: The component object's field componentDetails stores detailed information about the source of its respective value(s).
|
||||
- false (default): The component object does not contain a field componentDetails.
|
||||
""";
|
||||
|
||||
String OVERRIDES_PATH = "/overrides";
|
||||
String REVERT_PATH = "/revert";
|
||||
|
||||
String COMPONENT_OVERRIDE_PARAM = "componentOverride";
|
||||
|
||||
|
||||
@GetMapping(value = FILE_PATH + FILE_ID_PATH_VARIABLE + COMPONENTS_PATH, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
|
||||
@ -72,5 +73,35 @@ public interface ComponentResource {
|
||||
@Parameter(name = INCLUDE_DETAILS_PARAM, description = INCLUDE_DETAILS_DESCRIPTION) @RequestParam(name = INCLUDE_DETAILS_PARAM, defaultValue = "false", required = false) boolean includeDetails);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
@PostMapping(value = PATH + FILE_ID_PATH_VARIABLE + OVERRIDES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Adds overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
void addOverride(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@Parameter(name = FILE_ID_PARAM, description = "The identifier of the file that the components are requested for.", required = true) @PathVariable(FILE_ID_PARAM) String fileId,
|
||||
@Parameter(name = COMPONENT_OVERRIDE_PARAM, description = "The object to override the component.", required = true) @RequestBody Component componentOverrideModel);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
@GetMapping(value = PATH + FILE_ID_PATH_VARIABLE + OVERRIDES_PATH, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
|
||||
@Operation(summary = "Gets overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
|
||||
ComponentOverrideModelList getOverrides(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@Parameter(name = FILE_ID_PARAM, description = "The identifier of the file that the components are requested for.", required = true) @PathVariable(FILE_ID_PARAM) String fileId);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
@PostMapping(value = PATH + FILE_ID_PATH_VARIABLE + OVERRIDES_PATH + REVERT_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Reverts overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
void revertOverrides(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@Parameter(name = FILE_ID_PARAM, description = "The identifier of the file that the components are requested for.", required = true) @PathVariable(FILE_ID_PARAM) String fileId,
|
||||
@RequestBody RevertOverrideRequest revertOverrideRequest);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntryValue;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ComponentOverride {
|
||||
|
||||
String name;
|
||||
List<ComponentLogEntryValue> componentOverrideValues = new ArrayList<>();
|
||||
}
|
||||
@ -2,13 +2,19 @@ package com.iqser.red.service.persistence.management.v1.processor.service;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.ComponentLogMongoService;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -19,7 +25,8 @@ import lombok.experimental.FieldDefaults;
|
||||
public class ComponentLogService {
|
||||
|
||||
private final FileManagementStorageService fileManagementStorageService;
|
||||
private final ComponentOverrideService componentOverrideService;
|
||||
private final ComponentLogMongoService componentLogMongoService;
|
||||
private final AuditPersistenceService auditPersistenceService;
|
||||
|
||||
// TODO: make this DB changeable!
|
||||
private static final List<String> ORDER = List.of("Study_Title",
|
||||
@ -65,30 +72,43 @@ public class ComponentLogService {
|
||||
|
||||
public ComponentLog getComponentLog(String dossierId, String fileId, boolean includeOverrides) {
|
||||
|
||||
ComponentLog componentLog = sortComponentLogEntriesByOrderList(fileManagementStorageService.getComponentLog(dossierId, fileId), ORDER);
|
||||
ComponentLog componentLog;
|
||||
try {
|
||||
componentLog = fileManagementStorageService.getComponentLog(dossierId, fileId);
|
||||
} catch (NotFoundException e) {
|
||||
var componentLogOptional = componentLogMongoService.findComponentLogByDossierIdAndFileId(dossierId, fileId);
|
||||
if (componentLogOptional.isEmpty()) {
|
||||
throw new NotFoundException(e.getMessage());
|
||||
}
|
||||
componentLog = componentLogOptional.get();
|
||||
}
|
||||
|
||||
if (!includeOverrides) {
|
||||
componentLog = sortComponentLogEntriesByOrderList(componentLog, ORDER);
|
||||
return componentLog;
|
||||
}
|
||||
|
||||
ComponentsOverrides componentsOverrides = componentOverrideService.getOverrides(dossierId, fileId);
|
||||
if (Objects.isNull(componentsOverrides.getComponentOverrides()) || componentsOverrides.getComponentOverrides().isEmpty()) {
|
||||
return componentLog;
|
||||
}
|
||||
List<ComponentLogEntry> componentOverrides = getOverrides(dossierId, fileId);
|
||||
|
||||
List<ComponentLogEntry> overriddenComponentLogEntries = componentLog.getComponentLogEntries()
|
||||
.stream()
|
||||
.map(componentLogEntry -> applyOverride(componentLogEntry,
|
||||
componentsOverrides.getComponentOverrides()
|
||||
.get(componentLogEntry.getName())))
|
||||
.toList();
|
||||
replaceOverriddenComponentLogEntries(componentLog, componentOverrides);
|
||||
|
||||
componentLog.setComponentLogEntries(overriddenComponentLogEntries);
|
||||
componentLog = sortComponentLogEntriesByOrderList(componentLog, ORDER);
|
||||
return componentLog;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void replaceOverriddenComponentLogEntries(ComponentLog componentLog, List<ComponentLogEntry> componentOverrides) {
|
||||
// remove override entries from componentLog
|
||||
componentLog.getComponentLogEntries()
|
||||
.removeIf(entry -> componentOverrides.stream()
|
||||
.anyMatch(override -> entry.getName().equals(override.getName())));
|
||||
|
||||
// insert overrides to Component log
|
||||
componentLog.getComponentLogEntries().addAll(componentOverrides);
|
||||
}
|
||||
|
||||
|
||||
private ComponentLog sortComponentLogEntriesByOrderList(ComponentLog componentLog, List<String> order) {
|
||||
|
||||
return new ComponentLog(componentLog.getAnalysisNumber(),
|
||||
@ -107,14 +127,93 @@ public class ComponentLogService {
|
||||
}
|
||||
|
||||
|
||||
private ComponentLogEntry applyOverride(ComponentLogEntry componentLogEntry, String override) {
|
||||
public void addOverride(String dossierId, String fileId, ComponentLogEntry componentOverride) {
|
||||
|
||||
if (Objects.isNull(override)) {
|
||||
return componentLogEntry;
|
||||
var optionalComponentLogEntry = componentLogMongoService.findComponentLogEntryById(dossierId, fileId, componentOverride.getName());
|
||||
|
||||
if (optionalComponentLogEntry.isPresent()) {
|
||||
ComponentLogEntry componentToUpdate = optionalComponentLogEntry.get();
|
||||
componentToUpdate.setComponentValues(componentOverride.getComponentValues());
|
||||
saveOverride(dossierId, fileId, componentToUpdate);
|
||||
auditOverride(dossierId, fileId, componentToUpdate);
|
||||
} else {
|
||||
insertOverride(dossierId, fileId, componentOverride);
|
||||
auditOverride(dossierId, fileId, componentOverride);
|
||||
}
|
||||
componentLogEntry.getComponentValues()
|
||||
.forEach(componentValue -> componentValue.setValue(override));
|
||||
return componentLogEntry;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void saveOverride(String dossierId, String fileId, ComponentLogEntry componentToUpdate) {
|
||||
|
||||
componentLogMongoService.saveComponentLogEntries(dossierId, fileId, List.of(componentToUpdate));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void insertOverride(String dossierId, String fileId, ComponentLogEntry componentToAdd) {
|
||||
|
||||
componentLogMongoService.insertComponentLogEntries(dossierId, fileId, List.of(componentToAdd));
|
||||
}
|
||||
|
||||
|
||||
public List<ComponentLogEntry> getOverrides(String dossierId, String fileId) {
|
||||
|
||||
return componentLogMongoService.findOverrides(dossierId, fileId);
|
||||
}
|
||||
|
||||
|
||||
public void revertOverrides(String dossierId, String fileId, RevertOverrideRequest revertOverrideRequest) {
|
||||
|
||||
revertOverrideRequest.getComponents()
|
||||
.forEach(componentName -> {
|
||||
var componentLogEntry = componentLogMongoService.findComponentLogEntryById(dossierId, fileId, componentName)
|
||||
.orElseThrow(() -> new NotFoundException(String.format("Component %s was not found.", componentName)));
|
||||
|
||||
auditOverrideRevert(dossierId, fileId, componentLogEntry);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void auditOverride(String dossierId, String fileId, ComponentLogEntry entry) {
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component is overwritten with value")
|
||||
.details(Map.of("dossierId",
|
||||
dossierId,
|
||||
"fileId",
|
||||
fileId,
|
||||
"ComponentName",
|
||||
entry.getName(),
|
||||
"Action",
|
||||
"MODIFY",
|
||||
"Values",
|
||||
entry.getComponentValues()))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
private void auditOverrideRevert(String dossierId, String fileId, ComponentLogEntry entry) {
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("The component override for was reverted")
|
||||
.details(Map.of("dossierId",
|
||||
dossierId,
|
||||
"fileId",
|
||||
fileId,
|
||||
"ComponentName",
|
||||
entry.getName(),
|
||||
"Action",
|
||||
"REVERT",
|
||||
"Values",
|
||||
entry.getComponentValues()))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@ -148,4 +247,4 @@ public class ComponentLogService {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ComponentOverrideService {
|
||||
|
||||
private final FileManagementStorageService fileManagementStorageService;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void addOverrides(String dossierId, String fileId, ComponentsOverrides componentsOverrides) {
|
||||
|
||||
if (!fileManagementStorageService.objectExists(dossierId, fileId, FileType.COMPONENTS)) {
|
||||
fileManagementStorageService.storeObject(dossierId, fileId, FileType.COMPONENTS, new ByteArrayInputStream(objectMapper.writeValueAsBytes(componentsOverrides)));
|
||||
return;
|
||||
}
|
||||
|
||||
var existingComponentsBytes = fileManagementStorageService.getStoredObjectBytes(dossierId, fileId, FileType.COMPONENTS);
|
||||
var existingComponents = objectMapper.readValue(existingComponentsBytes, ComponentsOverrides.class);
|
||||
existingComponents.getComponentOverrides().putAll(componentsOverrides.getComponentOverrides());
|
||||
|
||||
fileManagementStorageService.storeObject(dossierId, fileId, FileType.COMPONENTS, new ByteArrayInputStream(objectMapper.writeValueAsBytes(existingComponents)));
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public ComponentsOverrides getOverrides(String dossierId, String fileId) {
|
||||
|
||||
var exists = fileManagementStorageService.objectExists(dossierId, fileId, FileType.COMPONENTS);
|
||||
if (!exists) {
|
||||
return ComponentsOverrides.builder().componentOverrides(Collections.emptyMap()).build();
|
||||
}
|
||||
var existingComponentsBytes = fileManagementStorageService.getStoredObjectBytes(dossierId, fileId, FileType.COMPONENTS);
|
||||
return objectMapper.readValue(existingComponentsBytes, ComponentsOverrides.class);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void revertOverrides(String dossierId, String fileId, RevertOverrideRequest revertOverrideRequest) {
|
||||
|
||||
if (!fileManagementStorageService.objectExists(dossierId, fileId, FileType.COMPONENTS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var existingComponentsBytes = fileManagementStorageService.getStoredObjectBytes(dossierId, fileId, FileType.COMPONENTS);
|
||||
var existingComponents = objectMapper.readValue(existingComponentsBytes, ComponentsOverrides.class);
|
||||
|
||||
revertOverrideRequest.getComponents()
|
||||
.forEach(c -> existingComponents.getComponentOverrides().remove(c));
|
||||
|
||||
fileManagementStorageService.storeObject(dossierId, fileId, FileType.COMPONENTS, new ByteArrayInputStream(objectMapper.writeValueAsBytes(existingComponents)));
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,4 +5,5 @@
|
||||
<include file="/mongo/changelog/tenant/1-initial-database.changelog.xml"/>
|
||||
<include file="/mongo/changelog/tenant/2-create-indices-for-entries.xml"/>
|
||||
<include file="/mongo/changelog/tenant/3-add-page-paragraph-idx.xml"/>
|
||||
<include file="/mongo/changelog/tenant/4-create-component-entities.xml"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.20.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
|
||||
|
||||
<changeSet id="createComponentCollection" author="ali">
|
||||
|
||||
<ext:createCollection collectionName="component-logs"/>
|
||||
|
||||
<ext:createCollection collectionName="components"/>
|
||||
|
||||
</changeSet>
|
||||
|
||||
|
||||
</databaseChangeLog>
|
||||
@ -0,0 +1,62 @@
|
||||
//package com.iqser.red.service.peristence.v1.server.integration.tests;
|
||||
//
|
||||
//import static com.mongodb.assertions.Assertions.assertNotNull;
|
||||
//import static com.mongodb.assertions.Assertions.assertTrue;
|
||||
//import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
//
|
||||
//import java.util.List;
|
||||
//import java.util.Optional;
|
||||
//
|
||||
//import org.junit.jupiter.api.Test;
|
||||
//import org.springframework.core.io.ClassPathResource;
|
||||
//
|
||||
//import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
//import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
//import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentDocument;
|
||||
//import com.iqser.red.service.persistence.service.v1.api.shared.mongo.mapper.ComponentLogDocumentMapper;
|
||||
//
|
||||
//import lombok.SneakyThrows;
|
||||
//
|
||||
//public class ComponentLogDocumentMapperTest {
|
||||
//
|
||||
// private final ComponentLogDocumentMapper mapper = ComponentLogDocumentMapper.INSTANCE;
|
||||
//
|
||||
// private final String COMPONENT_LOG = "files/componentlog/componentLogExample.json";
|
||||
// private final String COMPONENT_OVERRIDE = "files/componentlog/componentOverrideExample.json";
|
||||
// private static final String TEST_DOSSIER_ID = "91ce8e90-9aec-473c-b8c3-cbe16443ad34";
|
||||
// private static final String TEST_FILE_ID = "b2cbdd4dca0aa1aa0ebbfc5cc1462df0";
|
||||
//
|
||||
//
|
||||
// @Test
|
||||
// @SneakyThrows
|
||||
// public void ComponentOverrideMapper() {
|
||||
//
|
||||
// var overrideFile = new ClassPathResource(String.format(COMPONENT_OVERRIDE));
|
||||
// ObjectMapper objectMapper = new ObjectMapper();
|
||||
// objectMapper.registerModule(new JavaTimeModule());
|
||||
//
|
||||
// ComponentsOverrides componentsOverridesBefore = objectMapper.readValue(overrideFile.getInputStream(), ComponentsOverrides.class);
|
||||
//
|
||||
// List<ComponentDocument> componentDocument = mapper.toComponentOverrideDocuments(componentsOverridesBefore, TEST_DOSSIER_ID, TEST_FILE_ID);
|
||||
//
|
||||
// assertEquals(componentDocument.get(0).getDossierId(), TEST_DOSSIER_ID);
|
||||
// assertEquals(componentDocument.get(0).getFileId(), TEST_FILE_ID);
|
||||
// assertEquals(componentDocument.get(0).getId(), mapper.getComponentId(TEST_DOSSIER_ID, TEST_FILE_ID, componentDocument.get(0).getName()));
|
||||
//
|
||||
// Optional<ComponentValueDocument> optionalComponentValueDocument = componentDocument.get(0).getOverrideValues()
|
||||
// .stream()
|
||||
// .findFirst();
|
||||
//
|
||||
// assertTrue(optionalComponentValueDocument.isPresent());
|
||||
// assertNotNull(optionalComponentValueDocument.get().getValueId());
|
||||
// assertNotNull(optionalComponentValueDocument.get().getComponentOverrideId());
|
||||
//
|
||||
// ComponentsOverrides componentsOverridesAfter = mapper.fromComponentOverrideDocument(componentDocument.get(0));
|
||||
//
|
||||
// assertEquals(mapper.buildComponentOverrideMap(componentDocument.get(0).getName(),
|
||||
// componentsOverridesBefore.getComponentOverrides()
|
||||
// .get(componentDocument.get(0).getName())), componentsOverridesAfter);
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -0,0 +1,266 @@
|
||||
{
|
||||
"analysisNumber": 3,
|
||||
"componentRulesVersion": 1,
|
||||
"componentLogEntries": [
|
||||
{
|
||||
"name": "Study_Title",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "StudyTitle.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Performing_Laboratory",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "fallback",
|
||||
"componentRuleId": "PerformingLaboratory.0.2",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Report_Number",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "ReportNumber.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GLP_Study",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "No",
|
||||
"originalValue": "No",
|
||||
"valueDescription": "Yes if present, No if not",
|
||||
"componentRuleId": "GLPStudy.1.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Test_Guidelines_2",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all values of type with ', '",
|
||||
"componentRuleId": "TestGuideline.2.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Experimental_Starting_Date",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Convert values of type '' to dd/MM/yyyy joined with ', '",
|
||||
"componentRuleId": "StartDate.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Experimental_Completion_Date",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Convert values of type '' to dd/MM/yyyy joined with ', '",
|
||||
"componentRuleId": "CompletionDate.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Certificate_of_Analysis_Batch_Identification",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "AnalysisCertificate.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Species",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "Species.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Strain",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "Strain.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Doses_mg_per_kg_bw",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "Necropsy.1.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Mortality_Statement",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "MortalityStatement.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Weight_Behavior_Changes",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all values of type with '\n'",
|
||||
"componentRuleId": "WeightBehavior.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Necropsy_Findings",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "Necropsy.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Deviation_from_the_Guideline",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all values of type with '\n'",
|
||||
"componentRuleId": "GuidelineDeviation.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_LD50_Greater_than",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "No entity of type 'ld50_greater' found",
|
||||
"componentRuleId": "Conclusion.1.1",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_LD50_mg_per_kg",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "Conclusion.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_Minimum_Confidence",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "Conclusion.2.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_Maximum_Confidence",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "Conclusion.3.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Study_Conclusion",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": null,
|
||||
"value": "",
|
||||
"originalValue": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "StudyConclusion.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,244 @@
|
||||
{
|
||||
"componentOverrides": [
|
||||
{
|
||||
"name": "Study_Title",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "1",
|
||||
"value": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "StudyTitle.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Performing_Laboratory",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "2",
|
||||
"value": "",
|
||||
"valueDescription": "fallback",
|
||||
"componentRuleId": "PerformingLaboratory.0.2",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Report_Number",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "3",
|
||||
"value": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "ReportNumber.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GLP_Study",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "4",
|
||||
"value": "No",
|
||||
"valueDescription": "Yes if present, No if not",
|
||||
"componentRuleId": "GLPStudy.1.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Test_Guidelines_2",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "5",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all values of type with ', '",
|
||||
"componentRuleId": "TestGuideline.2.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Experimental_Starting_Date",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "6",
|
||||
"value": "",
|
||||
"valueDescription": "Convert values of type '' to dd/MM/yyyy joined with ', '",
|
||||
"componentRuleId": "StartDate.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Experimental_Completion_Date",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "7",
|
||||
"value": "",
|
||||
"valueDescription": "Convert values of type '' to dd/MM/yyyy joined with ', '",
|
||||
"componentRuleId": "CompletionDate.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Certificate_of_Analysis_Batch_Identification",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "8",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "AnalysisCertificate.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Species",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "9",
|
||||
"value": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "Species.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Strain",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "10",
|
||||
"value": "",
|
||||
"valueDescription": "First found value of type or else ''",
|
||||
"componentRuleId": "Strain.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Doses_mg_per_kg_bw",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "11",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "Necropsy.1.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Mortality_Statement",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "12",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "MortalityStatement.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Weight_Behavior_Changes",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "13",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all values of type with '\n'",
|
||||
"componentRuleId": "WeightBehavior.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Necropsy_Findings",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "14",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "Necropsy.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Deviation_from_the_Guideline",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "15",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all values of type with '\n'",
|
||||
"componentRuleId": "GuidelineDeviation.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_LD50_Greater_than",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "16",
|
||||
"value": "",
|
||||
"valueDescription": "No entity of type 'ld50_greater' found",
|
||||
"componentRuleId": "Conclusion.1.1",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_LD50_mg_per_kg",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "17",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "Conclusion.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_Minimum_Confidence",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "18",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "Conclusion.2.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conclusion_Maximum_Confidence",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "19",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all unique values of type with ', '",
|
||||
"componentRuleId": "Conclusion.3.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Study_Conclusion",
|
||||
"componentValues": [
|
||||
{
|
||||
"valueId": "20",
|
||||
"value": "",
|
||||
"valueDescription": "Joining all values of type with ' '",
|
||||
"componentRuleId": "StudyConclusion.0.0",
|
||||
"componentLogEntityReferences": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -16,5 +16,5 @@ public class ComponentLogEntry {
|
||||
|
||||
String name;
|
||||
List<ComponentLogEntryValue> componentValues;
|
||||
|
||||
boolean overridden;
|
||||
}
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.model.component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ComponentsOverrides {
|
||||
|
||||
private Map<String, String> componentOverrides = new HashMap<>();
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntryValue;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Document(collection = "components")
|
||||
public class ComponentDocument {
|
||||
|
||||
@Id
|
||||
@EqualsAndHashCode.Include
|
||||
String id; // componentLogId/name = componentOverrideId
|
||||
|
||||
String componentLogId;
|
||||
|
||||
String name;
|
||||
|
||||
List<ComponentLogEntryValue> overrideValues = new ArrayList<>();
|
||||
|
||||
// these parameters will be needed later
|
||||
// List<ComponentLogEntryValue> values = new ArrayList<>();
|
||||
// boolean overridden;
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Document(collection = "component-logs")
|
||||
public class ComponentLogDocument {
|
||||
|
||||
@Id
|
||||
@EqualsAndHashCode.Include
|
||||
String id; // dossierId/fileId = componentLogId
|
||||
|
||||
String dossierId;
|
||||
String fileId;
|
||||
|
||||
int analysisNumber;
|
||||
long componentRulesVersion = -1;
|
||||
|
||||
@DBRef
|
||||
List<ComponentDocument> components = new ArrayList<>();
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.exception;
|
||||
|
||||
public class ComponentLogDocumentNotFoundException extends RuntimeException {
|
||||
|
||||
public ComponentLogDocumentNotFoundException(String errorMessage) {
|
||||
|
||||
super(errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentDocument;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentLogDocument;
|
||||
|
||||
@Mapper
|
||||
public interface ComponentLogDocumentMapper {
|
||||
|
||||
ComponentLogDocumentMapper INSTANCE = Mappers.getMapper(ComponentLogDocumentMapper.class);
|
||||
|
||||
|
||||
@Mapping(source = "components", target = "componentLogEntries")
|
||||
ComponentLog fromComponentLogDocument(ComponentLogDocument componentLogDocument);
|
||||
|
||||
|
||||
List<ComponentDocument> toComponentDocuments(List<ComponentLogEntry> componentLogEntries);
|
||||
|
||||
|
||||
@Mapping(source = "overrideValues", target = "componentValues")
|
||||
ComponentLogEntry fromComponentDocument(ComponentDocument componentDocument);
|
||||
|
||||
|
||||
@Mapping(expression = "java(getComponentLogId(dossierId, fileId))", target = "id")
|
||||
ComponentLogDocument toComponentLogDocument(String dossierId, String fileId, ComponentLog componentLog);
|
||||
|
||||
|
||||
@Mapping(expression = "java(getComponentId(componentLogId, componentLogEntry.getName()))", target = "id")
|
||||
ComponentDocument toComponentDocument(String componentLogId, ComponentLogEntry componentLogEntry);
|
||||
|
||||
|
||||
default String getComponentLogId(String dossierId, String fileId) {
|
||||
|
||||
return dossierId + "/" + fileId;
|
||||
}
|
||||
|
||||
|
||||
default String getComponentId(String componentLogId, String componentName) {
|
||||
|
||||
return componentLogId + "/" + componentName;
|
||||
}
|
||||
|
||||
|
||||
default String getComponentId(String dossierId, String fileId, String componentName) {
|
||||
|
||||
return getComponentLogId(dossierId, fileId) + "/" + componentName;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentDocument;
|
||||
|
||||
@Repository
|
||||
public interface ComponentDocumentRepository extends MongoRepository<ComponentDocument, String> {
|
||||
|
||||
@Query(value = "{ 'componentLogId' : ?0}", delete = true)
|
||||
void deleteByComponentLogId(String componentLogId);
|
||||
|
||||
|
||||
@Query(value = "{ 'componentLogId': ?0, 'componentName': ?1 }")
|
||||
Optional<ComponentDocument> findComponentDocumentByName(String componentLogId, String componentName);
|
||||
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentLogDocument;
|
||||
|
||||
@Repository
|
||||
public interface ComponentLogDocumentRepository extends MongoRepository<ComponentLogDocument, String>, CustomComponentRepository {
|
||||
|
||||
@Query(value = "{ 'id' : ?0 }", fields = "{ 'analysisNumber' : 1 }")
|
||||
Optional<ComponentLogDocument> findAnalysisNumberById(String id);
|
||||
|
||||
|
||||
@Query(value = "{ 'id': ?0 }", fields = "{ 'components': 0 }")
|
||||
Optional<ComponentLogDocument> findComponentLogDocumentWithoutEntriesById(String id);
|
||||
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentDocument;
|
||||
|
||||
@Repository
|
||||
public interface CustomComponentRepository {
|
||||
|
||||
List<ComponentDocument> findOverrides(String fileId, String dossierId);
|
||||
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.repository;
|
||||
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.match;
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation;
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.replaceRoot;
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.unwind;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentDocument;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class CustomComponentRepositoryImpl implements CustomComponentRepository {
|
||||
|
||||
private final MongoTemplate mongoTemplate;
|
||||
|
||||
|
||||
@Override
|
||||
public List<ComponentDocument> findOverrides(String fileId, String dossierId) {
|
||||
|
||||
LookupOperation lookupOperation = LookupOperation.newLookup().from("componentDocument").localField("components").foreignField("_id").as("componentDocs");
|
||||
|
||||
AggregationOperation matchOperation = match(Criteria.where("fileId").is(fileId).and("dossierId").is(dossierId));
|
||||
|
||||
AggregationOperation unwindOperation = unwind("componentDocs");
|
||||
|
||||
AggregationOperation matchNonEmptyOverrides = match(Criteria.where("componentDocs.overrideValues").ne(null));
|
||||
|
||||
AggregationOperation replaceRootOperation = replaceRoot("componentDocs");
|
||||
|
||||
Aggregation aggregation = newAggregation(matchOperation, lookupOperation, unwindOperation, matchNonEmptyOverrides, replaceRootOperation);
|
||||
|
||||
AggregationResults<ComponentDocument> results = mongoTemplate.aggregate(aggregation, "componentLogDocument", ComponentDocument.class);
|
||||
|
||||
return results.getMappedResults();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,229 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.mongo.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentDocument;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.document.ComponentLogDocument;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.exception.ComponentLogDocumentNotFoundException;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.mapper.ComponentLogDocumentMapper;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.repository.ComponentDocumentRepository;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.repository.ComponentLogDocumentRepository;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Service
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
public class ComponentLogMongoService {
|
||||
|
||||
ComponentLogDocumentRepository componentLogDocumentRepository;
|
||||
ComponentDocumentRepository componentDocumentRepository;
|
||||
ComponentLogDocumentMapper mapper = ComponentLogDocumentMapper.INSTANCE;
|
||||
|
||||
|
||||
public ComponentLogMongoService(ComponentLogDocumentRepository componentLogDocumentRepository, ComponentDocumentRepository componentDocumentRepository) {
|
||||
|
||||
this.componentLogDocumentRepository = componentLogDocumentRepository;
|
||||
this.componentDocumentRepository = componentDocumentRepository;
|
||||
}
|
||||
|
||||
|
||||
public void insertComponentLog(String dossierId, String fileId, ComponentLog componentLog) {
|
||||
|
||||
ComponentLogDocument componentLogDocument = componentLogDocumentRepository.insert(mapper.toComponentLogDocument(dossierId, fileId, componentLog));
|
||||
componentDocumentRepository.insert(componentLog.getComponentLogEntries()
|
||||
.stream()
|
||||
.map(componentLogEntry -> mapper.toComponentDocument(componentLogDocument.getId(), componentLogEntry))
|
||||
.toList());
|
||||
}
|
||||
|
||||
|
||||
public void saveComponentLog(String dossierId, String fileId, ComponentLog componentLog) {
|
||||
|
||||
ComponentLogDocument componentLogDocument = componentLogDocumentRepository.save(mapper.toComponentLogDocument(dossierId, fileId, componentLog));
|
||||
componentDocumentRepository.saveAll(componentLog.getComponentLogEntries()
|
||||
.stream()
|
||||
.map(componentLogEntry -> mapper.toComponentDocument(componentLogDocument.getId(), componentLogEntry))
|
||||
.toList());
|
||||
}
|
||||
|
||||
|
||||
public void upsertComponentLog(String dossierId, String fileId, ComponentLog componentLog) {
|
||||
|
||||
Optional<ComponentLogDocument> optionalComponentLogDocument = componentLogDocumentRepository.findById(mapper.getComponentLogId(dossierId, fileId));
|
||||
if (optionalComponentLogDocument.isEmpty()) {
|
||||
insertComponentLog(dossierId, fileId, componentLog);
|
||||
return;
|
||||
}
|
||||
|
||||
ComponentLogDocument oldComponentLogDocument = optionalComponentLogDocument.get();
|
||||
List<ComponentDocument> oldComponentDocuments = oldComponentLogDocument.getComponents();
|
||||
|
||||
ComponentLogDocument newComponentLogDocument = mapper.toComponentLogDocument(dossierId, fileId, componentLog);
|
||||
List<ComponentDocument> newComponentDocuments = newComponentLogDocument.getComponents();
|
||||
|
||||
List<ComponentDocument> toUpdate = new ArrayList<>(newComponentDocuments);
|
||||
toUpdate.retainAll(oldComponentDocuments);
|
||||
|
||||
List<ComponentDocument> toRemove = new ArrayList<>(oldComponentDocuments);
|
||||
toRemove.removeAll(toUpdate);
|
||||
|
||||
List<ComponentDocument> toInsert = new ArrayList<>(newComponentDocuments);
|
||||
toInsert.removeAll(toUpdate);
|
||||
|
||||
componentDocumentRepository.saveAll(toUpdate);
|
||||
componentDocumentRepository.deleteAll(toRemove);
|
||||
componentDocumentRepository.insert(toInsert);
|
||||
|
||||
componentLogDocumentRepository.save(newComponentLogDocument);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void deleteComponentLog(String dossierId, String fileId) {
|
||||
|
||||
String componentLogId = mapper.getComponentLogId(dossierId, fileId);
|
||||
|
||||
componentLogDocumentRepository.deleteById(componentLogId);
|
||||
|
||||
componentDocumentRepository.deleteByComponentLogId(componentLogId);
|
||||
}
|
||||
|
||||
|
||||
public void insertComponentLogEntries(String dossierId, String fileId, List<ComponentLogEntry> componentLogEntries) {
|
||||
|
||||
String componentLogId = mapper.getComponentLogId(dossierId, fileId);
|
||||
|
||||
ComponentLogDocument componentLogDocument = getComponentLogDocument(componentLogId);
|
||||
|
||||
List<ComponentDocument> componentDocuments = componentLogEntries.stream()
|
||||
.map(componentLogEntry -> mapper.toComponentDocument(componentLogId, componentLogEntry))
|
||||
.toList();
|
||||
|
||||
componentLogDocument.getComponents().addAll(componentDocuments);
|
||||
|
||||
componentDocumentRepository.insert(componentDocuments);
|
||||
componentLogDocumentRepository.save(componentLogDocument);
|
||||
}
|
||||
|
||||
|
||||
private ComponentLogDocument getComponentLogDocument(String componentLogId) {
|
||||
|
||||
Optional<ComponentLogDocument> optionalComponentLogDocument = componentLogDocumentRepository.findById(componentLogId);
|
||||
|
||||
if (optionalComponentLogDocument.isEmpty()) {
|
||||
throw new ComponentLogDocumentNotFoundException(String.format("Component log not found for %s", componentLogId));
|
||||
}
|
||||
|
||||
return optionalComponentLogDocument.get();
|
||||
}
|
||||
|
||||
|
||||
public void saveComponentLogEntries(String dossierId, String fileId, List<ComponentLogEntry> componentLogEntries) {
|
||||
|
||||
String componentLogId = mapper.getComponentLogId(dossierId, fileId);
|
||||
|
||||
ComponentLogDocument componentLogDocument = getComponentLogDocument(componentLogId);
|
||||
|
||||
List<ComponentDocument> componentDocuments = componentLogEntries.stream()
|
||||
.map(componentLogEntry -> mapper.toComponentDocument(componentLogId, componentLogEntry))
|
||||
.toList();
|
||||
|
||||
componentLogDocument.getComponents().addAll(componentDocuments);
|
||||
|
||||
componentDocumentRepository.saveAll(componentDocuments);
|
||||
componentLogDocumentRepository.save(componentLogDocument);
|
||||
}
|
||||
|
||||
|
||||
public void updateComponentLogEntries(String dossierId, String fileId, List<ComponentLogEntry> componentLogEntries) {
|
||||
|
||||
String componentLogId = mapper.getComponentLogId(dossierId, fileId);
|
||||
|
||||
componentDocumentRepository.saveAll(componentLogEntries.stream()
|
||||
.map(componentLogEntry -> mapper.toComponentDocument(componentLogId, componentLogEntry))
|
||||
.toList());
|
||||
}
|
||||
|
||||
|
||||
public void deleteComponentLogEntries(String dossierId, String fileId, List<ComponentLogEntry> componentLogEntries) {
|
||||
|
||||
String componentLogId = mapper.getComponentLogId(dossierId, fileId);
|
||||
|
||||
ComponentLogDocument componentLogDocument = getComponentLogDocument(componentLogId);
|
||||
|
||||
List<ComponentDocument> componentDocuments = componentLogEntries.stream()
|
||||
.map(componentLogEntry -> mapper.toComponentDocument(componentLogId, componentLogEntry))
|
||||
.toList();
|
||||
|
||||
componentLogDocument.getComponents().removeAll(componentDocuments);
|
||||
|
||||
componentDocumentRepository.deleteAll(componentDocuments);
|
||||
componentLogDocumentRepository.save(componentLogDocument);
|
||||
}
|
||||
|
||||
|
||||
public Optional<ComponentLog> findComponentLogByDossierIdAndFileId(String dossierId, String fileId) {
|
||||
|
||||
return componentLogDocumentRepository.findById(mapper.getComponentLogId(dossierId, fileId))
|
||||
.map(mapper::fromComponentLogDocument);
|
||||
}
|
||||
|
||||
|
||||
public Optional<ComponentLogEntry> findComponentLogEntryById(String dossierId, String fileId, String componentName) {
|
||||
|
||||
return componentDocumentRepository.findComponentDocumentByName(mapper.getComponentLogId(dossierId, fileId), componentName)
|
||||
.map(mapper::fromComponentDocument);
|
||||
}
|
||||
|
||||
|
||||
public List<ComponentLogEntry> findOverrides(String dossierId, String fileId) {
|
||||
|
||||
return componentLogDocumentRepository.findOverrides(dossierId, fileId)
|
||||
.stream()
|
||||
.map(mapper::fromComponentDocument)
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
public boolean componentLogDocumentExists(String dossierId, String fileId) {
|
||||
|
||||
return componentLogDocumentRepository.existsById(mapper.getComponentLogId(dossierId, fileId));
|
||||
}
|
||||
|
||||
|
||||
public Optional<Integer> findLatestAnalysisNumber(String dossierId, String fileId) {
|
||||
|
||||
return componentLogDocumentRepository.findAnalysisNumberById(mapper.getComponentLogId(dossierId, fileId))
|
||||
.map(ComponentLogDocument::getAnalysisNumber);
|
||||
}
|
||||
|
||||
|
||||
public List<ComponentLogEntry> findComponentLogEntriesWithComponentNameIn(String dossierId, String fileId, Collection<String> componentNames) {
|
||||
|
||||
String componentLogId = mapper.getComponentLogId(dossierId, fileId);
|
||||
List<String> names = componentNames.stream()
|
||||
.map(name -> mapper.getComponentId(componentLogId, name))
|
||||
.toList();
|
||||
|
||||
return componentDocumentRepository.findAllById(names)
|
||||
.stream()
|
||||
.map(mapper::fromComponentDocument)
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
public Optional<ComponentLog> findComponentLogWithoutEntries(String dossierId, String fileId) {
|
||||
|
||||
return componentLogDocumentRepository.findComponentLogDocumentWithoutEntriesById(mapper.getComponentLogId(dossierId, fileId))
|
||||
.map(mapper::fromComponentLogDocument);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user