Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • simonrose/naming-backend
  • anderslindh1/naming-backend
  • andersharrisson/naming-backend
3 results
Show changes
Showing
with 4781 additions and 3625 deletions
/*
* Copyright (C) 2024 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.rest.controller;
import org.openepics.names.rest.api.v1.IPvNames;
import org.openepics.names.rest.beans.response.Response;
import org.openepics.names.rest.beans.response.ResponseBoolean;
import org.openepics.names.service.NamesService;
import org.openepics.names.util.NameInformation;
import org.openepics.names.util.NamingConventionUtil;
import org.openepics.names.util.ProcessVariableNameInformation;
import org.openepics.names.util.TextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
/**
* This part of REST API provides validation of PV names data for Naming application.
*
* @author Lars Johansson
* @see NamingConventionUtil
*/
@RestController
@EnableAutoConfiguration
public class PvNamesController implements IPvNames {
private final NamesService namesService;
@Autowired
public PvNamesController(
NamesService namesService) {
this.namesService = namesService;
}
@Override
public ResponseEntity<ResponseBoolean> isValidProcessVariableName(String pvName) {
Boolean value = Boolean.TRUE;
String message = null;
String details = pvName;
String field = "pvName";
NameInformation nameInformation = NamingConventionUtil.extractNameInformation(pvName);
ProcessVariableNameInformation pvNameInformation = NamingConventionUtil.extractProcessVariableNameInformation(pvName);
if (!Boolean.TRUE.equals(namesService.existsName(nameInformation.conventionName()))) {
value = Boolean.FALSE;
message = TextUtil.PV_NAME_VALIDATION_CONVENTION_NAME_IS_NOT_REGISTERED_IN_NAMING;
} else if (!pvNameInformation.isValidFormat()) {
value = Boolean.FALSE;
message = pvNameInformation.message();
}
return new ResponseEntity<>(new ResponseBoolean(value, message, details, field), Response.getHeaderJson(), HttpStatus.OK);
}
}
......@@ -20,13 +20,18 @@ package org.openepics.names.rest.controller;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.wip.WipDeviceGroupRepository;
import org.openepics.names.repository.wip.WipDeviceTypeRepository;
import org.openepics.names.repository.wip.WipDisciplineRepository;
import org.openepics.names.repository.wip.WipNameRepository;
import org.openepics.names.repository.wip.WipSubsystemRepository;
import org.openepics.names.repository.wip.WipSystemGroupRepository;
import org.openepics.names.repository.wip.WipSystemRepository;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.NameElement;
......@@ -36,7 +41,8 @@ import org.openepics.names.rest.beans.response.ResponsePageStructureElements;
import org.openepics.names.service.NamesService;
import org.openepics.names.service.StructuresService;
import org.openepics.names.util.NamingConventionUtil;
import org.openepics.names.util.StructureElementUtil.StructureChoice;
import org.openepics.names.util.StructureChoice;
import org.openepics.names.util.wip.HolderWipRepositories;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -50,6 +56,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
/**
* This part of REST API provides reports for Naming application.
*
* @author Lars Johansson
*/
@Tag(name = "Report",
description = "provide reports for Naming application")
@RestController
......@@ -57,39 +68,49 @@ import io.swagger.v3.oas.annotations.tags.Tag;
@EnableAutoConfiguration
public class ReportController {
// note
// global exception handler available
private static final Logger LOGGER = Logger.getLogger(ReportController.class.getName());
private static final String NEWLINE = "\n";
private static final String SPACE = " ";
private static final String DIVIDER_32 = "--------------------------------";
private static final String DIVIDER_64 = DIVIDER_32 + DIVIDER_32;
private static final String DIVIDER_96 = DIVIDER_32 + DIVIDER_32 + DIVIDER_32;
private static final String DIVIDER_128 = DIVIDER_32 + DIVIDER_32 + DIVIDER_32 + DIVIDER_32;
private static final String NBR = "#: ";
private static final String NBR_HISTORY = "# history: ";
private static final String NBR_DISTINCT = "# distinct: ";
private static final String NBR_ACTIVE = "# active: ";
private static final String NBR_ALL = "# all: ";
private static final String NBR_CANCELLED = "# cancelled: ";
private static final String NBR_DELETED = "# deleted: ";
private static final String NBR_OTHER = "# other: ";
private static final String NBR_PENDING = "# pending: ";
private static final String NBR_CANCELLED = "# cancelled: ";
private static final String NBR_REJECTED = "# rejected: ";
private static final String NBR_OTHER = "# other: ";
private NamesService namesService;
private StructuresService structuresService;
private final NamesService namesService;
private final StructuresService structuresService;
private final HolderWipRepositories holderWipRepositories;
@Autowired
public ReportController(
NamesService namesService,
StructuresService structuresService) {
StructuresService structuresService,
WipNameRepository wipNnameRepository,
WipSystemGroupRepository wipSystemGroupRepository,
WipSystemRepository wipSystemRepository,
WipSubsystemRepository wipSubsystemRepository,
WipDisciplineRepository wipDisciplineRepository,
WipDeviceGroupRepository wipDeviceGroupRepository,
WipDeviceTypeRepository wipDeviceTypeRepository) {
this.namesService = namesService;
this.structuresService = structuresService;
this.holderWipRepositories = new HolderWipRepositories(
wipNnameRepository,
wipSystemGroupRepository,
wipSystemRepository,
wipSubsystemRepository,
wipDisciplineRepository,
wipDeviceGroupRepository,
wipDeviceTypeRepository);
}
/**
......@@ -111,10 +132,11 @@ public class ReportController {
3) System structure
4) Device structure
5) Device structure - P&ID Disciplines
"""
)
""")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Method completed OK. Return report about Naming (text).",
@ApiResponse(
responseCode = "200",
description = "Method completed OK. Return report about Naming (text).",
content = @Content(mediaType = "text/plain", schema = @Schema(implementation = String.class)))
})
@GetMapping(
......@@ -122,293 +144,147 @@ public class ReportController {
produces = {"text/plain"})
public String reportAbout() {
// report metrics about Naming
// ess names, system structure, device structure
// status, latest, deleted
// status names - APPROVED, structures - APPROVED, ARCHIVED, CANCELLED, PENDING, REJECTED
// latest true (default)
// deleted null, false, true
// metrics can be read with service layer or repository layer
// ess names
// read valid, valid deleted, valid not deleted
// count for kind of name
// system structure, device structure
// read valid per structure
// count for status
//
// note
// obsolete values are not shown
// metrics can be read with service layer or repository layer
// ----------------------------------------
// prepare metrics
// names - read, count
// structures - read, count
// prepare text
// names - format
// structures - format
// report
// prepare metrics
// read names - valid, valid deleted, valid not deleted
// count names - kind of name
// count names - history
ResponsePageNameElements nameElementsEssNames = namesService.readNames(null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
ResponsePageNameElements nameElementsEssNamesDeleted = namesService.readNames(Boolean.TRUE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
ResponsePageNameElements nameElementsEssNamesNotDeleted = namesService.readNames(Boolean.FALSE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
Long nbrEssNamesHistory = holderWipRepositories.nameRepository().countNamesHistory(null, null, null, null, null, null, null, null);
long nbrEssNameSystemstructure = 0;
long nbrEssNameSystemstructureDevicestructure = 0;
long nbrEssNameSystemstructureDevicestructureIndex = 0;
long nbrEssNameOther = 0;
for (NameElement nameElement : nameElementsEssNamesNotDeleted.getList()) {
if (!StringUtils.isEmpty(nameElement.getSystemstructure())
&& StringUtils.isEmpty(nameElement.getDevicestructure())
&& StringUtils.isEmpty(nameElement.getIndex())) {
nbrEssNameSystemstructure++;
} else if (!StringUtils.isEmpty(nameElement.getSystemstructure())
&& !StringUtils.isEmpty(nameElement.getDevicestructure())
&& StringUtils.isEmpty(nameElement.getIndex())) {
nbrEssNameSystemstructureDevicestructure++;
} else if (!StringUtils.isEmpty(nameElement.getSystemstructure())
&& !StringUtils.isEmpty(nameElement.getDevicestructure())
&& !StringUtils.isEmpty(nameElement.getIndex())) {
nbrEssNameSystemstructureDevicestructureIndex++;
} else {
nbrEssNameOther++;
}
}
ResponsePageStructureElements structureElementsSystemgroup = structuresService.readStructures(Type.SYSTEMGROUP, null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsSystem = structuresService.readStructures(Type.SYSTEM, null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsSubsystem = structuresService.readStructures(Type.SUBSYSTEM, null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsDiscipline = structuresService.readStructures(Type.DISCIPLINE, null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsDevicegroup = structuresService.readStructures(Type.DEVICEGROUP, null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsDevicetype = structuresService.readStructures(Type.DEVICETYPE, null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
Map<UUID, Long> mapUuidCountSystemGroup = new TreeMap<>();
Map<UUID, Long> mapUuidCountSystem = new TreeMap<>();
Map<UUID, Long> mapUuidCountSubsystem = new TreeMap<>();
Map<UUID, Long> mapUuidCountDiscipline = new TreeMap<>();
Map<UUID, Long> mapUuidCountDeviceGroup = new TreeMap<>();
Map<UUID, Long> mapUuidCountDeviceType = new TreeMap<>();
long nbrActiveSystemGroup = 0;
long nbrActiveSystem = 0;
long nbrActiveSubsystem = 0;
long nbrActiveDiscipline = 0;
long nbrActiveDeviceGroup = 0;
long nbrActiveDeviceType = 0;
long nbrDeletedSystemGroup = 0;
long nbrDeletedSystem = 0;
long nbrDeletedSubsystem = 0;
long nbrDeletedDiscipline = 0;
long nbrDeletedDeviceGroup = 0;
long nbrDeletedDeviceType = 0;
long nbrPendingSystemGroup = 0;
long nbrPendingSystem = 0;
long nbrPendingSubsystem = 0;
long nbrPendingDiscipline = 0;
long nbrPendingDeviceGroup = 0;
long nbrPendingDeviceType = 0;
long nbrCancelledSystemGroup = 0;
long nbrCancelledSystem = 0;
long nbrCancelledSubsystem = 0;
long nbrCancelledDiscipline = 0;
long nbrCancelledDeviceGroup = 0;
long nbrCancelledDeviceType = 0;
long nbrRejectedSystemGroup = 0;
long nbrRejectedSystem = 0;
long nbrRejectedSubsystem = 0;
long nbrRejectedDiscipline = 0;
long nbrRejectedDeviceGroup = 0;
long nbrRejectedDeviceType = 0;
long nbrOtherSystemGroup = 0;
long nbrOtherSystem = 0;
long nbrOtherSubsystem = 0;
long nbrOtherDiscipline = 0;
long nbrOtherDeviceGroup = 0;
long nbrOtherDeviceType = 0;
for (StructureElement structureElement : structureElementsSystemgroup.getList()) {
addOne(structureElement.getUuid(), mapUuidCountSystemGroup);
if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.FALSE.equals(structureElement.isDeleted())) {
nbrActiveSystemGroup++;
} else if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.TRUE.equals(structureElement.isDeleted())) {
nbrDeletedSystemGroup++;
} else if (Status.PENDING.equals(structureElement.getStatus())) {
nbrPendingSystemGroup++;
} else if (Status.CANCELLED.equals(structureElement.getStatus())) {
nbrCancelledSystemGroup++;
} else if (Status.REJECTED.equals(structureElement.getStatus())) {
nbrRejectedSystemGroup++;
} else {
nbrOtherSystemGroup++;
}
}
for (StructureElement structureElement : structureElementsSystem.getList()) {
addOne(structureElement.getUuid(), mapUuidCountSystem);
if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.FALSE.equals(structureElement.isDeleted())) {
nbrActiveSystem++;
} else if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.TRUE.equals(structureElement.isDeleted())) {
nbrDeletedSystem++;
} else if (Status.PENDING.equals(structureElement.getStatus())) {
nbrPendingSystem++;
} else if (Status.CANCELLED.equals(structureElement.getStatus())) {
nbrCancelledSystem++;
} else if (Status.REJECTED.equals(structureElement.getStatus())) {
nbrRejectedSystem++;
} else {
nbrOtherSystem++;
}
}
for (StructureElement structureElement : structureElementsSubsystem.getList()) {
addOne(structureElement.getUuid(), mapUuidCountSubsystem);
if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.FALSE.equals(structureElement.isDeleted())) {
nbrActiveSubsystem++;
} else if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.TRUE.equals(structureElement.isDeleted())) {
nbrDeletedSubsystem++;
} else if (Status.PENDING.equals(structureElement.getStatus())) {
nbrPendingSubsystem++;
} else if (Status.CANCELLED.equals(structureElement.getStatus())) {
nbrCancelledSubsystem++;
} else if (Status.REJECTED.equals(structureElement.getStatus())) {
nbrRejectedSubsystem++;
} else {
nbrOtherSubsystem++;
}
}
for (StructureElement structureElement : structureElementsDiscipline.getList()) {
addOne(structureElement.getUuid(), mapUuidCountDiscipline);
if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.FALSE.equals(structureElement.isDeleted())) {
nbrActiveDiscipline++;
} else if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.TRUE.equals(structureElement.isDeleted())) {
nbrDeletedDiscipline++;
} else if (Status.PENDING.equals(structureElement.getStatus())) {
nbrPendingDiscipline++;
} else if (Status.CANCELLED.equals(structureElement.getStatus())) {
nbrCancelledDiscipline++;
} else if (Status.REJECTED.equals(structureElement.getStatus())) {
nbrRejectedDiscipline++;
} else {
nbrOtherDiscipline++;
}
}
for (StructureElement structureElement : structureElementsDevicegroup.getList()) {
addOne(structureElement.getUuid(), mapUuidCountDeviceGroup);
if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.FALSE.equals(structureElement.isDeleted())) {
nbrActiveDeviceGroup++;
} else if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.TRUE.equals(structureElement.isDeleted())) {
nbrDeletedDeviceGroup++;
} else if (Status.PENDING.equals(structureElement.getStatus())) {
nbrPendingDeviceGroup++;
} else if (Status.CANCELLED.equals(structureElement.getStatus())) {
nbrCancelledDeviceGroup++;
} else if (Status.REJECTED.equals(structureElement.getStatus())) {
nbrRejectedDeviceGroup++;
} else {
nbrOtherDeviceGroup++;
}
}
for (StructureElement structureElement : structureElementsDevicetype.getList()) {
addOne(structureElement.getUuid(), mapUuidCountDeviceType);
if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.FALSE.equals(structureElement.isDeleted())) {
nbrActiveDeviceType++;
} else if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isLatest())
&& Boolean.TRUE.equals(structureElement.isDeleted())) {
nbrDeletedDeviceType++;
} else if (Status.PENDING.equals(structureElement.getStatus())) {
nbrPendingDeviceType++;
} else if (Status.CANCELLED.equals(structureElement.getStatus())) {
nbrCancelledDeviceType++;
} else if (Status.REJECTED.equals(structureElement.getStatus())) {
nbrRejectedDeviceType++;
} else {
nbrOtherDeviceType++;
}
}
HolderReportName holderReportName = new HolderReportName(nameElementsEssNamesNotDeleted);
// prepare metrics
// read structures - valid
// count structures - status
// count structures - history
ResponsePageStructureElements structureElementsSystemGroup = structuresService.readStructures(Type.SYSTEMGROUP, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsSystem = structuresService.readStructures(Type.SYSTEM, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsSubsystem = structuresService.readStructures(Type.SUBSYSTEM, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsDiscipline = structuresService.readStructures(Type.DISCIPLINE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsDeviceGroup = structuresService.readStructures(Type.DEVICEGROUP, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
ResponsePageStructureElements structureElementsDeviceType = structuresService.readStructures(Type.DEVICETYPE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
HolderReportStructure holderReportStructureSystemGroup = new HolderReportStructure(structureElementsSystemGroup);
HolderReportStructure holderReportStructureSystem = new HolderReportStructure(structureElementsSystem);
HolderReportStructure holderReportStructureSubsystem = new HolderReportStructure(structureElementsSubsystem);
HolderReportStructure holderReportStructureDiscipline = new HolderReportStructure(structureElementsDiscipline);
HolderReportStructure holderReportStructureDeviceGroup = new HolderReportStructure(structureElementsDeviceGroup);
HolderReportStructure holderReportStructureDeviceType = new HolderReportStructure(structureElementsDeviceType);
Long nbrSystemGroupHistory = holderWipRepositories.systemGroupRepository().countSystemGroupsHistory(null, null, null, null, null, null);
Long nbrSystemHistory = holderWipRepositories.systemRepository().countSystemsHistory(null, null, null, null, null, null, null);
Long nbrSubsystemHistory = holderWipRepositories.subsystemRepository().countSubsystemsHistory(null, null, null, null, null, null, null);
Long nbrDisciplineHistory = holderWipRepositories.disciplineRepository().countDisciplinesHistory(null, null, null, null, null, null);
Long nbrDeviceGroupHistory = holderWipRepositories.deviceGroupRepository().countDeviceGroupsHistory(null, null, null, null, null, null, null);
Long nbrDeviceTypeHistory = holderWipRepositories.deviceTypeRepository().countDeviceTypesHistory(null, null, null, null, null, null, null);
// prepare text
int spaceUntilSizeStructure = 16;
String metricsOverviewEssName = NBR_ACTIVE + nameElementsEssNamesNotDeleted.getListSize();
String metricsOverviewSystemGroup = NBR_ACTIVE + nbrActiveSystemGroup;
String metricsOverviewSystem = NBR_ACTIVE + nbrActiveSystem;
String metricsOverviewSubsystem = NBR_ACTIVE + nbrActiveSubsystem;
String metricsOverviewDiscipline = NBR_ACTIVE + nbrActiveDiscipline;
String metricsOverviewDeviceGroup = NBR_ACTIVE + nbrActiveDeviceGroup;
String metricsOverviewDeviceType = NBR_ACTIVE + nbrActiveDeviceType;
String metricsEssName = NBR_ALL + addSpaceUntilSize(nameElementsEssNames.getListSize(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nameElementsEssNamesNotDeleted.getListSize(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nameElementsEssNamesDeleted.getListSize(), spaceUntilSizeStructure);
String metricsEssNameSystemstructure = NBR + nbrEssNameSystemstructure;
String metricsEssNameSystemstructureDevicestructure = NBR + nbrEssNameSystemstructureDevicestructure;
String metricsEssNameSystemstructureDevicestructureIndex = NBR + nbrEssNameSystemstructureDevicestructureIndex;
String metricsEssNameOther = NBR + nbrEssNameOther;
String metricsOverviewSystemGroup = NBR_ACTIVE + holderReportStructureSystemGroup.getNumberActive();
String metricsOverviewSystem = NBR_ACTIVE + holderReportStructureSystem.getNumberActive();
String metricsOverviewSubsystem = NBR_ACTIVE + holderReportStructureSubsystem.getNumberActive();
String metricsOverviewDiscipline = NBR_ACTIVE + holderReportStructureDiscipline.getNumberActive();
String metricsOverviewDeviceGroup = NBR_ACTIVE + holderReportStructureDeviceGroup.getNumberActive();
String metricsOverviewDeviceType = NBR_ACTIVE + holderReportStructureDeviceType.getNumberActive();
String metricsEssName =
NBR_HISTORY + addSpaceUntilSize(nbrEssNamesHistory, spaceUntilSizeStructure)
+ NBR_DISTINCT + addSpaceUntilSize(nameElementsEssNames.getListSize(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nameElementsEssNamesNotDeleted.getListSize(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nameElementsEssNamesDeleted.getListSize(), spaceUntilSizeStructure);
String metricsEssNameSystemstructure = NBR + holderReportName.getNumberEssNameSystemstructure();
String metricsEssNameSystemstructureDevicestructure = NBR + holderReportName.getNumberEssNameSystemstructureDevicestructure();
String metricsEssNameSystemstructureDevicestructureIndex = NBR + holderReportName.getNumberEssNameSystemstructureDevicestructureIndex();
String metricsEssNameOther = NBR_OTHER + holderReportName.getNumberEssNameOther();
String metricsSystemstructureSystemGroup =
NBR_ALL + addSpaceUntilSize(mapUuidCountSystemGroup.size(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nbrActiveSystemGroup, spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nbrDeletedSystemGroup, spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(nbrPendingSystemGroup, spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(nbrCancelledSystemGroup, spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(nbrRejectedSystemGroup, spaceUntilSizeStructure)
+ NBR_OTHER + addSpaceUntilSize(nbrOtherSystemGroup, spaceUntilSizeStructure);
NBR_HISTORY + addSpaceUntilSize(nbrSystemGroupHistory, spaceUntilSizeStructure)
+ NBR_DISTINCT + addSpaceUntilSize(holderReportStructureSystemGroup.getSizeMapUuidCount(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(holderReportStructureSystemGroup.getNumberActive(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(holderReportStructureSystemGroup.getNumberDeleted(), spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(holderReportStructureSystemGroup.getNumberPending(), spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(holderReportStructureSystemGroup.getNumberCancelled(), spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(holderReportStructureSystemGroup.getNumberRejected(), spaceUntilSizeStructure);
String metricsSystemstructureSystem =
NBR_ALL + addSpaceUntilSize(mapUuidCountSystem.size(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nbrActiveSystem, spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nbrDeletedSystem, spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(nbrPendingSystem, spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(nbrCancelledSystem, spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(nbrRejectedSystem, spaceUntilSizeStructure)
+ NBR_OTHER + addSpaceUntilSize(nbrOtherSystem, spaceUntilSizeStructure);
NBR_HISTORY + addSpaceUntilSize(nbrSystemHistory, spaceUntilSizeStructure)
+ NBR_DISTINCT + addSpaceUntilSize(holderReportStructureSystem.getSizeMapUuidCount(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(holderReportStructureSystem.getNumberActive(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(holderReportStructureSystem.getNumberDeleted(), spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(holderReportStructureSystem.getNumberPending(), spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(holderReportStructureSystem.getNumberCancelled(), spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(holderReportStructureSystem.getNumberRejected(), spaceUntilSizeStructure);
String metricsSystemstructureSubsystem =
NBR_ALL + addSpaceUntilSize(mapUuidCountSubsystem.size(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nbrActiveSubsystem, spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nbrDeletedSubsystem, spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(nbrPendingSubsystem, spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(nbrCancelledSubsystem, spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(nbrRejectedSubsystem, spaceUntilSizeStructure)
+ NBR_OTHER + addSpaceUntilSize(nbrOtherSubsystem, spaceUntilSizeStructure);
NBR_HISTORY + addSpaceUntilSize(nbrSubsystemHistory, spaceUntilSizeStructure)
+ NBR_DISTINCT + addSpaceUntilSize(holderReportStructureSubsystem.getSizeMapUuidCount(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(holderReportStructureSubsystem.getNumberActive(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(holderReportStructureSubsystem.getNumberDeleted(), spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(holderReportStructureSubsystem.getNumberPending(), spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(holderReportStructureSubsystem.getNumberCancelled(), spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(holderReportStructureSubsystem.getNumberRejected(), spaceUntilSizeStructure);
String metricsDevicestructureDiscipline =
NBR_ALL + addSpaceUntilSize(mapUuidCountDiscipline.size(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nbrActiveDiscipline, spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nbrDeletedDiscipline, spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(nbrPendingDiscipline, spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(nbrCancelledDiscipline, spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(nbrRejectedDiscipline, spaceUntilSizeStructure)
+ NBR_OTHER + addSpaceUntilSize(nbrOtherDiscipline, spaceUntilSizeStructure);
NBR_HISTORY + addSpaceUntilSize(nbrDisciplineHistory, spaceUntilSizeStructure)
+ NBR_DISTINCT + addSpaceUntilSize(holderReportStructureDiscipline.getSizeMapUuidCount(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(holderReportStructureDiscipline.getNumberActive(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(holderReportStructureDiscipline.getNumberDeleted(), spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(holderReportStructureDiscipline.getNumberPending(), spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(holderReportStructureDiscipline.getNumberCancelled(), spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(holderReportStructureDiscipline.getNumberRejected(), spaceUntilSizeStructure);
String metricsDevicestructureDeviceGroup =
NBR_ALL + addSpaceUntilSize(mapUuidCountDeviceGroup.size(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nbrActiveDeviceGroup, spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nbrDeletedDeviceGroup, spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(nbrPendingDeviceGroup, spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(nbrCancelledDeviceGroup, spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(nbrRejectedDeviceGroup, spaceUntilSizeStructure)
+ NBR_OTHER + addSpaceUntilSize(nbrOtherDeviceGroup, spaceUntilSizeStructure);
NBR_HISTORY + addSpaceUntilSize(nbrDeviceGroupHistory, spaceUntilSizeStructure)
+ NBR_DISTINCT + addSpaceUntilSize(holderReportStructureDeviceGroup.getSizeMapUuidCount(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(holderReportStructureDeviceGroup.getNumberActive(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(holderReportStructureDeviceGroup.getNumberDeleted(), spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(holderReportStructureDeviceGroup.getNumberPending(), spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(holderReportStructureDeviceGroup.getNumberCancelled(), spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(holderReportStructureDeviceGroup.getNumberRejected(), spaceUntilSizeStructure);
String metricsDevicestructureDeviceType =
NBR_ALL + addSpaceUntilSize(mapUuidCountDeviceType.size(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(nbrActiveDeviceType, spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(nbrDeletedDeviceType, spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(nbrPendingDeviceType, spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(nbrCancelledDeviceType, spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(nbrRejectedDeviceType, spaceUntilSizeStructure)
+ NBR_OTHER + addSpaceUntilSize(nbrOtherDeviceType, spaceUntilSizeStructure);
NBR_HISTORY + addSpaceUntilSize(nbrDeviceTypeHistory, spaceUntilSizeStructure)
+ NBR_DISTINCT + addSpaceUntilSize(holderReportStructureDeviceType.getSizeMapUuidCount(), spaceUntilSizeStructure)
+ NBR_ACTIVE + addSpaceUntilSize(holderReportStructureDeviceType.getNumberActive(), spaceUntilSizeStructure)
+ NBR_DELETED + addSpaceUntilSize(holderReportStructureDeviceType.getNumberDeleted(), spaceUntilSizeStructure)
+ NBR_PENDING + addSpaceUntilSize(holderReportStructureDeviceType.getNumberPending(), spaceUntilSizeStructure)
+ NBR_CANCELLED + addSpaceUntilSize(holderReportStructureDeviceType.getNumberCancelled(), spaceUntilSizeStructure)
+ NBR_REJECTED + addSpaceUntilSize(holderReportStructureDeviceType.getNumberRejected(), spaceUntilSizeStructure);
StringBuilder metricsPIDDiscipline = new StringBuilder();
for (String discipline : NamingConventionUtil.getDisciplinesPID()) {
metricsPIDDiscipline.append(addSpaceUntilSize(discipline, spaceUntilSizeStructure)).append(SPACE);
}
StringBuilder metricsPIDNumeric = new StringBuilder();
metricsPIDNumeric.append(addSpaceUntilSize("", 68)).append("SC-IOC (*)");
// report header
StringBuilder sb = new StringBuilder();
sb.append("About Naming").append(NEWLINE)
.append(DIVIDER_128).append(NEWLINE)
.append(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date())).append(NEWLINE)
.append("Note # means number of, active means approved latest not deleted, obsolete values are not shown unless history is requested.").append(NEWLINE)
.append(DIVIDER_128).append(NEWLINE)
.append("Name and structure data are displayed per line of uuid which is unique identifier through lifecycle of entry.").append(NEWLINE)
.append("Note # means number of, active means valid not deleted, obsolete values are not shown unless history is requested.").append(NEWLINE)
.append(DIVIDER_128).append(NEWLINE)
.append("Metrics for Naming").append(NEWLINE)
.append(" 1) # entries - Overview").append(NEWLINE)
......@@ -437,11 +313,10 @@ public class ReportController {
sb.append(DIVIDER_96).append(NEWLINE);
// # names with system structure only - system group, system, system + subsystem
sb.append("ESS Name " + metricsEssName).append(NEWLINE);
sb.append(DIVIDER_64).append(NEWLINE);
sb.append("ESS Name (System structure) " + metricsEssNameSystemstructure).append(NEWLINE);
sb.append("ESS Name (System structure + Device structure) " + metricsEssNameSystemstructureDevicestructure).append(NEWLINE);
sb.append("ESS Name (System structure + Device structure + Index) " + metricsEssNameSystemstructureDevicestructureIndex).append(NEWLINE);
sb.append("ESS Name (Other) " + metricsEssNameOther).append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
sb.append("System structure " + metricsEssNameSystemstructure).append(NEWLINE);
sb.append("System structure + Device structure " + metricsEssNameSystemstructureDevicestructure).append(NEWLINE);
sb.append("System structure + Device structure + Index " + metricsEssNameSystemstructureDevicestructureIndex).append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
sb.append("3) # entries - System structure").append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
......@@ -458,46 +333,56 @@ public class ReportController {
sb.append("Device Type " + metricsDevicestructureDeviceType).append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
sb.append("5) Device structure - P&ID Disciplines").append(NEWLINE);
sb.append(" P&ID Numeric (*)").append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
// disciplines p&id, scientific
sb.append(metricsPIDDiscipline.toString()).append(NEWLINE);
sb.append(metricsPIDNumeric.toString()).append(NEWLINE);
sb.append(DIVIDER_128).append(NEWLINE);
return sb.toString();
}
/**
* Add one to count for key in map.
*
* @param key key
* @param map map
*/
private void addOne(UUID key, Map<UUID, Long> map) {
addOne(key, map, null);
}
/**
* Add one to count for key in map.
*
* @param key key
* @param map map
* @param mapNok map nok
*/
private void addOne(UUID key, Map<UUID, Long> map, Map<UUID, Long> mapNok) {
if (key == null) {
LOGGER.log(Level.FINEST, "addOne, key == null");
return;
// part of preparation for report is to keep track of kind of names and structures,
// which are expected to have values according to certain kinds and statuses.
// if unexpected kinds and statuses are kept track of (should be zero),
// if non-zero, this is listed as message which may (should) be told to system responsible.
// possibility to show any kind of message to user
boolean hasMessage = holderReportName.getNumberEssNameOther() > 0
|| holderReportStructureSystemGroup.getNumberOther() > 0
|| holderReportStructureSystem.getNumberOther() > 0
|| holderReportStructureSubsystem.getNumberOther() > 0
|| holderReportStructureDiscipline.getNumberOther() > 0
|| holderReportStructureDeviceGroup.getNumberOther() > 0
|| holderReportStructureDeviceType.getNumberOther() > 0;
if (hasMessage) {
sb.append("Message").append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
if (holderReportName.getNumberEssNameOther() > 0) {
sb.append(" ESS Name ").append(metricsEssNameOther).append(NEWLINE);
}
if (holderReportStructureSystemGroup.getNumberOther() > 0) {
sb.append(" System Group ").append(NBR_OTHER + holderReportStructureSystemGroup.getNumberOther()).append(NEWLINE);
}
if (holderReportStructureSystem.getNumberOther() > 0) {
sb.append(" System ").append(NBR_OTHER + holderReportStructureSystem.getNumberOther()).append(NEWLINE);
}
if (holderReportStructureSubsystem.getNumberOther() > 0) {
sb.append(" Subsystem ").append(NBR_OTHER + holderReportStructureSubsystem.getNumberOther()).append(NEWLINE);
}
if (holderReportStructureDiscipline.getNumberOther() > 0) {
sb.append(" Discipline ").append(NBR_OTHER + holderReportStructureDiscipline.getNumberOther()).append(NEWLINE);
}
if (holderReportStructureDeviceGroup.getNumberOther() > 0) {
sb.append(" Device Group ").append(NBR_OTHER + holderReportStructureDeviceGroup.getNumberOther()).append(NEWLINE);
}
if (holderReportStructureDeviceType.getNumberOther() > 0) {
sb.append(" Device Type ").append(NBR_OTHER + holderReportStructureDeviceType.getNumberOther()).append(NEWLINE);
}
sb.append(DIVIDER_128).append(NEWLINE);
}
Long no = map.get(key);
if (mapNok != null && no == null) {
no = mapNok.get(key);
no = no != null ? no + 1 : 1;
mapNok.put(key, no);
} else {
no = no != null ? no + 1 : 1;
map.put(key, no);
}
return sb.toString();
}
/**
* Add space to string (for value) until it has size.
*
......@@ -526,4 +411,133 @@ public class ReportController {
return addSpaceUntilSize(String.valueOf(val), size);
}
/**
* Utility class and holder of content about names for reporting purposes.
*
* @author Lars Johansson
*/
private class HolderReportName {
private int nbrEssNameSystemstructure = 0;
private int nbrEssNameSystemstructureDevicestructure = 0;
private int nbrEssNameSystemstructureDevicestructureIndex = 0;
private int nbrEssNameOther = 0;
public HolderReportName(ResponsePageNameElements nameElements) {
for (NameElement nameElement : nameElements.getList()) {
if (!StringUtils.isEmpty(nameElement.getSystemStructure())
&& StringUtils.isEmpty(nameElement.getDeviceStructure())
&& StringUtils.isEmpty(nameElement.getIndex())) {
nbrEssNameSystemstructure++;
} else if (!StringUtils.isEmpty(nameElement.getSystemStructure())
&& !StringUtils.isEmpty(nameElement.getDeviceStructure())
&& StringUtils.isEmpty(nameElement.getIndex())) {
nbrEssNameSystemstructureDevicestructure++;
} else if (!StringUtils.isEmpty(nameElement.getSystemStructure())
&& !StringUtils.isEmpty(nameElement.getDeviceStructure())
&& !StringUtils.isEmpty(nameElement.getIndex())) {
nbrEssNameSystemstructureDevicestructureIndex++;
} else {
nbrEssNameOther++;
}
}
}
public int getNumberEssNameSystemstructure() {
return nbrEssNameSystemstructure;
}
public int getNumberEssNameSystemstructureDevicestructure() {
return nbrEssNameSystemstructureDevicestructure;
}
public int getNumberEssNameSystemstructureDevicestructureIndex() {
return nbrEssNameSystemstructureDevicestructureIndex;
}
public int getNumberEssNameOther() {
return nbrEssNameOther;
}
}
/**
* Utility class and holder of content about structures for reporting purposes.
*
* @author Lars Johansson
*/
private class HolderReportStructure {
private Map<UUID, Long> mapUuidCount = new HashMap<>();
private int nbrActive = 0;
private int nbrDeleted = 0;
private int nbrPending = 0;
private int nbrCancelled = 0;
private int nbrRejected = 0;
private int nbrOther = 0;
public HolderReportStructure(ResponsePageStructureElements structureElements) {
for (StructureElement structureElement : structureElements.getList()) {
addOne(structureElement.getUuid(), mapUuidCount);
if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.FALSE.equals(structureElement.isDeleted())) {
nbrActive++;
} else if (Status.APPROVED.equals(structureElement.getStatus())
&& Boolean.TRUE.equals(structureElement.isDeleted())) {
nbrDeleted++;
} else if (Boolean.TRUE.equals(structureElement.isDeleted())) {
// ref. V5__Data_transformation_status_deleted.sql
// migration script to transform data to not rely on status attribute
nbrDeleted++;
} else if (Status.PENDING.equals(structureElement.getStatus())) {
nbrPending++;
} else if (Status.CANCELLED.equals(structureElement.getStatus())) {
nbrCancelled++;
} else if (Status.REJECTED.equals(structureElement.getStatus())) {
nbrRejected++;
} else {
nbrOther++;
}
}
}
/**
* Add one to count for key in map.
*
* @param key key
* @param map map
*/
private void addOne(UUID key, Map<UUID, Long> map) {
if (key == null) {
return;
}
Long no = map.get(key);
no = no != null ? no + 1 : 1;
map.put(key, no);
}
public int getSizeMapUuidCount() {
return mapUuidCount.size();
}
public int getNumberActive() {
return nbrActive;
}
public int getNumberDeleted() {
return nbrDeleted;
}
public int getNumberPending() {
return nbrPending;
}
public int getNumberCancelled() {
return nbrCancelled;
}
public int getNumberRejected() {
return nbrRejected;
}
public int getNumberOther() {
return nbrOther;
}
}
}
......@@ -18,7 +18,6 @@
package org.openepics.names.rest.controller;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -26,28 +25,29 @@ import java.util.logging.Logger;
import org.openepics.names.exception.ServiceException;
import org.openepics.names.rest.api.v1.IStructures;
import org.openepics.names.rest.beans.FieldStructure;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.StructureElement;
import org.openepics.names.rest.beans.element.StructureElementCommand;
import org.openepics.names.rest.beans.element.StructureElementCommandConfirm;
import org.openepics.names.rest.beans.element.StructureElementCommandCreate;
import org.openepics.names.rest.beans.element.StructureElementCommandUpdate;
import org.openepics.names.rest.beans.response.Response;
import org.openepics.names.rest.beans.response.ResponseBoolean;
import org.openepics.names.rest.beans.response.ResponseBooleanList;
import org.openepics.names.rest.beans.response.ResponsePageStructureElements;
import org.openepics.names.service.LogService;
import org.openepics.names.service.StructuresService;
import org.openepics.names.util.ExcelUtil;
import org.openepics.names.service.security.dto.UserDetails;
import org.openepics.names.service.security.util.SecurityUtil;
import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.ValidateStructureElementUtil;
import org.openepics.names.util.ValidateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.google.common.collect.Lists;
......@@ -61,177 +61,152 @@ import com.google.common.collect.Lists;
public class StructuresController implements IStructures {
// note
// global exception handler available
// TODO validate authority
// either
// no or
// naming user
// naming admin
// naming user & admin
// controller layer to call validation prior to invoking service layer
// business logic may be validation
// different kinds of validation
private static final Logger LOGGER = Logger.getLogger(StructuresController.class.getName());
private static final String ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX = "attachment; filename=StructureElement.xlsx";
private LogService logService;
private StructuresService structuresService;
private final LogService logService;
private final StructuresService structuresService;
@Autowired
public StructuresController(
LogService logUtil,
LogService logService,
StructuresService structuresService) {
this.logService = logUtil;
this.logService = logService;
this.structuresService = structuresService;
}
@Override
public ResponseEntity<List<StructureElement>> createStructures(List<StructureElementCommand> structureElements) {
// validate authority
// naming user & admin
public ResponseEntity<List<StructureElement>> createStructures(UserDetails user,
List<StructureElementCommandCreate> structureElementCommands) {
// validate authority - user & admin
// convert
// validate
// do
// create structures
try {
structuresService.validateStructuresCreate(structureElements);
return new ResponseEntity<>(structuresService.createStructures(structureElements), Response.getHeaderJson(), HttpStatus.CREATED);
List<StructureElementCommand> commands = StructureElementUtil.convertCommandCreate2Command(structureElementCommands);
structuresService.validateStructuresCreate(commands);
return new ResponseEntity<>(structuresService.createStructures(commands, SecurityUtil.getUsername(user)), Response.getHeaderJson(), HttpStatus.CREATED);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponseEntity<Resource> createStructures(MultipartFile file) {
// validate authority
// naming user & admin
// validate
// do
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
structuresService.validateStructuresCreate(structureElementCommands);
List<StructureElement> structureElements = structuresService.createStructures(structureElementCommands);
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
// ----------------------------------------------------------------------------------------------------
@Override
public ResponsePageStructureElements readStructures(Type type, Status[] statuses, Boolean deleted,
String uuid, String parentuuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
public ResponsePageStructureElements readStructures(Type type, Boolean deleted,
String parent, String mnemonic, String mnemonicPath, String description, String who,
FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
// validate
// read structures
try {
return structuresService.readStructures(type, statuses, deleted,
uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
ValidateStructureElementUtil.validateStructuresInputRead(type, deleted,
null, parent, mnemonic, mnemonicPath, description, who,
null, orderBy, isAsc, page, pageSize);
return structuresService.readStructures(type, deleted,
null, parent, mnemonic, mnemonicPath, description, who,
orderBy, isAsc, page, pageSize);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponseEntity<Resource> readStructuresDownload(Type type, Status[] statuses, Boolean deleted,
String uuid, String parentuuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
ResponsePageStructureElements structureElements = readStructures(type, statuses, deleted,
uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
orderBy, isAsc, page, pageSize);
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
}
public ResponseEntity<ResponsePageStructureElements> readStructure(String uuid) {
// validate
// read structure
@Override
public ResponsePageStructureElements readStructuresChildren(String uuid, Type type, Status[] statuses, Boolean deleted,
String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
try {
return structuresService.readStructuresChildren(uuid, type, statuses, deleted,
name, mnemonic, mnemonicequivalence, mnemonicpath, description,
orderBy, isAsc, page, pageSize);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
// use offset, limit
// have limit for size of search result
@Override
public ResponsePageStructureElements readStructuresMnemonic(String mnemonic,
FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
try {
return structuresService.readStructuresMnemonic(mnemonic, orderBy, isAsc, page, pageSize);
ValidateUtil.validateInputUuid(uuid);
ResponsePageStructureElements structureElements = structuresService.readStructures(null, null,
uuid, null, null, null, null, null,
null, null, Integer.valueOf(IStructures.DEFAULT_PAGE), Integer.valueOf(IStructures.DEFAULT_PAGE_SIZE));
HttpStatus status = null;
if (structureElements.getListSize() == 0) {
status = HttpStatus.NOT_FOUND;
} else {
status = HttpStatus.OK;
}
return new ResponseEntity<>(structureElements, Response.getHeaderJson(), status);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponsePageStructureElements readStructuresMnemonicpath(String mnemonicpath,
public ResponseEntity<ResponsePageStructureElements> readStructuresChildren(String uuid, Boolean deleted,
FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
// validate
// read structures
try {
return structuresService.readStructuresMnemonicpath(mnemonicpath, orderBy, isAsc, page, pageSize);
ValidateUtil.validateInputUuid(uuid);
ResponsePageStructureElements structureElements = structuresService.readStructuresChildren(uuid, deleted,
orderBy, isAsc, page, pageSize);
HttpStatus status = null;
if (structureElements.getListSize() == 0) {
status = HttpStatus.NOT_FOUND;
} else {
status = HttpStatus.OK;
}
return new ResponseEntity<>(structureElements, Response.getHeaderJson(), status);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponsePageStructureElements readStructuresHistory(String uuid, Type type,
FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
public ResponseEntity<ResponsePageStructureElements> readStructuresHistory(String uuid) {
// validate
// read structures
try {
return structuresService.readStructuresHistory(uuid, type,
orderBy, isAsc, page, pageSize);
ValidateUtil.validateInputUuid(uuid);
ResponsePageStructureElements structureElements = structuresService.readStructuresHistory(uuid,
Integer.valueOf(IStructures.DEFAULT_PAGE), Integer.valueOf(IStructures.DEFAULT_PAGE_SIZE));
HttpStatus status = null;
if (structureElements.getListSize() == 0) {
status = HttpStatus.NOT_FOUND;
} else {
status = HttpStatus.OK;
}
return new ResponseEntity<>(structureElements, Response.getHeaderJson(), status);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
......@@ -239,43 +214,37 @@ public class StructuresController implements IStructures {
// ----------------------------------------------------------------------------------------------------
@Override
public String equivalenceMnemonic(String mnemonic) {
try {
return structuresService.equivalenceMnemonic(mnemonic);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
public ResponseEntity<ResponseBoolean> existsStructure(Type type, String mnemonicPath) {
// validate
// read structures
@Override
public ResponseEntity<ResponseBoolean> existsStructure(Type type, String mnemonicpath) {
try {
return new ResponseEntity<>(new ResponseBoolean(structuresService.existsStructure(type, mnemonicpath)), Response.getHeaderJson(), HttpStatus.OK);
ValidateUtil.validateInputType(type);
ValidateUtil.validateInputMnemonicPath(mnemonicPath);
return new ResponseEntity<>(new ResponseBoolean(structuresService.existsStructure(type, mnemonicPath)), Response.getHeaderJson(), HttpStatus.OK);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()), Response.getHeaderJson(), HttpStatus.OK);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.getHeaderJson(), HttpStatus.OK);
}
}
@Override
public ResponseEntity<ResponseBoolean> isValidToCreateStructure(Type type, String mnemonicpath) {
public ResponseEntity<ResponseBoolean> isValidToCreateStructure(Type type, String mnemonicPath) {
// validate
// read structures
try {
return new ResponseEntity<>(new ResponseBoolean(structuresService.isValidToCreateStructure(type, mnemonicpath)), Response.getHeaderJson(), HttpStatus.OK);
ValidateUtil.validateInputType(type);
ValidateUtil.validateInputMnemonicPath(mnemonicPath);
return new ResponseEntity<>(new ResponseBoolean(structuresService.isValidToCreateStructure(type, mnemonicPath)), Response.getHeaderJson(), HttpStatus.OK);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()), Response.getHeaderJson(), HttpStatus.OK);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.getHeaderJson(), HttpStatus.OK);
}
}
......@@ -283,53 +252,27 @@ public class StructuresController implements IStructures {
// ----------------------------------------------------------------------------------------------------
@Override
public ResponseEntity<ResponseBooleanList> validateStructuresCreate(List<StructureElementCommand> structureElements) {
boolean response = true;
String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
try {
structuresService.validateStructuresCreate(structureElement);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
}
}
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
}
public ResponseEntity<ResponseBooleanList> validateStructuresCreate(List<StructureElementCommandCreate> structureElementCommands) {
// convert
// validate
@Override
public ResponseEntity<ResponseBooleanList> validateStructuresUpdate(List<StructureElementCommand> structureElements) {
List<StructureElementCommand> commands = StructureElementUtil.convertCommandCreate2Command(structureElementCommands);
boolean response = true;
String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
for (StructureElementCommand command : commands) {
try {
structuresService.validateStructuresUpdate(structureElement);
structuresService.validateStructuresCreate(command);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
......@@ -341,53 +284,27 @@ public class StructuresController implements IStructures {
}
@Override
public ResponseEntity<ResponseBooleanList> validateStructuresDelete(List<StructureElementCommand> structureElements) {
boolean response = true;
String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
try {
structuresService.validateStructuresDelete(structureElement);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
}
}
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
}
public ResponseEntity<ResponseBooleanList> validateStructuresUpdate(List<StructureElementCommandUpdate> structureElementCommands) {
// convert
// validate
@Override
public ResponseEntity<ResponseBooleanList> validateStructuresApprove(List<StructureElementCommand> structureElements) {
List<StructureElementCommand> commands = StructureElementUtil.convertCommandUpdate2Command(structureElementCommands);
boolean response = true;
String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
for (StructureElementCommand command : commands) {
try {
structuresService.validateStructuresApprove(structureElement);
structuresService.validateStructuresUpdate(command);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
......@@ -399,53 +316,27 @@ public class StructuresController implements IStructures {
}
@Override
public ResponseEntity<ResponseBooleanList> validateStructuresCancel(List<StructureElementCommand> structureElements) {
boolean response = true;
String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
try {
structuresService.validateStructuresCancel(structureElement);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
}
}
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
}
public ResponseEntity<ResponseBooleanList> validateStructuresDelete(List<StructureElementCommandConfirm> structureElementCommands) {
// convert
// validate
@Override
public ResponseEntity<ResponseBooleanList> validateStructuresReject(List<StructureElementCommand> structureElements) {
List<StructureElementCommand> commands = StructureElementUtil.convertCommandConfirm2Command(structureElementCommands);
boolean response = true;
String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
for (StructureElementCommand command : commands) {
try {
structuresService.validateStructuresReject(structureElement);
structuresService.validateStructuresDelete(command);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
if (response) {
response = false;
reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
......@@ -459,89 +350,22 @@ public class StructuresController implements IStructures {
// ----------------------------------------------------------------------------------------------------
@Override
public List<StructureElement> updateStructures(List<StructureElementCommand> structureElements) {
try {
structuresService.validateStructuresUpdate(structureElements);
return structuresService.updateStructures(structureElements);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponseEntity<Resource> updateStructures(MultipartFile file) {
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
structuresService.validateStructuresUpdate(structureElementCommands);
List<StructureElement> structureElements = structuresService.updateStructures(structureElementCommands);
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
// ----------------------------------------------------------------------------------------------------
@Override
public List<StructureElement> deleteStructures(List<StructureElementCommand> structureElements) {
try {
structuresService.validateStructuresDelete(structureElements);
return structuresService.deleteStructures(structureElements);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
public List<StructureElement> updateStructures(UserDetails user,
List<StructureElementCommandUpdate> structureElementCommands) {
// validate authority - user & admin
// convert
// validate
// update structures
@Override
public ResponseEntity<Resource> deleteStructures(MultipartFile file) {
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
structuresService.validateStructuresDelete(structureElementCommands);
List<StructureElement> structureElements = structuresService.deleteStructures(structureElementCommands);
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
List<StructureElementCommand> commands = StructureElementUtil.convertCommandUpdate2Command(structureElementCommands);
structuresService.validateStructuresUpdate(commands);
return structuresService.updateStructures(commands, SecurityUtil.getUsername(user));
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
......@@ -549,130 +373,23 @@ public class StructuresController implements IStructures {
// ----------------------------------------------------------------------------------------------------
@Override
public List<StructureElement> approveStructures(List<StructureElementCommand> structureElements) {
try {
structuresService.validateStructuresApprove(structureElements);
return structuresService.approveStructures(structureElements);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponseEntity<Resource> approveStructures(MultipartFile file) {
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
structuresService.validateStructuresApprove(structureElementCommands);
List<StructureElement> structureElements = structuresService.approveStructures(structureElementCommands);
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public List<StructureElement> cancelStructures(List<StructureElementCommand> structureElements) {
try {
structuresService.validateStructuresCancel(structureElements);
return structuresService.cancelStructures(structureElements);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponseEntity<Resource> cancelStructures(MultipartFile file) {
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
structuresService.validateStructuresCancel(structureElementCommands);
List<StructureElement> structureElements = structuresService.cancelStructures(structureElementCommands);
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public List<StructureElement> rejectStructures(List<StructureElementCommand> structureElements) {
try {
structuresService.validateStructuresReject(structureElements);
return structuresService.rejectStructures(structureElements);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
}
}
public ResponseEntity<Response> deleteStructures(UserDetails user,
List<StructureElementCommandConfirm> structureElementCommands) {
// validate authority - user & admin
// convert
// validate
// delete structures
@Override
public ResponseEntity<Resource> rejectStructures(MultipartFile file) {
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
structuresService.validateStructuresReject(structureElementCommands);
List<StructureElement> structureElements = structuresService.rejectStructures(structureElementCommands);
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
List<StructureElementCommand> commands = StructureElementUtil.convertCommandConfirm2Command(structureElementCommands);
structuresService.validateStructuresDelete(commands);
structuresService.deleteStructures(commands, SecurityUtil.getUsername(user));
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logStackTraceElements(LOGGER, Level.WARNING, e);
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
......
......@@ -18,24 +18,31 @@
package org.openepics.names.rest.controller;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.old.model.DeviceRevision;
import org.openepics.names.old.model.NamePartRevision;
import org.openepics.names.old.model.NamePartRevisionStatus;
import org.openepics.names.old.nameviews.NameViewProvider;
import org.openepics.names.repository.IAuditNameRepository;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository;
......@@ -43,16 +50,37 @@ import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.model.Discipline;
import org.openepics.names.repository.model.Name;
import org.openepics.names.repository.model.Subsystem;
import org.openepics.names.repository.model.System;
import org.openepics.names.repository.model.SystemGroup;
import org.openepics.names.repository.AuditNameRepository;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.repository.DisciplineRepository;
import org.openepics.names.repository.NameRepository;
import org.openepics.names.repository.SubsystemRepository;
import org.openepics.names.repository.SystemGroupRepository;
import org.openepics.names.repository.SystemRepository;
import org.openepics.names.repository.model.wip.WipDeviceGroup;
import org.openepics.names.repository.model.wip.WipDeviceType;
import org.openepics.names.repository.model.wip.WipDiscipline;
import org.openepics.names.repository.model.wip.WipName;
import org.openepics.names.repository.model.wip.WipStructure;
import org.openepics.names.repository.model.wip.WipSubsystem;
import org.openepics.names.repository.model.wip.WipSystem;
import org.openepics.names.repository.model.wip.WipSystemGroup;
import org.openepics.names.repository.old.IDeviceRevisionRepository;
import org.openepics.names.repository.old.INamePartRevisionRepository;
import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
import org.openepics.names.repository.wip.IWipDisciplineRepository;
import org.openepics.names.repository.wip.IWipNameRepository;
import org.openepics.names.repository.wip.IWipSubsystemRepository;
import org.openepics.names.repository.wip.IWipSystemGroupRepository;
import org.openepics.names.repository.wip.IWipSystemRepository;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.util.HolderIRepositories;
import org.openepics.names.util.HolderRepositories;
import org.openepics.names.util.ValidateUtil;
import org.openepics.names.util.wip.HolderIWipRepositories;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -64,15 +92,66 @@ import io.swagger.v3.oas.annotations.Hidden;
/**
* This part of REST API provides verification of data migration for Naming application.
*
* <p>Prerequisite(s)
* <p>
* Prerequisites.
* These are required to ensure that comparisons of content in old and migrated tables
* can be done and that result of comparisons are valid.
* <ul>
* <li>migration script run</li>
* <li>tables corresponding to both old and migrated database available</li>
* <li>must be done directly after migration has been done</li>
* <li>no changes of any kind in any way for content, either names or structures, may have been introduced</li>
* </ul>
*
* <p>
* Verification is preferably done in following order
* <ol>
* <li>structures</li>
* <li>names</li>
* <li>data is reachable</li>
* <li>comparison of old REST API vs. new REST API</li>
* </ol>
*
* <p>
* Structures.
* <ul>
* <li>Verification of structures (after) vs. name parts (before)</li>
* <li>Check that each attribute as expected in each structure entry</li>
* </ul>
*
* <p>
* Names.
* <ul>
* <li>Verification of names (after) vs. devices (before)</li>
* <li>Check that each attribute as expected in each name entry</li>
* </ul>
*
* <p>
* Data is reachable.
* <ul>
* <li>Verification of data in the sense that all data can be reached</li>
* <li>Concerns itself with new database, not old database</li>
* </ul>
*
* <p>
* Comparison of old REST API vs. new REST API.
* <ul>
* <li>Verification of differences between old REST API and new REST API</li>
* <li>Check that all content in new REST API is in old REST API and that difference is old/obsolete data</li>
* </ul>
*
* <p>
* Note
* <ul>
* <li>both old and migrated database available</li>
* <li>log statements and output are technical and implementation-like, and meant to give detailed information</li>
* <li>after migration has been done and verified, this part of REST API no longer holds any function and may be removed
* together with related code not used elsewhere. As a suggestion, this may done in the second release of the software.</li>
* </ul>
*
* <p>
* Ideally, some knowledge of database tables and object structures acquired to dig into this class.
* It can be done in any case and there is documentation available.
* It is recommended to have database tables and object structures available.
* It is recommended to have database tables available in database management tool for any further queries.
*
* @author Lars Johansson
*/
......@@ -82,303 +161,192 @@ import io.swagger.v3.oas.annotations.Hidden;
@EnableAutoConfiguration
public class VerificationController {
// note
// global exception handler available
/*
Methods
read GET /verification/migration_devicerevision - readMigrationDeviceRevision()
read GET /verification/migration_namepartrevision - readMigrationNamePartRevision
read GET /verification/data_reachable - readDataReachable()
read GET /verification/restapi_oldvsnew - readRestApiOldVsNew()
*/
// methods
// read GET /verification/migration_namepartrevision - readMigrationStructures
// read GET /verification/migration_devicerevision - readMigrationNames
// read GET /verification/data_reachable - readDataReachable
// read GET /verification/restapi_oldvsnew - readRestApiOldVsNew
private static final Logger LOGGER = Logger.getLogger(VerificationController.class.getName());
private static final String NEW_LINE_BR = "<br/>";
private static final String NEWLINE = "\n";
private static final String SPACE = " ";
private static final String DIVIDER_32 = "--------------------------------";
private static final String DIVIDER_96 = DIVIDER_32 + DIVIDER_32 + DIVIDER_32;
private static final String DIVIDER_128 = DIVIDER_32 + DIVIDER_32 + DIVIDER_32 + DIVIDER_32;
// prepare text
private static final int SPACE_UNTIL_SIZE_32 = 32;
private static final int SPACE_UNTIL_SIZE_40 = 40;
private static final int SPACE_UNTIL_SIZE_48 = 48;
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private HolderIRepositories holderIRepositories;
private final IDeviceRevisionRepository deviceRevisionRepository;
private final INamePartRevisionRepository namePartRevisionRepository;
@Autowired
IDeviceRevisionRepository deviceRevisionRepository;
@Autowired
INamePartRevisionRepository namePartRevisionRepository;
private final HolderIWipRepositories holderIWipRepositories;
private final HolderIRepositories holderIRepositories;
private final HolderRepositories holderRepositories;
@Autowired
public VerificationController(
INameRepository nameRepository,
ISystemGroupRepository systemGroupRepository,
ISystemRepository systemRepository,
ISubsystemRepository subsystemRepository,
IDisciplineRepository disciplineRepository,
IDeviceGroupRepository deviceGroupRepository,
IDeviceTypeRepository deviceTypeRepository) {
holderIRepositories = new HolderIRepositories(
IDeviceRevisionRepository deviceRevisionRepository,
INamePartRevisionRepository namePartRevisionRepository,
IWipNameRepository iWipNameRepository,
IWipSystemGroupRepository iWipSystemGroupRepository,
IWipSystemRepository iWipSystemRepository,
IWipSubsystemRepository iWipSubsystemRepository,
IWipDisciplineRepository iWipDisciplineRepository,
IWipDeviceGroupRepository iWipDeviceGroupRepository,
IWipDeviceTypeRepository iWipDeviceTypeRepository,
INameRepository iNameRepository,
ISystemGroupRepository iSystemGroupRepository,
ISystemRepository iSystemRepository,
ISubsystemRepository iSubsystemRepository,
IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository,
IAuditNameRepository iAuditNameRepository,
IAuditStructureRepository iAuditStructureRepository,
NameRepository nameRepository,
SystemGroupRepository systemGroupRepository,
SystemRepository systemRepository,
SubsystemRepository subsystemRepository,
DisciplineRepository disciplineRepository,
DeviceGroupRepository deviceGroupRepository,
DeviceTypeRepository deviceTypeRepository,
AuditNameRepository auditNameRepository,
AuditStructureRepository auditStructureRepository) {
this.deviceRevisionRepository = deviceRevisionRepository;
this.namePartRevisionRepository = namePartRevisionRepository;
this.holderIWipRepositories = new HolderIWipRepositories(
iWipNameRepository,
iWipSystemGroupRepository,
iWipSystemRepository,
iWipSubsystemRepository,
iWipDisciplineRepository,
iWipDeviceGroupRepository,
iWipDeviceTypeRepository);
this.holderIRepositories = new HolderIRepositories(
iNameRepository,
iSystemGroupRepository,
iSystemRepository,
iSubsystemRepository,
iDisciplineRepository,
iDeviceGroupRepository,
iDeviceTypeRepository,
iAuditNameRepository,
iAuditStructureRepository);
this.holderRepositories = new HolderRepositories(
nameRepository,
systemGroupRepository,
systemRepository,
subsystemRepository,
disciplineRepository,
deviceGroupRepository,
deviceTypeRepository);
deviceTypeRepository,
auditNameRepository,
auditStructureRepository);
}
/**
* Perform verification of data migration with focus on device revision.
* Perform verification of data migration with focus on structures, i.e. name part revisions.
* Ok if all entries ok and no entry nok.
*
* @return report of data migration
*/
@GetMapping("/migration_devicerevision")
public String readMigrationDeviceRevision() {
// verification of
// name vs. devicerevision, device
// with help of namepartrevision, namepart
// note
// check entry by entry
// ----------
// to check 1st, 2nd, 3rd parent to determine if systemgroup, system or subsystem
// otherwise not clear how to make sure if it is supposed to be systemgroup and not system, subsystem and vice versa
// ----------
// date may be in different format for different objects, to be formatted before being compared
// ----------
// name.id = devicerevision.id
// name.version = devicerevision.version
// name.uuid = devicerevision.device_id (device.id --> device.uuid)
// name.namepartrevision_systemgroup_uuid = devicerevision.section_id (namepart.id --> namepart.uuid
// name.namepartrevision_system_uuid = devicerevision.section_id (namepart.id --> namepart.uuid
// name.namepartrevision_subsystem_uuid = devicerevision.section_id (namepart.id --> namepart.uuid
// name.namepartrevision_devicetype_uuid = devicerevision.devicetype_id (namepart.id --> namepart.uuid
// name.instance_index = devicerevision.instanceindex
// name.convention_name = devicerevision.conventionname
// name.convention_name_equivalence = devicerevision.conventionnameeqclass
// name.description = devicerevision.additionalinfo
// name.status = null
// name.latest = true if id = get max id for uuid (not consider status)
// name.deleted = devicerevision.deleted
// name.requested = devicerevision.requestdate
// name.requested_by = devicerevision.requestedby_id (useraccount.id --> useraccount.username)
// name.requested_comment = null
// name.processed = null
// name.processed_by = null
// name.processed_comment = devicerevision.processorcomment
StringBuilder reportHtml = new StringBuilder();
@GetMapping(
path = {"/migration_structures"},
produces = {"text/plain"})
public String verifyMigrationStructures() {
// about
// verification of structures (after) vs. name parts (before)
// how
// find data for verification
// structures - systemgroup, system, subsystem, discipline, devicegroup, devicetype
// name parts - namepartrevision, namepart
// utility
// interpret data into hashmaps for faster retrieval in checks
// check
// for each entry in each structure
// check entry by entry
// each attribute as expected
// ok if
// all entries ok
// no entry nok
// e.g. if there has been usage of new database tables (new entries) before verification, there are more rows in those tables
// which means new and more ids than in old database tables
// which means those new ids don't exist in old database tables
// --> retrieval of device revisions for those ids will give null
StringBuilder report = new StringBuilder();
prepareLogReport(report, "About verification for data migration of structures");
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, " Compare structures data before and after migration");
prepareLogReport(report, " Check that each entry is migrated and that content after migration is same as content before migration");
prepareLogReport(report, " ");
prepareLogReport(report, " 1) Find data for structures before migration (all entries in tables)");
prepareLogReport(report, " Find data for structures after migration (all entries in tables)");
prepareLogReport(report, " 2) Prepare map (id, namepartrevision) for data before migration");
prepareLogReport(report, " Prepare map (uuid, max id) for data after migration, for each kind of structure, corresponding to latest approved entry in each line of uuid");
prepareLogReport(report, " 3) Process each kind of structure entry and each entry therein (data after migration)");
prepareLogReport(report, " For each entry, find corresponding data before migration and check that attributes are same and that correct entry has latest attribute set");
prepareLogReport(report, " Count entries for which data are same and not same (ok, nok)");
prepareLogReport(report, " 4) Result is ok if");
prepareLogReport(report, " number of entries before and after migration are same");
prepareLogReport(report, " number of entries which are not same is 0");
prepareLogReport(report, DIVIDER_128);
// find data
// for verification
// names
// to support
// device names
// name part revisions
List<Name> names = holderIRepositories.getNameRepository().findAll();
List<DeviceRevision> deviceNames = deviceRevisionRepository.findAll();
List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
prepareLogReport("readMigrationDeviceRevision, find data, names.size: " + names.size(), reportHtml);
prepareLogReport("readMigrationDeviceRevision, find data, deviceNames.size: " + deviceNames.size(), reportHtml);
prepareLogReport("readMigrationDeviceRevision, find data, namePartRevisions.size: " + namePartRevisions.size(), reportHtml);
// utility
// interpret lists into hashmaps for faster retrieval in for loop below
// used to help check name entries
// ----------
// mapIdDeviceRevision - find corresponding (old) device revision for given id
// mapUuidMaxIdName - find out latest name id for given uuid
// mapUuidNamePartRevision - find out name part revision for given uuid
HashMap<Long, DeviceRevision> mapIdDeviceRevision = new HashMap<>((int)(deviceNames.size()/0.75 + 2));
for (DeviceRevision deviceRevision : deviceNames) {
mapIdDeviceRevision.put(deviceRevision.getId(), deviceRevision);
}
HashMap<UUID, Long> mapUuidMaxIdName = new HashMap<>();
for (Name name : names) {
if (mapUuidMaxIdName.get(name.getUuid()) == null
|| name.getId() > mapUuidMaxIdName.get(name.getUuid())) {
mapUuidMaxIdName.put(name.getUuid(), name.getId());
}
}
HashMap<UUID, NamePartRevision> mapUuidNamePartRevision = new HashMap<>((int)(namePartRevisions.size()/0.75 + 2));
for (NamePartRevision namePartRevision : namePartRevisions) {
mapUuidNamePartRevision.put(namePartRevision.getNamePart().getUuid(), namePartRevision);
}
prepareLogReport("readMigrationDeviceRevision, utility, mapIdDeviceRevision.size: " + mapIdDeviceRevision.size(), reportHtml);
prepareLogReport("readMigrationDeviceRevision, utility, mapUuidMaxIdName.size: " + mapUuidMaxIdName.size(), reportHtml);
prepareLogReport("readMigrationDeviceRevision, utility, mapUuidNamePartRevision.size: " + mapUuidNamePartRevision.size(), reportHtml);
// keep track of id
// ok
// nok
SortedSet<Long> id_ok_deviceRevisionDevice = new TreeSet<>();
SortedSet<Long> id_nok_deviceRevisionDevice = new TreeSet<>();
prepareLogReport("readMigrationDeviceRevision, check, before, id_ok_deviceRevisionDevice.size: " + id_ok_deviceRevisionDevice.size(), reportHtml);
prepareLogReport("readMigrationDeviceRevision, check, before, id_nok_deviceRevisionDevice.size: " + id_nok_deviceRevisionDevice.size(), reportHtml);
// name
// check entry by entry
// each attribute as expected
boolean check = false;
DeviceRevision deviceRevision = null;
for (Name name : names) {
deviceRevision = mapIdDeviceRevision.get(name.getId());
check = deviceRevision != null;
check = check && name.getId().equals(deviceRevision.getId());
check = check && name.getVersion().equals(deviceRevision.getVersion());
check = check && name.getUuid().equals(deviceRevision.getDevice().getUuid());
// to check 1st, 2nd, 3rd parent to determine if systemgroup, system or subsystem
// otherwise not clear how to make sure if it is supposed to be systemgroup and not system, subsystem and vice versa
NamePartRevision parent1 = deviceRevision.getSection() != null
? mapUuidNamePartRevision.get(deviceRevision.getSection().getUuid())
: null;
NamePartRevision parent2 = parent1 != null && parent1.getParent() != null
? mapUuidNamePartRevision.get(parent1.getParent().getUuid())
: null;
NamePartRevision parent3 = parent2 != null && parent2.getParent() != null
? mapUuidNamePartRevision.get(parent2.getParent().getUuid())
: null;
// parent 1 but not parent 2, 3 - system group
// parent 1, 2 but not parent 3 - system
// parent 1, 2, 3 - subsystem
// else nok
UUID systemGroupUuid = name.getSystemgroupUuid();
UUID systemUuid = name.getSystemUuid();
UUID subsystemUuid = name.getSubsystemUuid();
UUID sectionUuid = deviceRevision.getSection().getUuid();
if (parent1 != null && parent2 == null && parent3 == null) {
check = check && sectionUuid.equals(systemGroupUuid) && systemUuid == null && subsystemUuid == null;
} else if (parent1 != null && parent2 != null && parent3 == null) {
check = check && sectionUuid.equals(systemUuid) && systemGroupUuid == null && subsystemUuid == null;
} else if (parent1 != null && parent2 != null && parent3 != null) {
check = check && sectionUuid.equals(subsystemUuid) && systemGroupUuid == null && systemUuid == null;
} else {
check = false;
}
check = check && ((name.getDevicetypeUuid() == null && deviceRevision.getDeviceType() == null)
|| (name.getDevicetypeUuid().equals(deviceRevision.getDeviceType().getUuid())));
check = check && StringUtils.equals(name.getInstanceIndex(), deviceRevision.getInstanceIndex());
check = check && StringUtils.equals(name.getConventionName(), deviceRevision.getConventionName());
check = check && StringUtils.equals(name.getConventionNameEquivalence(), deviceRevision.getConventionNameEqClass());
check = check && StringUtils.equals(name.getDescription(), deviceRevision.getAdditionalInfo());
check = check && name.getStatus() == null;
// latest
// true if id = get max id for uuid
check = check && name.isLatest() == name.getId().equals(mapUuidMaxIdName.get(name.getUuid()));
check = check && name.isDeleted() == deviceRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((name.getRequested() == null && deviceRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(name.getRequested()), SDF.format(deviceRevision.getRequestDate())));
check = check && StringUtils.equals(name.getRequestedBy(), deviceRevision.getRequestedBy().getUsername());
check = check && name.getRequestedComment() == null;
check = check && name.getProcessed() == null;
check = check && name.getProcessedBy() == null;
check = check && StringUtils.equals(name.getProcessedComment(), deviceRevision.getProcessorComment());
// add to count
if (check) {
id_ok_deviceRevisionDevice.add(name.getId());
} else {
id_nok_deviceRevisionDevice.add(name.getId());
}
}
// ok if
// all entries ok
// no entry nok
boolean ok = id_ok_deviceRevisionDevice.size() == names.size()
&& id_nok_deviceRevisionDevice.isEmpty();
prepareLogReport("readMigrationDeviceRevision, check, after, id_ok_deviceRevisionDevice.size: " + id_ok_deviceRevisionDevice.size(), reportHtml);
prepareLogReport("readMigrationDeviceRevision, check, after, id_nok_deviceRevisionDevice.size: " + id_nok_deviceRevisionDevice.size(), reportHtml);
prepareLogReport("readMigrationDeviceRevision, ok: " + ok, reportHtml);
return reportHtml.toString();
}
/**
* Perform verification of data migration with focus on name part revision.
* Ok if all entries ok and no entry nok.
*
* @return report of data migration
*/
@GetMapping("/migration_namepartrevision")
public String readMigrationNamePartRevision() {
// verification of
// systemgroup
// system
// subsystem
// discipline
// devicegroup
// devicetype
// vs.
// namepartrevision
// with help of namepartrevision, namepart
// note
// check entry by entry
// ----------
// to check parent uuid
// ----------
// date may be in different format for different objects, to be formatted before being compared
// ----------
// e.g.
// system.id = namepartrevision.id
// system.version = namepartrevision.version
// system.uuid = namepartrevision.namepart_id (namepart.id --> namepart.uuid)
// ( system.parent_uuid = namepartrevision.parent_id (namepart.id --> namepart.uuid) )
// system.name = namepartrevision.name
// system.mnemonic = namepartrevision.mnemonic
// system.mnemonicequivalence = namepartrevision.mnemoniceqclass
// system.description = namepartrevision.description
// system.status = namepartrevision.status
// system.latest = true if id = get max id for uuid (consider status, but not PENDING)
// system.deleted = namepartrevision.deleted
// system.requested = namepartrevision.requestdate
// system.requested_by = namepartrevision.requestedby_id (useraccount.id --> useraccount.username)
// system.requested_comment = namepartrevision.requestercomment
// system.processed = namepartrevision.processdate
// system.processed_by = namepartrevision.processedby_id (useraccount.id --> useraccount.username)
// system.processed_comment = namepartrevision.processorcomment
StringBuilder reportHtml = new StringBuilder();
// find data
// for verification
// system groups
// systems
// subsystems
// disciplines
// device groups
// device types
// to support
// name part revisions
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findAll();
List<System> systems = holderIRepositories.getSystemRepository().findAll();
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findAll();
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findAll();
List<DeviceGroup> deviceGroups = holderIRepositories.getDeviceGroupRepository().findAll();
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findAll();
List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
prepareLogReport("readMigrationNamePartRevision, find data, systemGroups.size: " + systemGroups.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, find data, systems.size: " + systems.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, find data, subsystems.size: " + subsystems.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, find data, disciplines.size: " + disciplines.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, find data, deviceGroups.size: " + deviceGroups.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, find data, deviceTypes.size: " + deviceTypes.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, find data, namePartRevisions.size: " + namePartRevisions.size(), reportHtml);
List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findAll();
List<WipSystem> systems = holderIWipRepositories.systemRepository().findAll();
List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findAll();
List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findAll();
List<WipDeviceGroup> deviceGroups = holderIWipRepositories.deviceGroupRepository().findAll();
List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findAll();
int sumStructures = systemGroups.size()
+ systems.size()
+ subsystems.size()
+ disciplines.size()
+ deviceGroups.size()
+ deviceTypes.size();
prepareLogReport(report, "Find data");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# namepartrevision:", SPACE_UNTIL_SIZE_48) + namePartRevisions.size());
prepareLogReport(report, addSpaceUntilSize("# wip systemgroup:", SPACE_UNTIL_SIZE_48) + systemGroups.size());
prepareLogReport(report, addSpaceUntilSize("# wip system:", SPACE_UNTIL_SIZE_48) + systems.size());
prepareLogReport(report, addSpaceUntilSize("# wip subsystem:", SPACE_UNTIL_SIZE_48) + subsystems.size());
prepareLogReport(report, addSpaceUntilSize("# wip discipline:", SPACE_UNTIL_SIZE_48) + disciplines.size());
prepareLogReport(report, addSpaceUntilSize("# wip devicegroup:", SPACE_UNTIL_SIZE_48) + deviceGroups.size());
prepareLogReport(report, addSpaceUntilSize("# wip devicetype:", SPACE_UNTIL_SIZE_48) + deviceTypes.size());
prepareLogReport(report, addSpaceUntilSize("# sum:", SPACE_UNTIL_SIZE_48) + sumStructures);
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# systemgroup:", SPACE_UNTIL_SIZE_48) + holderIRepositories.systemGroupRepository().findAll().size());
prepareLogReport(report, addSpaceUntilSize("# system:", SPACE_UNTIL_SIZE_48) + holderIRepositories.systemRepository().findAll().size());
prepareLogReport(report, addSpaceUntilSize("# subsystem:", SPACE_UNTIL_SIZE_48) + holderIRepositories.subsystemRepository().findAll().size());
prepareLogReport(report, addSpaceUntilSize("# discipline:", SPACE_UNTIL_SIZE_48) + holderIRepositories.disciplineRepository().findAll().size());
prepareLogReport(report, addSpaceUntilSize("# devicegroup:", SPACE_UNTIL_SIZE_48) + holderIRepositories.deviceGroupRepository().findAll().size());
prepareLogReport(report, addSpaceUntilSize("# devicetype:", SPACE_UNTIL_SIZE_48) + holderIRepositories.deviceTypeRepository().findAll().size());
prepareLogReport(report, addSpaceUntilSize("# audit systemgroup:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEMGROUP, null));
prepareLogReport(report, addSpaceUntilSize("# audit system:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEM, null));
prepareLogReport(report, addSpaceUntilSize("# audit subsystem:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.SUBSYSTEM, null));
prepareLogReport(report, addSpaceUntilSize("# audit discipline:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.DISCIPLINE, null));
prepareLogReport(report, addSpaceUntilSize("# audit devicegroup:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICEGROUP, null));
prepareLogReport(report, addSpaceUntilSize("# audit devicetype:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICETYPE, null));
prepareLogReport(report, DIVIDER_96);
// utility
// interpret lists into hashmaps for faster retrieval in for loop below
......@@ -397,7 +365,7 @@ public class VerificationController {
mapIdNamePartRevision.put(namePartRevision.getId(), namePartRevision);
}
HashMap<UUID, Long> mapUuidMaxIdSystemGroup = new HashMap<>();
for (SystemGroup systemGroup : systemGroups) {
for (WipSystemGroup systemGroup : systemGroups) {
if ( (mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()) == null
|| systemGroup.getId() > mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(systemGroup.getStatus().name())) {
......@@ -405,7 +373,7 @@ public class VerificationController {
}
}
HashMap<UUID, Long> mapUuidMaxIdSystem = new HashMap<>();
for (System system : systems) {
for (WipSystem system : systems) {
if (( mapUuidMaxIdSystem.get(system.getUuid()) == null
|| system.getId() > mapUuidMaxIdSystem.get(system.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(system.getStatus().name())) {
......@@ -413,7 +381,7 @@ public class VerificationController {
}
}
HashMap<UUID, Long> mapUuidMaxIdSubsystem = new HashMap<>();
for (Subsystem subsystem : subsystems) {
for (WipSubsystem subsystem : subsystems) {
if ( (mapUuidMaxIdSubsystem.get(subsystem.getUuid()) == null
|| subsystem.getId() > mapUuidMaxIdSubsystem.get(subsystem.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(subsystem.getStatus().name())) {
......@@ -421,7 +389,7 @@ public class VerificationController {
}
}
HashMap<UUID, Long> mapUuidMaxIdDiscipline = new HashMap<>();
for (Discipline discipline : disciplines) {
for (WipDiscipline discipline : disciplines) {
if ((mapUuidMaxIdDiscipline.get(discipline.getUuid()) == null
|| discipline.getId() > mapUuidMaxIdDiscipline.get(discipline.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(discipline.getStatus().name())) {
......@@ -429,7 +397,7 @@ public class VerificationController {
}
}
HashMap<UUID, Long> mapUuidMaxIdDeviceGroup = new HashMap<>();
for (DeviceGroup deviceGroup : deviceGroups) {
for (WipDeviceGroup deviceGroup : deviceGroups) {
if ((mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()) == null
|| deviceGroup.getId() > mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(deviceGroup.getStatus().name())) {
......@@ -437,7 +405,7 @@ public class VerificationController {
}
}
HashMap<UUID, Long> mapUuidMaxIdDeviceType = new HashMap<>();
for (DeviceType deviceType : deviceTypes) {
for (WipDeviceType deviceType : deviceTypes) {
if ((mapUuidMaxIdDeviceType.get(deviceType.getUuid()) == null
|| deviceType.getId() > mapUuidMaxIdDeviceType.get(deviceType.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(deviceType.getStatus().name())) {
......@@ -445,334 +413,317 @@ public class VerificationController {
}
}
prepareLogReport("readMigrationNamePartRevision, utility, mapIdNamePartRevision.size: " + mapIdNamePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdSystemGroup.size: " + mapUuidMaxIdSystemGroup.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdSystem.size: " + mapUuidMaxIdSystem.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdSubsystem.size: " + mapUuidMaxIdSubsystem.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdDiscipline.size: " + mapUuidMaxIdDiscipline.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdDeviceGroup.size: " + mapUuidMaxIdDeviceGroup.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdDeviceType.size: " + mapUuidMaxIdDeviceType.size(), reportHtml);
prepareLogReport(report, "Utility");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# map id namepartrevision:", SPACE_UNTIL_SIZE_48) + mapIdNamePartRevision.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved systemgroup:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdSystemGroup.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved system:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdSystem.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved subsystem:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdSubsystem.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved discipline:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdDiscipline.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved devicegroup:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdDeviceGroup.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved devicetype:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdDeviceType.size());
prepareLogReport(report, DIVIDER_96);
// keep track of id
// ok
// nok
SortedSet<Long> id_ok_namePartRevision = new TreeSet<>();
SortedSet<Long> id_nok_namePartRevision = new TreeSet<>();
SortedSet<Long> idOkNamePartRevision = new TreeSet<>();
SortedSet<Long> idNokNamePartRevision = new TreeSet<>();
prepareLogReport("readMigrationNamePartRevision, check, before, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, before, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
prepareLogReport(report, addSpaceUntilSize("Check", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# ok namepartrevision", SPACE_UNTIL_SIZE_32) + addSpaceUntilSize("# nok namepartrevision", SPACE_UNTIL_SIZE_32));
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("before", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
// system group
// check entry by entry
// each attribute as expected
// each attribute as expected
boolean check = false;
NamePartRevision namePartRevision = null;
for (SystemGroup systemGroup : systemGroups) {
for (WipSystemGroup systemGroup : systemGroups) {
namePartRevision = mapIdNamePartRevision.get(systemGroup.getId());
check = namePartRevision != null;
check = check && systemGroup.getId().equals(namePartRevision.getId());
check = check && systemGroup.getVersion().equals(namePartRevision.getVersion());
check = check && systemGroup.getUuid().equals(namePartRevision.getNamePart().getUuid());
// no parent uuid for system group
check = check && StringUtils.equals(systemGroup.getName(), namePartRevision.getName());
check = check && StringUtils.equals(systemGroup.getMnemonic(), namePartRevision.getMnemonic());
check = check && StringUtils.equals(systemGroup.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
check = check && StringUtils.equals(systemGroup.getDescription(), namePartRevision.getDescription());
check = check && ((systemGroup.getStatus() == null && namePartRevision.getStatus() == null)
|| (systemGroup.getStatus().name().equals(namePartRevision.getStatus().name())));
// latest
// true if id = get max id for uuid
// special rules for pending, not consider pending
check = check && systemGroup.isLatest() == systemGroup.getId().equals(mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()));
check = check && systemGroup.isDeleted() == namePartRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((systemGroup.getRequested() == null && namePartRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(systemGroup.getRequested()), SDF.format(namePartRevision.getRequestDate())));
check = check && (systemGroup.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
|| StringUtils.equals(systemGroup.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(systemGroup.getRequestedComment(), namePartRevision.getRequesterComment());
check = check && ((systemGroup.getProcessed() == null && namePartRevision.getProcessDate() == null)
|| StringUtils.equals(SDF.format(systemGroup.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
check = check && (systemGroup.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
|| StringUtils.equals(systemGroup.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
check = check && StringUtils.equals(systemGroup.getProcessedComment(), namePartRevision.getProcessorComment());
// no check for parent uuid
check = namePartRevision != null
&& equals(systemGroup, namePartRevision, mapUuidMaxIdSystemGroup);
// add to count
if (check) {
id_ok_namePartRevision.add(systemGroup.getId());
idOkNamePartRevision.add(systemGroup.getId());
} else {
id_nok_namePartRevision.add(systemGroup.getId());
idNokNamePartRevision.add(systemGroup.getId());
}
}
prepareLogReport("readMigrationNamePartRevision, check, after systemgroup, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, after systemgroup, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
prepareLogReport(report, addSpaceUntilSize("after systemgroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
// system
// check entry by entry
// each attribute as expected
for (System system : systems) {
// each attribute as expected
for (WipSystem system : systems) {
namePartRevision = mapIdNamePartRevision.get(system.getId());
check = namePartRevision != null;
check = check && system.getId().equals(namePartRevision.getId());
check = check && system.getVersion().equals(namePartRevision.getVersion());
check = check && system.getUuid().equals(namePartRevision.getNamePart().getUuid());
// parent uuid
check = check && system.getParentUuid().equals(namePartRevision.getParent().getUuid());
check = check && StringUtils.equals(system.getName(), namePartRevision.getName());
check = check && StringUtils.equals(system.getMnemonic(), namePartRevision.getMnemonic());
check = check && StringUtils.equals(system.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
check = check && StringUtils.equals(system.getDescription(), namePartRevision.getDescription());
check = check && ((system.getStatus() == null && namePartRevision.getStatus() == null)
|| (system.getStatus().name().equals(namePartRevision.getStatus().name())));
// latest
// true if id = get max id for uuid
// special rules for pending, not consider pending
check = check && system.isLatest() == system.getId().equals(mapUuidMaxIdSystem.get(system.getUuid()));
check = check && system.isDeleted() == namePartRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((system.getRequested() == null && namePartRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(system.getRequested()), SDF.format(namePartRevision.getRequestDate())));
check = check && (system.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
|| StringUtils.equals(system.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(system.getRequestedComment(), namePartRevision.getRequesterComment());
check = check && ((system.getProcessed() == null && namePartRevision.getProcessDate() == null)
|| StringUtils.equals(SDF.format(system.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
check = check && (system.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
|| StringUtils.equals(system.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
check = check && StringUtils.equals(system.getProcessedComment(), namePartRevision.getProcessorComment());
check = namePartRevision != null
&& system.getParentUuid().equals(namePartRevision.getParent().getUuid())
&& equals(system, namePartRevision, mapUuidMaxIdSystem);
// add to count
if (check) {
id_ok_namePartRevision.add(system.getId());
idOkNamePartRevision.add(system.getId());
} else {
id_nok_namePartRevision.add(system.getId());
idNokNamePartRevision.add(system.getId());
}
}
prepareLogReport("readMigrationNamePartRevision, check, after system, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, after system, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
prepareLogReport(report, addSpaceUntilSize("after system", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
// subsystem
// check entry by entry
// each attribute as expected
for (Subsystem subsystem : subsystems) {
// each attribute as expected
for (WipSubsystem subsystem : subsystems) {
namePartRevision = mapIdNamePartRevision.get(subsystem.getId());
check = namePartRevision != null;
check = check && subsystem.getId().equals(namePartRevision.getId());
check = check && subsystem.getVersion().equals(namePartRevision.getVersion());
check = check && subsystem.getUuid().equals(namePartRevision.getNamePart().getUuid());
// parent uuid
check = check && subsystem.getParentUuid().equals(namePartRevision.getParent().getUuid());
check = check && StringUtils.equals(subsystem.getName(), namePartRevision.getName());
check = check && StringUtils.equals(subsystem.getMnemonic(), namePartRevision.getMnemonic());
check = check && StringUtils.equals(subsystem.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
check = check && StringUtils.equals(subsystem.getDescription(), namePartRevision.getDescription());
check = check && ((subsystem.getStatus() == null && namePartRevision.getStatus() == null)
|| (subsystem.getStatus().name().equals(namePartRevision.getStatus().name())));
// latest
// true if id = get max id for uuid
// special rules for pending, not consider pending
check = check && subsystem.isLatest() == subsystem.getId().equals(mapUuidMaxIdSubsystem.get(subsystem.getUuid()));
check = check && subsystem.isDeleted() == namePartRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((subsystem.getRequested() == null && namePartRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(subsystem.getRequested()), SDF.format(namePartRevision.getRequestDate())));
check = check && (subsystem.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
|| StringUtils.equals(subsystem.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(subsystem.getRequestedComment(), namePartRevision.getRequesterComment());
check = check && ((subsystem.getProcessed() == null && namePartRevision.getProcessDate() == null)
|| StringUtils.equals(SDF.format(subsystem.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
check = check && (subsystem.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
|| StringUtils.equals(subsystem.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
check = check && StringUtils.equals(subsystem.getProcessedComment(), namePartRevision.getProcessorComment());
check = namePartRevision != null
&& subsystem.getParentUuid().equals(namePartRevision.getParent().getUuid())
&& equals(subsystem, namePartRevision, mapUuidMaxIdSubsystem);
// add to count
if (check) {
id_ok_namePartRevision.add(subsystem.getId());
idOkNamePartRevision.add(subsystem.getId());
} else {
id_nok_namePartRevision.add(subsystem.getId());
idNokNamePartRevision.add(subsystem.getId());
}
}
prepareLogReport("readMigrationNamePartRevision, check, after subsystem, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, after subsystem, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
prepareLogReport(report, addSpaceUntilSize("after subsystem", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
// discipline
// check entry by entry
// each attribute as expected
for (Discipline discipline : disciplines) {
// each attribute as expected
for (WipDiscipline discipline : disciplines) {
namePartRevision = mapIdNamePartRevision.get(discipline.getId());
check = namePartRevision != null;
check = check && discipline.getId().equals(namePartRevision.getId());
check = check && discipline.getVersion().equals(namePartRevision.getVersion());
check = check && discipline.getUuid().equals(namePartRevision.getNamePart().getUuid());
// no parent uuid for discipline
check = check && StringUtils.equals(discipline.getName(), namePartRevision.getName());
check = check && StringUtils.equals(discipline.getMnemonic(), namePartRevision.getMnemonic());
check = check && StringUtils.equals(discipline.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
check = check && StringUtils.equals(discipline.getDescription(), namePartRevision.getDescription());
check = check && ((discipline.getStatus() == null && namePartRevision.getStatus() == null)
|| (discipline.getStatus().name().equals(namePartRevision.getStatus().name())));
// latest
// true if id = get max id for uuid
// special rules for pending, not consider pending
check = check && discipline.isLatest() == discipline.getId().equals(mapUuidMaxIdDiscipline.get(discipline.getUuid()));
check = check && discipline.isDeleted() == namePartRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((discipline.getRequested() == null && namePartRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(discipline.getRequested()), SDF.format(namePartRevision.getRequestDate())));
check = check && (discipline.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
|| StringUtils.equals(discipline.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(discipline.getRequestedComment(), namePartRevision.getRequesterComment());
check = check && ((discipline.getProcessed() == null && namePartRevision.getProcessDate() == null)
|| StringUtils.equals(SDF.format(discipline.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
check = check && (discipline.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
|| StringUtils.equals(discipline.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
check = check && StringUtils.equals(discipline.getProcessedComment(), namePartRevision.getProcessorComment());
// no check for parent uuid
check = namePartRevision != null
&& equals(discipline, namePartRevision, mapUuidMaxIdDiscipline);
// add to count
if (check) {
id_ok_namePartRevision.add(discipline.getId());
idOkNamePartRevision.add(discipline.getId());
} else {
id_nok_namePartRevision.add(discipline.getId());
idNokNamePartRevision.add(discipline.getId());
}
}
prepareLogReport("readMigrationNamePartRevision, check, after discipline, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, after discipline, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
prepareLogReport(report, addSpaceUntilSize("after discipline", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
// device group
// check entry by entry
// each attribute as expected
for (DeviceGroup deviceGroup : deviceGroups) {
// each attribute as expected
for (WipDeviceGroup deviceGroup : deviceGroups) {
namePartRevision = mapIdNamePartRevision.get(deviceGroup.getId());
check = namePartRevision != null;
check = check && deviceGroup.getId().equals(namePartRevision.getId());
check = check && deviceGroup.getVersion().equals(namePartRevision.getVersion());
check = check && deviceGroup.getUuid().equals(namePartRevision.getNamePart().getUuid());
// parent uuid
check = check && deviceGroup.getParentUuid().equals(namePartRevision.getParent().getUuid());
check = check && StringUtils.equals(deviceGroup.getName(), namePartRevision.getName());
check = check && StringUtils.equals(deviceGroup.getMnemonic(), namePartRevision.getMnemonic());
check = check && StringUtils.equals(deviceGroup.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
check = check && StringUtils.equals(deviceGroup.getDescription(), namePartRevision.getDescription());
check = check && ((deviceGroup.getStatus() == null && namePartRevision.getStatus() == null)
|| (deviceGroup.getStatus().name().equals(namePartRevision.getStatus().name())));
// latest
// true if id = get max id for uuid
// special rules for pending, not consider pending
check = check && deviceGroup.isLatest() == deviceGroup.getId().equals(mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()));
check = check && deviceGroup.isDeleted() == namePartRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((deviceGroup.getRequested() == null && namePartRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(deviceGroup.getRequested()), SDF.format(namePartRevision.getRequestDate())));
check = check && (deviceGroup.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
|| StringUtils.equals(deviceGroup.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(deviceGroup.getRequestedComment(), namePartRevision.getRequesterComment());
check = check && ((deviceGroup.getProcessed() == null && namePartRevision.getProcessDate() == null)
|| StringUtils.equals(SDF.format(deviceGroup.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
check = check && (deviceGroup.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
|| StringUtils.equals(deviceGroup.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
check = check && StringUtils.equals(deviceGroup.getProcessedComment(), namePartRevision.getProcessorComment());
check = namePartRevision != null
&& deviceGroup.getParentUuid().equals(namePartRevision.getParent().getUuid())
&& equals(deviceGroup, namePartRevision, mapUuidMaxIdDeviceGroup);
// add to count
if (check) {
id_ok_namePartRevision.add(deviceGroup.getId());
idOkNamePartRevision.add(deviceGroup.getId());
} else {
id_nok_namePartRevision.add(deviceGroup.getId());
idNokNamePartRevision.add(deviceGroup.getId());
}
}
prepareLogReport("readMigrationNamePartRevision, check, after devicegroup, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, after devicegroup, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
prepareLogReport(report, addSpaceUntilSize("after devicegroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
// device type
// check entry by entry
// each attribute as expected
for (DeviceType deviceType : deviceTypes) {
// each attribute as expected
for (WipDeviceType deviceType : deviceTypes) {
namePartRevision = mapIdNamePartRevision.get(deviceType.getId());
check = namePartRevision != null;
check = check && deviceType.getId().equals(namePartRevision.getId());
check = check && deviceType.getVersion().equals(namePartRevision.getVersion());
check = check && deviceType.getUuid().equals(namePartRevision.getNamePart().getUuid());
// parent uuid
check = check && deviceType.getParentUuid().equals(namePartRevision.getParent().getUuid());
check = check && StringUtils.equals(deviceType.getName(), namePartRevision.getName());
check = check && StringUtils.equals(deviceType.getMnemonic(), namePartRevision.getMnemonic());
check = check && StringUtils.equals(deviceType.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
check = check && StringUtils.equals(deviceType.getDescription(), namePartRevision.getDescription());
check = check && ((deviceType.getStatus() == null && namePartRevision.getStatus() == null)
|| (deviceType.getStatus().name().equals(namePartRevision.getStatus().name())));
// latest
// true if id = get max id for uuid
// special rules for pending, not consider pending
check = check && deviceType.isLatest() == deviceType.getId().equals(mapUuidMaxIdDeviceType.get(deviceType.getUuid()));
check = check && deviceType.isDeleted() == namePartRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((deviceType.getRequested() == null && namePartRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(deviceType.getRequested()), SDF.format(namePartRevision.getRequestDate())));
check = check && (deviceType.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
|| StringUtils.equals(deviceType.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(deviceType.getRequestedComment(), namePartRevision.getRequesterComment());
check = check && ((deviceType.getProcessed() == null && namePartRevision.getProcessDate() == null)
|| StringUtils.equals(SDF.format(deviceType.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
check = check && (deviceType.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
|| StringUtils.equals(deviceType.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
check = check && StringUtils.equals(deviceType.getProcessedComment(), namePartRevision.getProcessorComment());
check = namePartRevision != null
&& deviceType.getParentUuid().equals(namePartRevision.getParent().getUuid())
&& equals(deviceType, namePartRevision, mapUuidMaxIdDeviceType);
// add to count
if (check) {
idOkNamePartRevision.add(deviceType.getId());
} else {
idNokNamePartRevision.add(deviceType.getId());
}
}
prepareLogReport(report, addSpaceUntilSize("after devicetype", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport(report, DIVIDER_96);
// ok if
// all entries ok
// no entry nok
boolean ok = sumStructures == namePartRevisions.size()
&& idOkNamePartRevision.size() == namePartRevisions.size()
&& idNokNamePartRevision.isEmpty();
prepareLogReport(report, "Result");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, "ok: " + ok);
prepareLogReport(report, DIVIDER_128);
return report.toString();
}
/**
* Perform verification of data migration with focus on names, i.e. device revisions.
* Ok if all entries ok and no entry nok.
*
* @return report of data migration
*/
@GetMapping(
path = {"/migration_names"},
produces = {"text/plain"})
public String verifyMigrationNames() {
// about
// verification of names (after) vs. devices (before)
// how
// find data for verification
// names - name
// devices - devicerevision, device
// with help of namepartrevision, namepart
// utility
// interpret data into hashmaps for faster retrieval in checks
// check
// for each name
// check entry by entry
// each attribute as expected
// ok if
// all entries ok
// no entry nok
// e.g. if there has been usage of new database tables (new entries) before verification, there are more rows in those tables
// which means new and more ids than in old database tables
// which means those new ids don't exist in old database tables
// --> retrieval of device revisions for those ids will give null
StringBuilder report = new StringBuilder();
prepareLogReport(report, "About verification for data migration of names");
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, " Compare names data before and after migration");
prepareLogReport(report, " Check that each entry is migrated and that content after migration is same as content before migration");
prepareLogReport(report, " ");
prepareLogReport(report, " 1) Find data for structures before migration (all entries in tables)");
prepareLogReport(report, " Find data for names before migration (all entries in tables)");
prepareLogReport(report, " Find data for names after migration (all entries in tables)");
prepareLogReport(report, " 2) Prepare map (uuid, namepartrevision) for data before migration");
prepareLogReport(report, " Prepare map (id, devicerevision) for data before migration");
prepareLogReport(report, " Prepare map (uuid, max id) for data after migration, for each name, corresponding to latest approved entry in each line of uuid");
prepareLogReport(report, " 3) Process each name entry (data after migration)");
prepareLogReport(report, " For each entry, find corresponding data before migration and check that attributes are same and that correct entry has latest attribute set");
prepareLogReport(report, " Count entries for which data are same and not same (ok, nok)");
prepareLogReport(report, " 4) Result is ok if");
prepareLogReport(report, " number of entries before and after migration are same");
prepareLogReport(report, " number of entries which are not same is 0");
prepareLogReport(report, DIVIDER_128);
// find data
List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
List<DeviceRevision> deviceRevisions = deviceRevisionRepository.findAll();
List<WipName> names = holderIWipRepositories.nameRepository().findAll();
prepareLogReport(report, "Find data");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# namepartrevision:", SPACE_UNTIL_SIZE_48) + namePartRevisions.size());
prepareLogReport(report, addSpaceUntilSize("# devicerevision:", SPACE_UNTIL_SIZE_48) + deviceRevisions.size());
prepareLogReport(report, addSpaceUntilSize("# wip name:", SPACE_UNTIL_SIZE_48) + names.size());
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# name:", SPACE_UNTIL_SIZE_48) + holderIRepositories.nameRepository().findAll().size());
prepareLogReport(report, addSpaceUntilSize("# audit name:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditNameRepository().countAuditNames(null));
prepareLogReport(report, DIVIDER_96);
// utility
// interpret lists into hashmaps for faster retrieval in for loop below
// used to help check name entries
// ----------
// mapUuidNamePartRevision - find out name part revision for given uuid
// mapIdDeviceRevision - find corresponding (old) device revision for given id
// mapUuidMaxIdName - find out latest name id for given uuid
HashMap<UUID, NamePartRevision> mapUuidNamePartRevision = new HashMap<>((int)(namePartRevisions.size()/0.75 + 2));
for (NamePartRevision namePartRevision : namePartRevisions) {
mapUuidNamePartRevision.put(namePartRevision.getNamePart().getUuid(), namePartRevision);
}
HashMap<Long, DeviceRevision> mapIdDeviceRevision = new HashMap<>((int)(deviceRevisions.size()/0.75 + 2));
for (DeviceRevision deviceRevision : deviceRevisions) {
mapIdDeviceRevision.put(deviceRevision.getId(), deviceRevision);
}
HashMap<UUID, Long> mapUuidMaxIdName = new HashMap<>();
for (WipName name : names) {
if (mapUuidMaxIdName.get(name.getUuid()) == null
|| name.getId() > mapUuidMaxIdName.get(name.getUuid())) {
mapUuidMaxIdName.put(name.getUuid(), name.getId());
}
}
prepareLogReport(report, "Utility");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# map uuid namepartrevision:", SPACE_UNTIL_SIZE_48) + mapUuidNamePartRevision.size());
prepareLogReport(report, addSpaceUntilSize("# map id devicerevision:", SPACE_UNTIL_SIZE_48) + mapIdDeviceRevision.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid maxid name:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdName.size());
prepareLogReport(report, DIVIDER_96);
// keep track of id
// ok
// nok
SortedSet<Long> idOkDeviceRevision = new TreeSet<>();
SortedSet<Long> idNokDeviceRevision = new TreeSet<>();
prepareLogReport(report, addSpaceUntilSize("Check", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# ok devicerevision", SPACE_UNTIL_SIZE_32) + addSpaceUntilSize("# nok devicerevision", SPACE_UNTIL_SIZE_32));
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("before", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkDeviceRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokDeviceRevision.size(), SPACE_UNTIL_SIZE_32));
// name
// check entry by entry
// each attribute as expected
boolean check = false;
DeviceRevision deviceRevision = null;
try {
for (WipName name : names) {
deviceRevision = mapIdDeviceRevision.get(name.getId());
check = deviceRevision != null
&& equals(name, deviceRevision, mapUuidMaxIdName, mapUuidNamePartRevision);
// add to count
if (check) {
id_ok_namePartRevision.add(deviceType.getId());
idOkDeviceRevision.add(name.getId());
} else {
id_nok_namePartRevision.add(deviceType.getId());
idNokDeviceRevision.add(name.getId());
}
}
prepareLogReport("readMigrationNamePartRevision, check, after devicetype, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, after devicetype, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
} catch (Exception e) {
e.printStackTrace();
}
prepareLogReport(report, addSpaceUntilSize("after", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkDeviceRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokDeviceRevision.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport(report, DIVIDER_96);
// ok if
// all entries ok
// no entry nok
boolean ok = id_ok_namePartRevision.size() == namePartRevisions.size()
&& id_nok_namePartRevision.isEmpty();
boolean ok = names.size() == deviceRevisions.size()
&& idOkDeviceRevision.size() == deviceRevisions.size()
&& idNokDeviceRevision.isEmpty();
prepareLogReport("readMigrationNamePartRevision, check, after, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, check, after, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, ok: " + ok, reportHtml);
prepareLogReport(report, "Result");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, "ok: " + ok);
prepareLogReport(report, DIVIDER_128);
return reportHtml.toString();
return report.toString();
}
// ----------------------------------------------------------------------------------------------------
/**
* Perform verification of data in sense that all data can be reached. Current data is one thing but suggested data (pending) and old data (obsolete) is another thing.
* Perform verification of data in the sense that all data can be reached. Current data is one thing but suggested data (pending) and old data (obsolete) is another thing.
* All data reached verification can be done like selecting all entries from tables (names, system group, system, subsystem, discipline, device group, device type)
* and then take uuid and retrieve history for uuid. By that, all entries should be reached. In a sense, select distinct uuid, then retrieve history by uuid,
* all ids should be encompassed by looking at all returned rows. Requires a couple of for loops and maps and sets to keep track of things.
......@@ -781,43 +732,68 @@ public class VerificationController {
*
* @return report of reachability of data
*/
@GetMapping("/data_reachable")
public String readDataReachable() {
StringBuilder reportHtml = new StringBuilder();
List<Name> names = holderIRepositories.getNameRepository().findAll();
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findAll();
List<System> systems = holderIRepositories.getSystemRepository().findAll();
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findAll();
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findAll();
List<DeviceGroup> deviceGroups = holderIRepositories.getDeviceGroupRepository().findAll();
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findAll();
prepareLogReport("readDataReachable, find data, names.size: " + names.size(), reportHtml);
prepareLogReport("readDataReachable, find data, systemGroups.size: " + systemGroups.size(), reportHtml);
prepareLogReport("readDataReachable, find data, systems.size: " + systems.size(), reportHtml);
prepareLogReport("readDataReachable, find data, subsystems.size: " + subsystems.size(), reportHtml);
prepareLogReport("readDataReachable, find data, disciplines.size: " + disciplines.size(), reportHtml);
prepareLogReport("readDataReachable, find data, deviceGroups.size: " + deviceGroups.size(), reportHtml);
prepareLogReport("readDataReachable, find data, deviceTypes.size: " + deviceTypes.size(), reportHtml);
HashSet<Long> setIdName = new HashSet<>();
HashSet<Long> setIdSystemGroup = new HashSet<>();
HashSet<Long> setIdSystem = new HashSet<>();
HashSet<Long> setIdSubsystem = new HashSet<>();
HashSet<Long> setIdDiscipline = new HashSet<>();
HashSet<Long> setIdDeviceGroup = new HashSet<>();
HashSet<Long> setIdDeviceType = new HashSet<>();
List<Name> namesByUuid = null;
List<SystemGroup> systemGroupsByUuid = null;
List<System> systemsByUuid = null;
List<Subsystem> subsystemsByUuid = null;
List<Discipline> disciplinesByUuid = null;
List<DeviceGroup> deviceGroupsByUuid = null;
List<DeviceType> deviceTypesByUuid = null;
prepareLogReport("readDataReachable, check, before", reportHtml);
@GetMapping(
path = {"/data_reachable"},
produces = {"text/plain"})
public String verifyDataReachable() {
StringBuilder report = new StringBuilder();
prepareLogReport(report, "About verification for reachability of data");
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, " Check that each entry in tables for migrated data (structures, names) also can be reached through find by id");
prepareLogReport(report, " ");
prepareLogReport(report, " 1) Find data for structures after migration (all entries in tables)");
prepareLogReport(report, " Find data for names after migration (all entries in tables)");
prepareLogReport(report, " 2) Process each name entry (data after migration)");
prepareLogReport(report, " For each entry, find corresponding data by id");
prepareLogReport(report, " Count entries found by id");
prepareLogReport(report, " 3) Process each kind of structure entry and each entry therein (data after migration)");
prepareLogReport(report, " For each entry, find corresponding data by id");
prepareLogReport(report, " Count entries found by id");
prepareLogReport(report, " 4) Result is ok if");
prepareLogReport(report, " number of entries (name) is same as number of entries found by id");
prepareLogReport(report, " number of entries (structure) is same as number of entries found by id");
prepareLogReport(report, DIVIDER_128);
List<WipName> names = holderIWipRepositories.nameRepository().findAll();
List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findAll();
List<WipSystem> systems = holderIWipRepositories.systemRepository().findAll();
List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findAll();
List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findAll();
List<WipDeviceGroup> deviceGroups = holderIWipRepositories.deviceGroupRepository().findAll();
List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findAll();
prepareLogReport(report, "Find data");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# name:", SPACE_UNTIL_SIZE_48) + names.size());
prepareLogReport(report, addSpaceUntilSize("# systemgroup:", SPACE_UNTIL_SIZE_48) + systemGroups.size());
prepareLogReport(report, addSpaceUntilSize("# system:", SPACE_UNTIL_SIZE_48) + systems.size());
prepareLogReport(report, addSpaceUntilSize("# subsystem:", SPACE_UNTIL_SIZE_48) + subsystems.size());
prepareLogReport(report, addSpaceUntilSize("# discipline:", SPACE_UNTIL_SIZE_48) + disciplines.size());
prepareLogReport(report, addSpaceUntilSize("# devicegroup:", SPACE_UNTIL_SIZE_48) + deviceGroups.size());
prepareLogReport(report, addSpaceUntilSize("# devicetype:", SPACE_UNTIL_SIZE_48) + deviceTypes.size());
prepareLogReport(report, DIVIDER_96);
HashSet<Long> foundbyIdName = new HashSet<>();
HashSet<Long> foundbyIdSystemGroup = new HashSet<>();
HashSet<Long> foundbyIdSystem = new HashSet<>();
HashSet<Long> foundbyIdSubsystem = new HashSet<>();
HashSet<Long> foundbyIdDiscipline = new HashSet<>();
HashSet<Long> foundbyIdDeviceGroup = new HashSet<>();
HashSet<Long> foundbyIdDeviceType = new HashSet<>();
List<WipName> namesByUuid = null;
List<WipSystemGroup> systemGroupsByUuid = null;
List<WipSystem> systemsByUuid = null;
List<WipSubsystem> subsystemsByUuid = null;
List<WipDiscipline> disciplinesByUuid = null;
List<WipDeviceGroup> deviceGroupsByUuid = null;
List<WipDeviceType> deviceTypesByUuid = null;
prepareLogReport(report, addSpaceUntilSize("Check", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# found by id", SPACE_UNTIL_SIZE_32));
prepareLogReport(report, DIVIDER_96);
// get started
// go through list(s)
......@@ -826,117 +802,142 @@ public class VerificationController {
// ok if set(s) size same as list(s) size
// any entry not in set or once in set
for (Name name : names) {
for (WipName name : names) {
// to mimic - Find history for name by uuid
namesByUuid = holderIRepositories.getNameRepository().findByUuid(name.getUuid().toString());
for (Name nameByUuid : namesByUuid) {
setIdName.add(nameByUuid.getId());
namesByUuid = holderIWipRepositories.nameRepository().findByUuid(name.getUuid().toString());
for (WipName nameByUuid : namesByUuid) {
foundbyIdName.add(nameByUuid.getId());
}
}
prepareLogReport(report, addSpaceUntilSize("after name", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdName.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readDataReachable, check, after name, setIdName.size: " + setIdName.size(), reportHtml);
for (SystemGroup systemGroup : systemGroups) {
for (WipSystemGroup systemGroup : systemGroups) {
// to mimic - Find history for system group by uuid
systemGroupsByUuid = holderIRepositories.getSystemGroupRepository().findByUuid(systemGroup.getUuid().toString());
for (SystemGroup systemGroupByUuid : systemGroupsByUuid) {
setIdSystemGroup.add(systemGroupByUuid.getId());
systemGroupsByUuid = holderIWipRepositories.systemGroupRepository().findByUuid(systemGroup.getUuid().toString());
for (WipSystemGroup systemGroupByUuid : systemGroupsByUuid) {
foundbyIdSystemGroup.add(systemGroupByUuid.getId());
}
}
prepareLogReport(report, addSpaceUntilSize("after systemgroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdSystemGroup.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readDataReachable, check, after systemgroup, setIdSystemGroup.size: " + setIdSystemGroup.size(), reportHtml);
for (System system : systems) {
for (WipSystem system : systems) {
// to mimic - Find history for system by uuid
systemsByUuid = holderIRepositories.getSystemRepository().findByUuid(system.getUuid().toString());
for (System systemByUuid : systemsByUuid) {
setIdSystem.add(systemByUuid.getId());
systemsByUuid = holderIWipRepositories.systemRepository().findByUuid(system.getUuid().toString());
for (WipSystem systemByUuid : systemsByUuid) {
foundbyIdSystem.add(systemByUuid.getId());
}
}
prepareLogReport(report, addSpaceUntilSize("after system", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdSystem.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readDataReachable, check, after system, setIdSystem.size: " + setIdSystem.size(), reportHtml);
for (Subsystem subsystem : subsystems) {
for (WipSubsystem subsystem : subsystems) {
// to mimic - Find history for subsystem by uuid
subsystemsByUuid = holderIRepositories.getSubsystemRepository().findByUuid(subsystem.getUuid().toString());
for (Subsystem subsystemByUuid : subsystemsByUuid) {
setIdSubsystem.add(subsystemByUuid.getId());
subsystemsByUuid = holderIWipRepositories.subsystemRepository().findByUuid(subsystem.getUuid().toString());
for (WipSubsystem subsystemByUuid : subsystemsByUuid) {
foundbyIdSubsystem.add(subsystemByUuid.getId());
}
}
prepareLogReport(report, addSpaceUntilSize("after subsystem", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdSubsystem.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readDataReachable, check, after subsystem, setIdSubsystem.size: " + setIdSubsystem.size(), reportHtml);
for (Discipline discipline : disciplines) {
for (WipDiscipline discipline : disciplines) {
// to mimic - Find history for discipline by uuid
disciplinesByUuid = holderIRepositories.getDisciplineRepository().findByUuid(discipline.getUuid().toString());
for (Discipline disciplineByUuid : disciplinesByUuid) {
setIdDiscipline.add(disciplineByUuid.getId());
disciplinesByUuid = holderIWipRepositories.disciplineRepository().findByUuid(discipline.getUuid().toString());
for (WipDiscipline disciplineByUuid : disciplinesByUuid) {
foundbyIdDiscipline.add(disciplineByUuid.getId());
}
}
prepareLogReport(report, addSpaceUntilSize("after discipline", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdDiscipline.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readDataReachable, check, after discipline, setIdDiscipline.size: " + setIdDiscipline.size(), reportHtml);
for (DeviceGroup deviceGroup : deviceGroups) {
for (WipDeviceGroup deviceGroup : deviceGroups) {
// to mimic - Find history for device group by uuid
deviceGroupsByUuid = holderIRepositories.getDeviceGroupRepository().findByUuid(deviceGroup.getUuid().toString());
for (DeviceGroup deviceGroupByUuid : deviceGroupsByUuid) {
setIdDeviceGroup.add(deviceGroupByUuid.getId());
deviceGroupsByUuid = holderIWipRepositories.deviceGroupRepository().findByUuid(deviceGroup.getUuid().toString());
for (WipDeviceGroup deviceGroupByUuid : deviceGroupsByUuid) {
foundbyIdDeviceGroup.add(deviceGroupByUuid.getId());
}
}
prepareLogReport(report, addSpaceUntilSize("after devicegroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdDeviceGroup.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readDataReachable, check, after devicegroup, setIdDeviceGroup.size: " + setIdDeviceGroup.size(), reportHtml);
for (DeviceType deviceType : deviceTypes) {
for (WipDeviceType deviceType : deviceTypes) {
// to mimic - Find history for device type by uuid
deviceTypesByUuid = holderIRepositories.getDeviceTypeRepository().findByUuid(deviceType.getUuid().toString());
for (DeviceType deviceTypeByUuid : deviceTypesByUuid) {
setIdDeviceType.add(deviceTypeByUuid.getId());
deviceTypesByUuid = holderIWipRepositories.deviceTypeRepository().findByUuid(deviceType.getUuid().toString());
for (WipDeviceType deviceTypeByUuid : deviceTypesByUuid) {
foundbyIdDeviceType.add(deviceTypeByUuid.getId());
}
}
prepareLogReport("readDataReachable, check, after devicetype, setIdDeviceType.size: " + setIdDeviceType.size(), reportHtml);
boolean ok = names.size() == setIdName.size()
&& systemGroups.size() == setIdSystemGroup.size()
&& systems.size() == setIdSystem.size()
&& subsystems.size() == setIdSubsystem.size()
&& disciplines.size() == setIdDiscipline.size()
&& deviceGroups.size() == setIdDeviceGroup.size()
&& deviceTypes.size() == setIdDeviceType.size();
prepareLogReport("readDataReachable, check, after", reportHtml);
prepareLogReport("readDataReachable, ok: " + ok, reportHtml);
return reportHtml.toString();
prepareLogReport(report, addSpaceUntilSize("after devicetype", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdDeviceType.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport(report, DIVIDER_96);
boolean ok = names.size() == foundbyIdName.size()
&& systemGroups.size() == foundbyIdSystemGroup.size()
&& systems.size() == foundbyIdSystem.size()
&& subsystems.size() == foundbyIdSubsystem.size()
&& disciplines.size() == foundbyIdDiscipline.size()
&& deviceGroups.size() == foundbyIdDeviceGroup.size()
&& deviceTypes.size() == foundbyIdDeviceType.size();
prepareLogReport(report, "Result");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, "ok: " + ok);
prepareLogReport(report, DIVIDER_128);
return report.toString();
}
/**
* Verify difference between old REST API and new REST API.
* Perform verification of differences between old REST API and new REST API.
*
* Amount is less in new than in old. Verify that all content in new REST API is in old REST API and that difference is old/obsolete data.
*
* @return
*/
@GetMapping("/restapi_oldvsnew")
public String readRestApiOldVsNew() {
StringBuilder reportHtml = new StringBuilder();
@GetMapping(
path = {"/restapi_oldvsnew"},
produces = {"text/plain"})
public String verifyRestApiOldVsNew() {
StringBuilder report = new StringBuilder();
prepareLogReport(report, "About verification for REST API, old vs new");
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
prepareLogReport(report, DIVIDER_128);
prepareLogReport(report, " Check that difference between content in new REST API vs content in old REST API is as expected");
prepareLogReport(report, " Old REST API - One value per name equivalence");
prepareLogReport(report, " New REST API - Obsolete values are not shown unless history is requested");
prepareLogReport(report, " ");
prepareLogReport(report, " 1) Find data for names before migration (all entries in tables)");
prepareLogReport(report, " Prepare cache for names before migration");
prepareLogReport(report, " Find data for names after migration (latest)");
prepareLogReport(report, " 2) Prepare map (id, devicerevision) for data before migration");
prepareLogReport(report, " Prepare map (id, devicerevision) for data before migration for comparing difference old - new REST API (same as above at start))");
prepareLogReport(report, " Prepare map (id, uuid) for data before migration");
prepareLogReport(report, " Prepare map (uuid, name) for data after migration (latest)");
prepareLogReport(report, " 3) Look into old REST API");
prepareLogReport(report, " 4) Compare old REST API with new REST API");
prepareLogReport(report, " Make note of difference (1)");
prepareLogReport(report, " 5) Check that difference is old / obsolete data");
prepareLogReport(report, " Make note of difference (2)");
prepareLogReport(report, " 6) Result is ok if");
prepareLogReport(report, " all entries in difference are superseded by later entries in new REST API");
prepareLogReport(report, " no entry in difference is available in new REST API");
prepareLogReport(report, DIVIDER_128);
// prepare old REST API
List<DeviceRevision> deviceRevisions = deviceRevisionRepository.findAll();
// old REST API cache
NameViewProvider nameViewProvider = new NameViewProvider();
nameViewProvider.update(deviceRevisions);
// prepare new REST API
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted();
List<Name> namesLatest = holderIRepositories.getNameRepository().findLatest();
List<WipName> namesLatest = holderIWipRepositories.nameRepository().findLatest();
prepareLogReport("readRestApiOldVsNew, find data, deviceRevisions.size: " + deviceRevisions.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, find data, nameViewProvider.getNameRevisions.entrySet.size: " + nameViewProvider.getNameRevisions().entrySet().size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, find data, names.size: " + names.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, find data, namesLatest.size: " + namesLatest.size(), reportHtml);
prepareLogReport(report, "Find data");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# devicerevision:", SPACE_UNTIL_SIZE_48) + deviceRevisions.size());
prepareLogReport(report, addSpaceUntilSize("# cache:", SPACE_UNTIL_SIZE_48) + nameViewProvider.getNameRevisions().entrySet().size());
prepareLogReport(report, addSpaceUntilSize("# name latest:", SPACE_UNTIL_SIZE_48) + namesLatest.size());
prepareLogReport(report, DIVIDER_96);
// prepare comparison
......@@ -949,92 +950,377 @@ public class VerificationController {
mapIdUuidDeviceRevision.put(entry.getValue().getId(), entry.getValue().getDevice().getUuid());
}
HashMap<Long, Name> mapIdName = new HashMap<>((int)(names.size()/0.75 + 2));
for (Name name : names) {
mapIdName.put(name.getId(), name);
}
HashMap<UUID, Name> mapUuidNameLatest = new HashMap<>((int)(namesLatest.size()/0.75 + 2));
for (Name name : namesLatest) {
HashMap<UUID, WipName> mapUuidNameLatest = new HashMap<>((int)(namesLatest.size()/0.75 + 2));
for (WipName name : namesLatest) {
mapUuidNameLatest.put(name.getUuid(), name);
}
prepareLogReport("readRestApiOldVsNew, utility, mapIdDeviceRevision.size: " + mapIdDeviceRevision.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, utility, mapIdDeviceRevisionDifference.size: " + mapIdDeviceRevisionDifference.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, utility, mapIdUuidDeviceRevision.size: " + mapIdUuidDeviceRevision.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, utility, mapIdName.size: " + mapIdName.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, utility, mapUuidNameLatest.size: " + mapUuidNameLatest.size(), reportHtml);
prepareLogReport(report, "Utility");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# map id devicerevision:", SPACE_UNTIL_SIZE_48) + mapIdDeviceRevision.size());
prepareLogReport(report, addSpaceUntilSize("# map id devicerevision difference:", SPACE_UNTIL_SIZE_48) + mapIdDeviceRevisionDifference.size());
prepareLogReport(report, addSpaceUntilSize("# map id uuid devicerevision:", SPACE_UNTIL_SIZE_48) + mapIdUuidDeviceRevision.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid name latest:", SPACE_UNTIL_SIZE_48) + mapUuidNameLatest.size());
prepareLogReport(report, DIVIDER_96);
// find out about old REST API and quality of data
// 0. uuid
// know how many uuid exist multiple times in old rest api
HashMap<UUID, Long> mapUUIDCountCache = new HashMap<>();
for (Entry<String, DeviceRevision> entry : nameViewProvider.getNameRevisions().entrySet()) {
UUID uuid = entry.getValue().getDevice().getUuid();
Long count = mapUUIDCountCache.get(uuid);
long value = count != null ? count.longValue() + 1 : 1;
mapUUIDCountCache.put(uuid, value);
}
prepareLogReport("readRestApiOldVsNew, check, before", reportHtml);
Map<UUID, Long> mapUUIDCountCacheDuplicateSorted = mapUUIDCountCache.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.naturalOrder()))
.filter(e -> e.getValue() > 1)
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
Optional<Entry<UUID, Long>> lastEntry = mapUUIDCountCacheDuplicateSorted.entrySet().stream().reduce((e1, e2) -> e2);
UUID lastKey = lastEntry.isPresent() ? lastEntry.get().getKey() : null;
Long lastCount = mapUUIDCountCacheDuplicateSorted.get(lastKey);
prepareLogReport(report, "Check old REST API");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# map uuid count cache:", SPACE_UNTIL_SIZE_48) + mapUUIDCountCache.size());
prepareLogReport(report, addSpaceUntilSize("# map uuid count cache duplicate sorted:", SPACE_UNTIL_SIZE_48) + mapUUIDCountCacheDuplicateSorted.size());
prepareLogReport(report, addSpaceUntilSize("# count most duplicated uuid:", SPACE_UNTIL_SIZE_48) + lastCount);
prepareLogReport(report, DIVIDER_96);
// compare old REST API with new REST API
// 1. difference
// 1. find difference
// subtract id in new REST API from old REST API
// result is difference
boolean idInOld = true;
int countIdInOld = 0;
int countNotIdInOld = 0;
for (Name name : names) {
int countIdNotInOld = 0;
int countIdNotInOldButDeleted = 0;
for (WipName name : namesLatest) {
idInOld = mapIdDeviceRevisionDifference.containsKey(name.getId());
if (idInOld) {
countIdInOld++;
} else if (!idInOld) {
countNotIdInOld++;
// either bug in old REST API or bug in implementation of cache for old REST API - NEED TO INVESTIGATE
// after investigation, appears bug in old REST API
countIdNotInOld++;
if (name.isDeleted()) {
countIdNotInOldButDeleted++;
}
}
mapIdDeviceRevisionDifference.remove(name.getId());
}
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdDeviceRevision.size: " + mapIdDeviceRevision.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdDeviceRevisionDifference.size: " + mapIdDeviceRevisionDifference.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdUuidDeviceRevision.size: " + mapIdUuidDeviceRevision.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdName.size: " + mapIdName.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapUuidNameLatest.size: " + mapUuidNameLatest.size(), reportHtml);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, countIdInOld: " + countIdInOld, reportHtml);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, countNotIdInOld: " + countNotIdInOld, reportHtml);
// 2. difference is old/obsolete data
// id corresponding to uuid should not be last in line
// <--> last in line should be deleted
prepareLogReport(report, "Check");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# map id devicerevision difference:", SPACE_UNTIL_SIZE_40) + mapIdDeviceRevisionDifference.size());
prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# count id in old:", SPACE_UNTIL_SIZE_40) + countIdInOld);
prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# count id not in old:", SPACE_UNTIL_SIZE_40) + countIdNotInOld);
prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# count id not in old but deleted:", SPACE_UNTIL_SIZE_40) + countIdNotInOldButDeleted);
prepareLogReport(report, DIVIDER_96);
// 2. check difference - is old/obsolete data
// can not know reason for certain
// find uuid corresponding to id, check that id not last in line of uuid
// ---------------------------------------------------------------------
// find uuid, name corresponding to id - should find name
// wrong if no name
// wrong if name is latest
ArrayList<DeviceRevision> listDeviceRevisionWrong = new ArrayList<>();
int countNameNull = 0;
int countNameIdEqualsDiffId = 0;
int countNameIdGreaterThanDiffId = 0;
int countNameIdLessThanDiffId = 0;
for (Entry<Long, DeviceRevision> entry : mapIdDeviceRevisionDifference.entrySet()) {
// for each difference
// find out uuid, name -
// note use of mapUuidNameLatest - latest (!)
UUID uuid = mapIdUuidDeviceRevision.get(entry.getKey());
Name name = uuid != null ? mapUuidNameLatest.get(uuid) : null;
WipName name = uuid != null ? mapUuidNameLatest.get(uuid) : null;
// something may be wrong
// if latest for devicerevision is in names then ok
// else if latest for devicerevision is deleted then ok
// else something is wrong
// if (!latestInLine && !name.isDeleted()) {
// <-->
// name != null && (name.isLatest() || name.isDeleted()) --> ok, else wrong
if (!(name != null && (name.isLatest() || name.isDeleted()))) {
// no name
// name is in remaining difference
if (name == null) {
// something is wrong
listDeviceRevisionWrong.add(entry.getValue());
countNameNull++;
continue;
}
if (name.getId().equals(entry.getKey())) {
listDeviceRevisionWrong.add(entry.getValue());
countNameIdEqualsDiffId++;
} else if (name.getId().longValue() > entry.getKey().longValue()) {
// ok
countNameIdGreaterThanDiffId++;
} else {
listDeviceRevisionWrong.add(entry.getValue());
countNameIdLessThanDiffId++;
}
}
prepareLogReport("readRestApiOldVsNew, check, after difference 2, listDeviceRevisionWrong.size: " + listDeviceRevisionWrong.size(), reportHtml);
boolean ok = (mapIdDeviceRevisionDifference.size() == (nameViewProvider.getNameRevisions().entrySet().size() - names.size()))
prepareLogReport(report, addSpaceUntilSize("after difference detail", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# wrong devicerevision:", SPACE_UNTIL_SIZE_40) + listDeviceRevisionWrong.size());
prepareLogReport(report, addSpaceUntilSize("after difference detail", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# name is nulll:", SPACE_UNTIL_SIZE_40) + countNameNull);
prepareLogReport(report, addSpaceUntilSize("after difference detail", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# name id > id in diff:", SPACE_UNTIL_SIZE_40) + countNameIdGreaterThanDiffId);
prepareLogReport(report, addSpaceUntilSize("after difference detail", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# name id = id in diff:", SPACE_UNTIL_SIZE_40) + countNameIdEqualsDiffId);
prepareLogReport(report, addSpaceUntilSize("after difference detail", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# name id < id in diff:", SPACE_UNTIL_SIZE_40) + countNameIdLessThanDiffId);
prepareLogReport(report, DIVIDER_96);
boolean ok = mapIdDeviceRevisionDifference.size() == countNameIdGreaterThanDiffId
&& listDeviceRevisionWrong.isEmpty();
prepareLogReport("readRestApiOldVsNew, check, after", reportHtml);
prepareLogReport("readRestApiOldVsNew, ok: " + ok, reportHtml);
prepareLogReport(report, "Result");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, "ok: " + ok);
prepareLogReport(report, DIVIDER_128);
return reportHtml.toString();
return report.toString();
}
/**
* Utility method for preparing reports for logging purposes.
*
* @param report
* @param message
* @param reportHtml
* @param reportLog
*/
private void prepareLogReport(String message, StringBuilder reportHtml) {
private void prepareLogReport(StringBuilder report, String message) {
if (!StringUtils.isEmpty(message)) {
report.append(message + NEWLINE);
LOGGER.log(Level.FINE, message);
reportHtml.append(message + NEW_LINE_BR);
}
}
/**
* Utility method to compare Structure with NamePartRevision.
* No check for parent uuid in this method.
*
* @param structure structure
* @param namePartRevision name part revision
* @param mapUuidMaxId map with max id for APPROVED entry in line of uuid for structure
* @return
*/
private boolean equals(WipStructure structure, NamePartRevision namePartRevision, HashMap<UUID, Long> mapUuidMaxId) {
// check
// check entry by entry
// each attribute as expected
// ----------
// to check parent uuid
// ----------
// date may be in different format for different objects, to be formatted before being compared
// ----------
// e.g.
// system.id = namepartrevision.id
// system.version = namepartrevision.version
// system.uuid = namepartrevision.namepart_id (namepart.id --> namepart.uuid)
// ( system.parent_uuid = namepartrevision.parent_id (namepart.id --> namepart.uuid) )
// system.name = namepartrevision.name
// system.mnemonic = namepartrevision.mnemonic
// system.mnemonic_equivalence = namepartrevision.mnemoniceqclass
// system.description = namepartrevision.description
// system.status = namepartrevision.status
// system.latest = true if id = get max id for uuid (consider status, but not PENDING)
// system.deleted = namepartrevision.deleted
// system.requested = namepartrevision.requestdate
// system.requested_by = namepartrevision.requestedby_id (useraccount.id --> useraccount.username)
// system.requested_comment = namepartrevision.requestercomment
// system.processed = namepartrevision.processdate
// system.processed_by = namepartrevision.processedby_id (useraccount.id --> useraccount.username)
// system.processed_comment = namepartrevision.processorcomment
//
// check if deleted && (cancelled, rejected, pending) && no approved in line of uuid, then it might be ok from that perspective
// consider - status, latest, deleted
if (ValidateUtil.isAnyNull(structure, namePartRevision, mapUuidMaxId)) {
return false;
}
boolean check = structure.getId().equals(namePartRevision.getId());
check = check && structure.getVersion().equals(namePartRevision.getVersion());
check = check && structure.getUuid().equals(namePartRevision.getNamePart().getUuid());
// no check for parent uuid in this method
// name and description (NamePartRevision) are concatenated into description (Structure)
// postgresql - nullif(concat_ws('. ', npr1."name", npr1.description)
// to be checked - with care
String concat = null;
String delimiter = ". ";
if (!StringUtils.isEmpty(namePartRevision.getName()) && !StringUtils.isEmpty(namePartRevision.getDescription())) {
concat = namePartRevision.getName() + delimiter + namePartRevision.getDescription();
} else if (StringUtils.isEmpty(namePartRevision.getName()) && !StringUtils.isEmpty(namePartRevision.getDescription())) {
concat = namePartRevision.getDescription();
} else if (!StringUtils.isEmpty(namePartRevision.getName()) && StringUtils.isEmpty(namePartRevision.getDescription())) {
concat = namePartRevision.getName();
}
// check = check && StringUtils.equals(structure.getName(), namePartRevision.getName());
check = check && StringUtils.equals(structure.getMnemonic(), namePartRevision.getMnemonic());
check = check && StringUtils.equals(structure.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
// check = check && StringUtils.equals(structure.getDescription(), namePartRevision.getDescription());
check = check && StringUtils.equals(structure.getDescription(), concat);
check = check && ((structure.getStatus() == null && namePartRevision.getStatus() == null)
|| (structure.getStatus().name().equals(namePartRevision.getStatus().name())));
// latest
// true if id = get max id for uuid
// special rules
// for pending, not consider pending
// for latest, deleted but not approved - ok because there are erroneous entries in database
// handled with V5__Data_transformation_status_deleted.sql
check = check &&
(structure.isLatest() == structure.getId().equals(mapUuidMaxId.get(structure.getUuid()))
|| structure.isLatest() && structure.isDeleted());
check = check &&
(structure.isDeleted() == namePartRevision.isDeleted()
|| structure.isLatest() && structure.isDeleted());
// date may be in different format for different objects, to be formatted before being compared
check = check && ((structure.getRequested() == null && namePartRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(structure.getRequested()), SDF.format(namePartRevision.getRequestDate())));
check = check && (structure.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
|| StringUtils.equals(structure.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(structure.getRequestedComment(), namePartRevision.getRequesterComment());
check = check && ((structure.getProcessed() == null && namePartRevision.getProcessDate() == null)
|| StringUtils.equals(SDF.format(structure.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
check = check && (structure.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
|| StringUtils.equals(structure.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
check = check && StringUtils.equals(structure.getProcessedComment(), namePartRevision.getProcessorComment());
return check;
}
/**
* Utility method to compare Name with DeviceRevision.
*
* @param name name
* @param deviceRevision device revision
* @param mapUuidMaxIdName map with max id for entry in line of uuid for name
* @param mapUuidNamePartRevision map with uuid for name part revision
* @return
*/
private boolean equals(WipName name, DeviceRevision deviceRevision, HashMap<UUID, Long> mapUuidMaxIdName, HashMap<UUID, NamePartRevision> mapUuidNamePartRevision) {
// check
// check entry by entry
// each attribute as expected
// ----------
// to check 1st, 2nd, 3rd parent to determine if systemgroup, system or subsystem
// otherwise not clear how to make sure if it is supposed to be systemgroup and not system, subsystem and vice versa
// ----------
// date may be in different format for different objects, to be formatted before being compared
// ----------
// name.id = devicerevision.id
// name.version = devicerevision.version
// name.uuid = devicerevision.device_id (device.id --> device.uuid)
// name.namepartrevision_systemgroup_uuid = devicerevision.section_id (namepart.id --> namepart.uuid
// name.namepartrevision_system_uuid = devicerevision.section_id (namepart.id --> namepart.uuid
// name.namepartrevision_subsystem_uuid = devicerevision.section_id (namepart.id --> namepart.uuid
// name.namepartrevision_devicetype_uuid = devicerevision.devicetype_id (namepart.id --> namepart.uuid
// name.instance_index = devicerevision.instanceindex
// name.convention_name = devicerevision.conventionname
// name.convention_name_equivalence = devicerevision.conventionnameeqclass
// name.description = devicerevision.additionalinfo
// name.status = null
// name.latest = true if id = get max id for uuid (not consider status)
// name.deleted = devicerevision.deleted
// name.requested = devicerevision.requestdate
// name.requested_by = devicerevision.requestedby_id (useraccount.id --> useraccount.username)
// name.requested_comment = null
// name.processed = null
// name.processed_by = null
// name.processed_comment = devicerevision.processorcomment
if (ValidateUtil.isAnyNull(name, deviceRevision, mapUuidMaxIdName)) {
return false;
}
boolean check = name.getId().equals(deviceRevision.getId());
check = check && name.getVersion().equals(deviceRevision.getVersion());
check = check && name.getUuid().equals(deviceRevision.getDevice().getUuid());
// to check 1st, 2nd, 3rd parent to determine if systemgroup, system or subsystem
// otherwise not clear how to make sure if it is supposed to be systemgroup and not system, subsystem and vice versa
NamePartRevision parent1 = deviceRevision.getSection() != null
? mapUuidNamePartRevision.get(deviceRevision.getSection().getUuid())
: null;
NamePartRevision parent2 = parent1 != null && parent1.getParent() != null
? mapUuidNamePartRevision.get(parent1.getParent().getUuid())
: null;
NamePartRevision parent3 = parent2 != null && parent2.getParent() != null
? mapUuidNamePartRevision.get(parent2.getParent().getUuid())
: null;
// parent 1 but not parent 2, 3 - system group
// parent 1, 2 but not parent 3 - system
// parent 1, 2, 3 - subsystem
// else nok
UUID systemGroupUuid = name.getSystemGroupUuid();
UUID systemUuid = name.getSystemUuid();
UUID subsystemUuid = name.getSubsystemUuid();
UUID sectionUuid = deviceRevision.getSection().getUuid();
if (parent1 != null && parent2 == null && parent3 == null) {
check = check && sectionUuid.equals(systemGroupUuid) && systemUuid == null && subsystemUuid == null;
} else if (parent1 != null && parent2 != null && parent3 == null) {
check = check && sectionUuid.equals(systemUuid) && systemGroupUuid == null && subsystemUuid == null;
} else if (parent1 != null && parent2 != null && parent3 != null) {
check = check && sectionUuid.equals(subsystemUuid) && systemGroupUuid == null && systemUuid == null;
} else {
check = false;
}
check = check && ((name.getDeviceTypeUuid() == null && deviceRevision.getDeviceType() == null)
|| (name.getDeviceTypeUuid().equals(deviceRevision.getDeviceType().getUuid())));
check = check && StringUtils.equals(name.getInstanceIndex(), deviceRevision.getInstanceIndex());
check = check && StringUtils.equals(name.getConventionName(), deviceRevision.getConventionName());
check = check && StringUtils.equals(name.getConventionNameEquivalence(), deviceRevision.getConventionNameEqClass());
check = check && StringUtils.equals(name.getDescription(), deviceRevision.getAdditionalInfo());
check = check && name.getStatus() == null;
// latest
// true if id = get max id for uuid
check = check && name.isLatest() == name.getId().equals(mapUuidMaxIdName.get(name.getUuid()));
check = check && name.isDeleted() == deviceRevision.isDeleted();
// date may be in different format for different objects, to be formatted before being compared
check = check && ((name.getRequested() == null && deviceRevision.getRequestDate() == null)
|| StringUtils.equals(SDF.format(name.getRequested()), SDF.format(deviceRevision.getRequestDate())));
check = check && StringUtils.equals(name.getRequestedBy(), deviceRevision.getRequestedBy().getUsername());
check = check && StringUtils.equals(name.getRequestedComment(), deviceRevision.getProcessorComment());
check = check && name.getProcessed() == null;
check = check && name.getProcessedBy() == null;
check = check && name.getProcessedComment() == null;
return check;
}
/**
* Add space to string (for value) until it has size.
*
* @param str value
* @param size size
* @return string expanded to size
*/
private String addSpaceUntilSize(String str, int size) {
if (str != null && str.length() < size) {
StringBuilder sb = new StringBuilder(str);
while (sb.length() < size) {
sb.append(SPACE);
}
return sb.toString();
}
return str;
}
/**
* Add space to string (for value) until it has size.
*
* @param val value
* @param size size
* @return string expanded to size
*/
private String addSpaceUntilSize(long val, int size) {
return addSpaceUntilSize(String.valueOf(val), size);
}
}
......@@ -29,19 +29,20 @@ import java.util.regex.PatternSyntaxException;
import io.swagger.v3.oas.annotations.Hidden;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository;
import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.model.Name;
import org.openepics.names.repository.model.wip.WipName;
import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
import org.openepics.names.repository.wip.IWipDisciplineRepository;
import org.openepics.names.repository.wip.IWipNameRepository;
import org.openepics.names.repository.wip.IWipSubsystemRepository;
import org.openepics.names.repository.wip.IWipSystemGroupRepository;
import org.openepics.names.repository.wip.IWipSystemRepository;
import org.openepics.names.rest.beans.old.DeviceNameElement;
import org.openepics.names.util.HolderIRepositories;
import org.openepics.names.util.HolderSystemDeviceStructure;
import org.openepics.names.service.LogService;
import org.openepics.names.util.NamingConventionUtil;
import org.openepics.names.util.old.DeviceNameElementUtil;
import org.openepics.names.util.wip.HolderIWipRepositories;
import org.openepics.names.util.wip.HolderWipStructures;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -82,26 +83,29 @@ public class DeviceNamesControllerV0 {
private static final Logger LOGGER = Logger.getLogger(DeviceNamesControllerV0.class.getName());
private HolderIRepositories holderIRepositories;
private final LogService logService;
private final HolderIWipRepositories holderIWipRepositories;
@Autowired
public DeviceNamesControllerV0(
INameRepository iNameRepository,
ISystemGroupRepository iSystemGroupRepository,
ISystemRepository iSystemRepository,
ISubsystemRepository iSubsystemRepository,
IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository) {
holderIRepositories = new HolderIRepositories(
iNameRepository,
iSystemGroupRepository,
iSystemRepository,
iSubsystemRepository,
iDisciplineRepository,
iDeviceGroupRepository,
iDeviceTypeRepository);
LogService logService,
IWipNameRepository iWipNameRepository,
IWipSystemGroupRepository iWipSystemGroupRepository,
IWipSystemRepository iWipSystemRepository,
IWipSubsystemRepository iWipSubsystemRepository,
IWipDisciplineRepository iWipDisciplineRepository,
IWipDeviceGroupRepository iWipDeviceGroupRepository,
IWipDeviceTypeRepository iWipDeviceTypeRepository) {
this.logService = logService;
this.holderIWipRepositories = new HolderIWipRepositories(
iWipNameRepository,
iWipSystemGroupRepository,
iWipSystemRepository,
iWipSubsystemRepository,
iWipDisciplineRepository,
iWipDeviceGroupRepository,
iWipDeviceTypeRepository);
}
/**
......@@ -111,16 +115,16 @@ public class DeviceNamesControllerV0 {
*/
@GetMapping
public List<DeviceNameElement> findNames() {
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted();
List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
// create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
LOGGER.log(Level.FINE, "findNames, deviceNameElement s.size: {0}", deviceNameElements.size());
......@@ -152,18 +156,18 @@ public class DeviceNamesControllerV0 {
try {
pattern = Pattern.compile(name);
} catch (PatternSyntaxException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements;
}
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted();
List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name namee : names) {
for (WipName namee : names) {
if (pattern.matcher(namee.getConventionName()).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(namee, holder));
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(namee, holderStructures));
}
}
......@@ -186,21 +190,21 @@ public class DeviceNamesControllerV0 {
// exact match
// case sensitive
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
final List<DeviceNameElement> deviceNameElements = Lists.newArrayList();
List<Name> namesSystemGroup = holderIRepositories.getNameRepository().findLatestBySystemGroupMnemonic(system);
for (Name name : namesSystemGroup) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
List<WipName> namesSystemGroup = holderIWipRepositories.nameRepository().findLatestBySystemGroupMnemonic(system);
for (WipName name : namesSystemGroup) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
List<Name> namesSystem = holderIRepositories.getNameRepository().findLatestBySystemMnemonic(system);
List<Name> namesSystemThroughSubsystem = holderIRepositories.getNameRepository().findLatestBySystemMnemonicThroughSubsystem(system);
for (Name name : namesSystem) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
List<WipName> namesSystem = holderIWipRepositories.nameRepository().findLatestBySystemMnemonic(system);
List<WipName> namesSystemThroughSubsystem = holderIWipRepositories.nameRepository().findLatestBySystemMnemonicThroughSubsystem(system);
for (WipName name : namesSystem) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
for (Name name : namesSystemThroughSubsystem) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
for (WipName name : namesSystemThroughSubsystem) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
LOGGER.log(Level.FINE, "findNamesBySystem, system: {0}", system);
......@@ -228,19 +232,19 @@ public class DeviceNamesControllerV0 {
try {
pattern = Pattern.compile(system);
} catch (PatternSyntaxException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements;
}
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted();
List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
for (WipName name : names) {
String sub = NamingConventionUtil.extractSystem(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
}
......@@ -263,17 +267,17 @@ public class DeviceNamesControllerV0 {
// exact match
// case sensitive
List<Name> names = holderIRepositories.getNameRepository().findLatestBySubsystemMnemonic(subsystem);
List<WipName> names = holderIWipRepositories.nameRepository().findLatestBySubsystemMnemonic(subsystem);
// create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
if (!names.isEmpty()) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
}
......@@ -302,19 +306,19 @@ public class DeviceNamesControllerV0 {
try {
pattern = Pattern.compile(subsystem);
} catch (PatternSyntaxException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements;
}
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted();
List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
for (WipName name : names) {
String sub = NamingConventionUtil.extractSubsystem(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
}
......@@ -337,17 +341,17 @@ public class DeviceNamesControllerV0 {
// exact match
// case sensitive
List<Name> names = holderIRepositories.getNameRepository().findLatestByDisciplineMnemonic(discipline);
List<WipName> names = holderIWipRepositories.nameRepository().findLatestByDisciplineMnemonicThroughDeviceType(discipline);
// create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
if (!names.isEmpty()) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
}
......@@ -376,19 +380,19 @@ public class DeviceNamesControllerV0 {
try {
pattern = Pattern.compile(discipline);
} catch (PatternSyntaxException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements;
}
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted();
List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
for (WipName name : names) {
String sub = NamingConventionUtil.extractDiscipline(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
}
......@@ -411,17 +415,17 @@ public class DeviceNamesControllerV0 {
// exact match
// case sensitive
List<Name> names = holderIRepositories.getNameRepository().findLatestByDeviceTypeMnemonic(deviceType);
List<WipName> names = holderIWipRepositories.nameRepository().findLatestByDeviceTypeMnemonic(deviceType);
// create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
if (!names.isEmpty()) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
}
......@@ -450,19 +454,19 @@ public class DeviceNamesControllerV0 {
try {
pattern = Pattern.compile(deviceType);
} catch (PatternSyntaxException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements;
}
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted();
List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) {
for (WipName name : names) {
String sub = NamingConventionUtil.extractDeviceType(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder));
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
}
}
......@@ -484,14 +488,14 @@ public class DeviceNamesControllerV0 {
// exact match
// case sensitive
Name name = null;
WipName name = null;
try {
UUID.fromString(uuid);
name = holderIRepositories.getNameRepository().findLatestByUuid(uuid);
name = holderIWipRepositories.nameRepository().findLatestByUuid(uuid);
} catch (IllegalArgumentException e) {
name = holderIRepositories.getNameRepository().findLatestByConventionName(uuid);
name = holderIWipRepositories.nameRepository().findLatestByConventionName(uuid);
}
DeviceNameElement deviceNameElement = DeviceNameElementUtil.getDeviceNameElement(name, holderIRepositories);
DeviceNameElement deviceNameElement = DeviceNameElementUtil.getDeviceNameElement(name, holderIWipRepositories);
LOGGER.log(Level.FINE, "findName, uuid: {0}", uuid);
LOGGER.log(Level.FINE, "findName, deviceNameElement: {0}", deviceNameElement);
......
......@@ -23,23 +23,23 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository;
import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.model.Discipline;
import org.openepics.names.repository.model.Name;
import org.openepics.names.repository.model.Subsystem;
import org.openepics.names.repository.model.System;
import org.openepics.names.repository.model.SystemGroup;
import org.openepics.names.repository.model.wip.WipDeviceGroup;
import org.openepics.names.repository.model.wip.WipDeviceType;
import org.openepics.names.repository.model.wip.WipDiscipline;
import org.openepics.names.repository.model.wip.WipName;
import org.openepics.names.repository.model.wip.WipSubsystem;
import org.openepics.names.repository.model.wip.WipSystem;
import org.openepics.names.repository.model.wip.WipSystemGroup;
import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
import org.openepics.names.repository.wip.IWipDisciplineRepository;
import org.openepics.names.repository.wip.IWipNameRepository;
import org.openepics.names.repository.wip.IWipSubsystemRepository;
import org.openepics.names.repository.wip.IWipSystemGroupRepository;
import org.openepics.names.repository.wip.IWipSystemRepository;
import org.openepics.names.rest.beans.old.HistoryElement;
import org.openepics.names.util.HolderIRepositories;
import org.openepics.names.util.old.HistoryElementUtil;
import org.openepics.names.util.wip.HolderIWipRepositories;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -75,26 +75,26 @@ public class HistoryControllerV0 {
private static final long THOUSAND_MILLISECONDS = 1000;
private HolderIRepositories holderIRepositories;
private final HolderIWipRepositories holderIWipRepositories;
@Autowired
public HistoryControllerV0(
INameRepository iNameRepository,
ISystemGroupRepository iSystemGroupRepository,
ISystemRepository iSystemRepository,
ISubsystemRepository iSubsystemRepository,
IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository) {
holderIRepositories = new HolderIRepositories(
iNameRepository,
iSystemGroupRepository,
iSystemRepository,
iSubsystemRepository,
iDisciplineRepository,
iDeviceGroupRepository,
iDeviceTypeRepository);
IWipNameRepository iWipNameRepository,
IWipSystemGroupRepository iWipSystemGroupRepository,
IWipSystemRepository iWipSystemRepository,
IWipSubsystemRepository iWipSubsystemRepository,
IWipDisciplineRepository iWipDisciplineRepository,
IWipDeviceGroupRepository iWipDeviceGroupRepository,
IWipDeviceTypeRepository iWipDeviceTypeRepository) {
this.holderIWipRepositories = new HolderIWipRepositories(
iWipNameRepository,
iWipSystemGroupRepository,
iWipSystemRepository,
iWipSubsystemRepository,
iWipDisciplineRepository,
iWipDeviceGroupRepository,
iWipDeviceTypeRepository);
}
/**
......@@ -118,16 +118,16 @@ public class HistoryControllerV0 {
return historyElements;
}
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findByUuid(uuid);
List<System> systems = holderIRepositories.getSystemRepository().findByUuid(uuid);
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findByUuid(uuid);
List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findByUuid(uuid);
List<WipSystem> systems = holderIWipRepositories.systemRepository().findByUuid(uuid);
List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findByUuid(uuid);
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findByUuid(uuid);
List<DeviceGroup> deviceGroups = holderIRepositories.getDeviceGroupRepository().findByUuid(uuid);
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findByUuid(uuid);
List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findByUuid(uuid);
List<WipDeviceGroup> deviceGroups = holderIWipRepositories.deviceGroupRepository().findByUuid(uuid);
List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findByUuid(uuid);
if (!systemGroups.isEmpty()) {
for (SystemGroup systemGroup : systemGroups) {
for (WipSystemGroup systemGroup : systemGroups) {
// one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
......@@ -143,7 +143,7 @@ public class HistoryControllerV0 {
}
}
} else if (!systems.isEmpty()) {
for (System system : systems) {
for (WipSystem system : systems) {
// one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
......@@ -159,7 +159,7 @@ public class HistoryControllerV0 {
}
}
} else if (!subsystems.isEmpty()) {
for (Subsystem subsystem : subsystems) {
for (WipSubsystem subsystem : subsystems) {
// one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
......@@ -175,7 +175,7 @@ public class HistoryControllerV0 {
}
}
} else if (!disciplines.isEmpty()) {
for (Discipline discipline : disciplines) {
for (WipDiscipline discipline : disciplines) {
// one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
......@@ -191,7 +191,7 @@ public class HistoryControllerV0 {
}
}
} else if (!deviceGroups.isEmpty()) {
for (DeviceGroup deviceGroup : deviceGroups) {
for (WipDeviceGroup deviceGroup : deviceGroups) {
// one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
......@@ -207,7 +207,7 @@ public class HistoryControllerV0 {
}
}
} else if (!deviceTypes.isEmpty()) {
for (DeviceType deviceType : deviceTypes) {
for (WipDeviceType deviceType : deviceTypes) {
// one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
......@@ -251,8 +251,8 @@ public class HistoryControllerV0 {
return historyElements;
}
List<Name> names = holderIRepositories.getNameRepository().findByUuid(uuid);
for (Name name : names) {
List<WipName> names = holderIWipRepositories.nameRepository().findByUuid(uuid);
for (WipName name : names) {
historyElements.add(HistoryElementUtil.getHistoryElement(name));
}
......
......@@ -25,23 +25,24 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository;
import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.model.Discipline;
import org.openepics.names.repository.model.Subsystem;
import org.openepics.names.repository.model.System;
import org.openepics.names.repository.model.SystemGroup;
import org.openepics.names.repository.model.wip.WipDeviceGroup;
import org.openepics.names.repository.model.wip.WipDeviceType;
import org.openepics.names.repository.model.wip.WipDiscipline;
import org.openepics.names.repository.model.wip.WipSubsystem;
import org.openepics.names.repository.model.wip.WipSystem;
import org.openepics.names.repository.model.wip.WipSystemGroup;
import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
import org.openepics.names.repository.wip.IWipDisciplineRepository;
import org.openepics.names.repository.wip.IWipNameRepository;
import org.openepics.names.repository.wip.IWipSubsystemRepository;
import org.openepics.names.repository.wip.IWipSystemGroupRepository;
import org.openepics.names.repository.wip.IWipSystemRepository;
import org.openepics.names.rest.beans.old.PartElement;
import org.openepics.names.util.HolderIRepositories;
import org.openepics.names.service.LogService;
import org.openepics.names.util.NamingConventionUtil;
import org.openepics.names.util.old.PartElementUtil;
import org.openepics.names.util.wip.HolderIWipRepositories;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -76,26 +77,29 @@ public class PartControllerV0 {
private static final Logger LOGGER = Logger.getLogger(PartControllerV0.class.getName());
private HolderIRepositories holderIRepositories;
private final LogService logService;
private final HolderIWipRepositories holderIWipRepositories;
@Autowired
public PartControllerV0(
INameRepository iNameRepository,
ISystemGroupRepository iSystemGroupRepository,
ISystemRepository iSystemRepository,
ISubsystemRepository iSubsystemRepository,
IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository) {
holderIRepositories = new HolderIRepositories(
iNameRepository,
iSystemGroupRepository,
iSystemRepository,
iSubsystemRepository,
iDisciplineRepository,
iDeviceGroupRepository,
iDeviceTypeRepository);
LogService logService,
IWipNameRepository iWipNameRepository,
IWipSystemGroupRepository iWipSystemGroupRepository,
IWipSystemRepository iWipSystemRepository,
IWipSubsystemRepository iWipSubsystemRepository,
IWipDisciplineRepository iWipDisciplineRepository,
IWipDeviceGroupRepository iWipDeviceGroupRepository,
IWipDeviceTypeRepository iWipDeviceTypeRepository) {
this.logService = logService;
this.holderIWipRepositories = new HolderIWipRepositories(
iWipNameRepository,
iWipSystemGroupRepository,
iWipSystemRepository,
iWipSubsystemRepository,
iWipDisciplineRepository,
iWipDeviceGroupRepository,
iWipDeviceTypeRepository);
}
/**
......@@ -115,30 +119,30 @@ public class PartControllerV0 {
// find in system structure
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findLatestByMnemonic(mnemonic);
List<System> systems = holderIRepositories.getSystemRepository().findLatestByMnemonic(mnemonic);
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findLatestByMnemonic(mnemonic);
List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatestByMnemonic(mnemonic);
List<WipSystem> systems = holderIWipRepositories.systemRepository().findLatestByMnemonic(mnemonic);
List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findLatestByMnemonic(mnemonic);
for (SystemGroup systemGroup : systemGroups) {
for (WipSystemGroup systemGroup : systemGroups) {
partElements.add(PartElementUtil.getPartElement(systemGroup));
}
for (System system : systems) {
partElements.add(PartElementUtil.getPartElement(system, holderIRepositories));
for (WipSystem system : systems) {
partElements.add(PartElementUtil.getPartElement(system, holderIWipRepositories));
}
for (Subsystem subsystem : subsystems) {
partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories));
for (WipSubsystem subsystem : subsystems) {
partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
}
// find in system structure
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findLatestByMnemonic(mnemonic);
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findLatestByMnemonic(mnemonic);
List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatestByMnemonic(mnemonic);
List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatestByMnemonic(mnemonic);
for (Discipline discipline : disciplines) {
for (WipDiscipline discipline : disciplines) {
partElements.add(PartElementUtil.getPartElement(discipline));
}
for (DeviceType deviceType : deviceTypes) {
partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories));
for (WipDeviceType deviceType : deviceTypes) {
partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
}
LOGGER.log(Level.FINE, "findPartsByMnemonic, mnemonic: {0}", mnemonic);
......@@ -167,49 +171,49 @@ public class PartControllerV0 {
try {
pattern = Pattern.compile(mnemonic);
} catch (PatternSyntaxException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
logService.logException(LOGGER, Level.WARNING, e);
}
// find in system structure
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findLatest();
List<System> systems = holderIRepositories.getSystemRepository().findLatest();
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findLatest();
List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatest();
List<WipSystem> systems = holderIWipRepositories.systemRepository().findLatest();
List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findLatest();
for (SystemGroup systemGroup : systemGroups) {
for (WipSystemGroup systemGroup : systemGroups) {
String sub = systemGroup.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(systemGroup));
}
}
for (System system : systems) {
for (WipSystem system : systems) {
String sub = system.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(system, holderIRepositories));
partElements.add(PartElementUtil.getPartElement(system, holderIWipRepositories));
}
}
for (Subsystem subsystem : subsystems) {
for (WipSubsystem subsystem : subsystems) {
String sub = subsystem.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories));
partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
}
}
// find in device structure
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findLatest();
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findLatest();
List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatest();
List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatest();
for (Discipline discipline : disciplines) {
for (WipDiscipline discipline : disciplines) {
String sub = discipline.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(discipline));
}
}
for (DeviceType deviceType : deviceTypes) {
for (WipDeviceType deviceType : deviceTypes) {
String sub = deviceType.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories));
partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
}
}
......@@ -239,57 +243,57 @@ public class PartControllerV0 {
try {
pattern = Pattern.compile(mnemonicPath);
} catch (PatternSyntaxException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
logService.logException(LOGGER, Level.WARNING, e);
}
// find in system structure
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findLatest();
List<System> systems = holderIRepositories.getSystemRepository().findLatest();
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findLatest();
List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatest();
List<WipSystem> systems = holderIWipRepositories.systemRepository().findLatest();
List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findLatest();
for (SystemGroup systemGroup : systemGroups) {
for (WipSystemGroup systemGroup : systemGroups) {
String sub = systemGroup.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(systemGroup));
}
}
for (System system : systems) {
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
for (WipSystem system : systems) {
WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
String sub = NamingConventionUtil.mnemonicPath2String(systemGroup.getName(), system.getName());
String sub = system.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(system, holderIRepositories));
partElements.add(PartElementUtil.getPartElement(system, holderIWipRepositories));
}
}
for (Subsystem subsystem : subsystems) {
System system = holderIRepositories.getSystemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
for (WipSubsystem subsystem : subsystems) {
WipSystem system = holderIWipRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
String sub = NamingConventionUtil.mnemonicPath2String(systemGroup.getMnemonic(), system.getMnemonic(), subsystem.getMnemonic());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories));
partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
}
}
// find in device structure
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findLatest();
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findLatest();
List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatest();
List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatest();
for (Discipline discipline : disciplines) {
for (WipDiscipline discipline : disciplines) {
String sub = discipline.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(discipline));
}
}
for (DeviceType deviceType : deviceTypes) {
DeviceGroup deviceGroup = holderIRepositories.getDeviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
for (WipDeviceType deviceType : deviceTypes) {
WipDeviceGroup deviceGroup = holderIWipRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
WipDiscipline discipline = holderIWipRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
String sub = NamingConventionUtil.mnemonicPath2String(discipline.getMnemonic(), deviceType.getMnemonic());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories));
partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
}
}
......
/*
* Copyright (C) 2021 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.rest.filter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.exception.handler.GlobalControllerExceptionHandler;
import org.openepics.names.rest.beans.response.Response;
import org.openepics.names.service.LogService;
import org.openepics.names.service.security.JwtTokenService;
import org.openepics.names.service.security.JwtUserDetailsService;
import org.openepics.names.service.security.dto.UserDetails;
import org.openepics.names.service.security.util.EncryptUtil;
import org.openepics.names.service.security.util.SecurityTextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.fusionauth.jwt.JWTExpiredException;
/**
* Purpose of class to intercept rest calls and handle cookies and tokens in uniformed manner.
*
* @author <a href="mailto:imre.toth@ess.eu">Imre Toth</a>
*/
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
private static final Logger LOGGER = Logger.getLogger(JwtRequestFilter.class.getName());
private final JwtUserDetailsService jwtUserDetailsService;
private final JwtTokenService jwtTokenService;
private final EncryptUtil encryptUtil;
private final GlobalControllerExceptionHandler globalControllerExceptionHandler;
private final LogService logService;
@Autowired
public JwtRequestFilter(
JwtUserDetailsService jwtUserDetailsService,
JwtTokenService jwtTokenService,
EncryptUtil encryptUtil,
GlobalControllerExceptionHandler globalControllerExceptionHandler,
LogService logService) {
this.jwtUserDetailsService = jwtUserDetailsService;
this.jwtTokenService = jwtTokenService;
this.encryptUtil = encryptUtil;
this.globalControllerExceptionHandler = globalControllerExceptionHandler;
this.logService = logService;
}
private static class TokenInfo {
private String userName;
private String rbacToken;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getRbacToken() {
return rbacToken;
}
public void setRbacToken(String rbacToken) {
this.rbacToken = rbacToken;
}
}
private TokenInfo extractTokenInfo(String jwtToken) {
TokenInfo result = new TokenInfo();
try {
result.setUserName(jwtTokenService.getUsernameFromToken(jwtToken));
result.setRbacToken(encryptUtil.decrypt(jwtTokenService.getRBACTokenFromToken(jwtToken)));
} catch (JWTExpiredException e) {
// not log as it may be considerable amount of exceptions
// otherwise message: JWT Token has expired
logService.logException(LOGGER, Level.WARNING, e, "JWT Token has expired");
return null;
} catch (Exception e) {
logService.logException(LOGGER, Level.WARNING, e, "Unable to get info from JWT Token");
return null;
}
return result;
}
@Override
protected void doFilterInternal(
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain)
throws ServletException, IOException {
final String requestTokenHeader = httpServletRequest.getHeader("Authorization");
String jwtToken = null;
TokenInfo tokenInfo = null;
try {
// JWT Token is in the form "Bearer token". Remove Bearer word and get
// only the Token
if (requestTokenHeader != null) {
if (requestTokenHeader.startsWith(SecurityTextUtil.AUTHENTICATION_HEADER_PREFIX)) {
jwtToken = requestTokenHeader.substring(SecurityTextUtil.AUTHENTICATION_HEADER_PREFIX.length());
} else {
jwtToken = requestTokenHeader;
}
tokenInfo = extractTokenInfo(jwtToken);
} else {
Cookie cookie = WebUtils.getCookie(httpServletRequest, SecurityTextUtil.COOKIE_AUTH_HEADER);
if (cookie != null) {
String cookieValue = cookie.getValue();
if (StringUtils.isNotEmpty(cookieValue)) {
jwtToken = cookieValue;
tokenInfo = extractTokenInfo(cookieValue);
}
}
}
// Once we get the token validate it.
if (tokenInfo != null
&& tokenInfo.getRbacToken() != null
&& SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.jwtUserDetailsService.loadUserByToken(tokenInfo.getRbacToken());
// if token is valid configure Spring Security to manually set
// authentication
if (jwtTokenService.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
} catch (RuntimeException e) {
// MyObject is whatever the output of the below method
ResponseEntity<Response> objectResponseEntity = null;
try {
objectResponseEntity = globalControllerExceptionHandler.handleConflict(e, new ServletWebRequest(httpServletRequest));
// set the response object
httpServletResponse.setStatus(objectResponseEntity.getStatusCode().value());
httpServletResponse.setContentType("application/json");
// pass down the actual obj that exception handler normally send
ObjectMapper mapper = new ObjectMapper();
PrintWriter out = httpServletResponse.getWriter();
out.print(mapper.writeValueAsString(objectResponseEntity.getBody()));
out.flush();
return;
} catch (Exception ex) {
logService.logException(LOGGER, Level.WARNING, ex, "JWT Request filter processing error");
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
......@@ -156,8 +156,12 @@ public class RestLogFilter implements Filter {
}
}
private final ObjectMapper mapper;
@Autowired
private ObjectMapper mapper;
public RestLogFilter(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public void init(FilterConfig filterConfig) {}
......@@ -198,7 +202,7 @@ public class RestLogFilter implements Filter {
logLine.setStatusCode(resp.getStatus());
}
} finally {
if (restRequest) {
if (restRequest && LOGGER.isLoggable(Level.INFO)) {
LOGGER.log(Level.INFO, mapper.writeValueAsString(logLine));
}
}
......
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository;
import org.openepics.names.repository.model.AuditStructure;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.model.Discipline;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.StructureElementCommand;
import org.openepics.names.util.EssNamingConvention;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.StructureChoice;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.notification.NotificationUtil;
import org.openepics.names.util.notification.StructureElementNotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;
/**
* This class provides structures services for device group.
*
* @author Lars Johansson
*/
@Service
public class DeviceGroupService {
private static final Logger LOGGER = Logger.getLogger(DeviceGroupService.class.getName());
private final DeviceTypeService deviceTypeService;
private final IDisciplineRepository iDisciplineRepository;
private final IDeviceGroupRepository iDeviceGroupRepository;
private final IDeviceTypeRepository iDeviceTypeRepository;
private final IAuditStructureRepository iAuditStructureRepository;
private final DeviceGroupRepository deviceGroupRepository;
private final AuditStructureRepository auditStructureRepository;
@Autowired
public DeviceGroupService(
DeviceTypeService deviceTypeService,
IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository,
IAuditStructureRepository iAuditStructureRepository,
DeviceGroupRepository deviceGroupRepository,
AuditStructureRepository auditStructureRepository) {
this.deviceTypeService = deviceTypeService;
this.iDisciplineRepository = iDisciplineRepository;
this.iDeviceGroupRepository = iDeviceGroupRepository;
this.iDeviceTypeRepository = iDeviceTypeRepository;
this.iAuditStructureRepository = iAuditStructureRepository;
this.deviceGroupRepository = deviceGroupRepository;
this.auditStructureRepository = auditStructureRepository;
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// create structure
// create audit
// return
// structure element for created structure
// notification
UUID uuid = UUID.randomUUID();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// create structure
// create audit
Discipline discipline = iDisciplineRepository.findByUuid(structureElementCommand.getParent().toString());
DeviceGroup deviceGroup = new DeviceGroup(uuid, discipline.getId(),
mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
when, username, null);
deviceGroupRepository.createDeviceGroup(deviceGroup);
auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, deviceGroup));
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(deviceGroup, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DEVICEGROUP, StructureCommand.CREATE, null, deviceGroup, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// update structure
// create audit
// previous for notification
// return
// structure element for updated structure
// notification
String uuid = structureElementCommand.getUuid().toString();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// update structure
// create audit
DeviceGroup deviceGroup = iDeviceGroupRepository.findByUuid(uuid);
deviceGroup.setMnemonic(mnemonic);
deviceGroup.setMnemonicEquivalence(equivalenceClassRepresentative);
deviceGroup.setOrdering(structureElementCommand.getOrdering());
deviceGroup.setDescription(structureElementCommand.getDescription());
deviceGroupRepository.updateDeviceGroup(deviceGroup);
AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, deviceGroup);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICEGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
DeviceGroup previous = new DeviceGroup(previousAuditStructure);
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(deviceGroup, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DEVICEGROUP, StructureCommand.UPDATE, previous, deviceGroup, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// delete structure (update)
// create audit
// previous for notification
// additional
// delete sub structures (and related names)
// return
// structure element for deleted structure
// notification
String uuid = structureElementCommand.getUuid().toString();
// delete structure
// create audit
DeviceGroup deviceGroup = iDeviceGroupRepository.findByUuid(uuid);
deviceGroup.setDeleted(Boolean.TRUE);
deviceGroup.setAttributesProcessed(when, username, null);
deviceGroupRepository.updateDeviceGroup(deviceGroup);
AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, deviceGroup);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICEGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
DeviceGroup previous = new DeviceGroup(previousAuditStructure);
// additional
// will propagate to sub structures
List<StructureElementCommand> commands = Lists.newArrayList();
List<DeviceType> deviceTypes = iDeviceTypeRepository.findNotDeletedByParent(deviceGroup.getId());
for (DeviceType deviceType : deviceTypes) {
commands.add(new StructureElementCommand(deviceType.getUuid(), Type.DEVICETYPE, null, null, null, null));
}
for (StructureElementCommand command : commands) {
deviceTypeService.deleteStructure(command, when, username, holderStructures);
}
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.COMMAND, StructureCommand.DELETE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(deviceGroup, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DEVICEGROUP, StructureCommand.DELETE, previous, deviceGroup, holderStructures));
}
}
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import java.text.MessageFormat;
import java.util.Date;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.model.AuditStructure;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.StructureElementCommand;
import org.openepics.names.util.EssNamingConvention;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.StructureChoice;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.notification.NotificationUtil;
import org.openepics.names.util.notification.StructureElementNotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* This class provides structures services for device type.
*
* @author Lars Johansson
*/
@Service
public class DeviceTypeService {
private static final Logger LOGGER = Logger.getLogger(DeviceTypeService.class.getName());
private final NamesService namesService;
private final IDeviceGroupRepository iDeviceGroupRepository;
private final IDeviceTypeRepository iDeviceTypeRepository;
private final IAuditStructureRepository iAuditStructureRepository;
private final DeviceTypeRepository deviceTypeRepository;
private final AuditStructureRepository auditStructureRepository;
@Autowired
public DeviceTypeService(
NamesService namesService,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository,
IAuditStructureRepository iAuditStructureRepository,
DeviceTypeRepository deviceTypeRepository,
AuditStructureRepository auditStructureRepository) {
this.namesService = namesService;
this.iDeviceGroupRepository = iDeviceGroupRepository;
this.iDeviceTypeRepository = iDeviceTypeRepository;
this.iAuditStructureRepository = iAuditStructureRepository;
this.deviceTypeRepository = deviceTypeRepository;
this.auditStructureRepository = auditStructureRepository;
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// create structure
// create audit
// return
// structure element for created structure
// notification
UUID uuid = UUID.randomUUID();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// create structure
// create audit
DeviceGroup deviceGroup = iDeviceGroupRepository.findByUuid(structureElementCommand.getParent().toString());
DeviceType deviceType = new DeviceType(uuid, deviceGroup.getId(),
mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
when, username, null);
deviceTypeRepository.createDeviceType(deviceType);
auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, deviceType));
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(deviceType, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DEVICETYPE, StructureCommand.CREATE, null, deviceType, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// update structure
// create audit
// previous for notification
// additional
// update related names
// return
// structure element for updated structure
// notification
String uuid = structureElementCommand.getUuid().toString();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// update structure
// create audit
DeviceType deviceType = iDeviceTypeRepository.findByUuid(uuid);
deviceType.setMnemonic(mnemonic);
deviceType.setMnemonicEquivalence(equivalenceClassRepresentative);
deviceType.setOrdering(structureElementCommand.getOrdering());
deviceType.setDescription(structureElementCommand.getDescription());
deviceTypeRepository.updateDeviceType(deviceType);
AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, deviceType);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICETYPE.name().toLowerCase(), uuid, auditStructure.getAuditId());
DeviceType previous = new DeviceType(previousAuditStructure);
// additional
namesService.updateNames(previous, deviceType, username, holderStructures);
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(deviceType, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DEVICETYPE, StructureCommand.UPDATE, previous, deviceType, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// delete structure (update)
// create audit
// previous for notification
// additional
// delete related names
// return
// structure element for deleted structure
// notification
String uuid = structureElementCommand.getUuid().toString();
// delete structure
// create audit
DeviceType deviceType = iDeviceTypeRepository.findByUuid(uuid);
deviceType.setDeleted(Boolean.TRUE);
deviceType.setAttributesProcessed(when, username, null);
deviceTypeRepository.updateDeviceType(deviceType);
AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, deviceType);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICETYPE.name().toLowerCase(), uuid, auditStructure.getAuditId());
DeviceType previous = new DeviceType(previousAuditStructure);
// additional
namesService.deleteNames(deviceType, username, holderStructures);
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.COMMAND, StructureCommand.DELETE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(deviceType, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DEVICETYPE, StructureCommand.DELETE, previous, deviceType, holderStructures));
}
}
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDisciplineRepository;
import org.openepics.names.repository.model.AuditStructure;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.Discipline;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.DisciplineRepository;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.StructureElementCommand;
import org.openepics.names.util.EssNamingConvention;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.StructureChoice;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.notification.NotificationUtil;
import org.openepics.names.util.notification.StructureElementNotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;
/**
* This class provides structures services for discipline.
*
* @author Lars Johansson
*/
@Service
public class DisciplineService {
private static final Logger LOGGER = Logger.getLogger(DisciplineService.class.getName());
private final NamesService namesService;
private final DeviceGroupService deviceGroupService;
private final IDeviceGroupRepository iDeviceGroupRepository;
private final IDisciplineRepository iDisciplineRepository;
private final IAuditStructureRepository iAuditStructureRepository;
private final DisciplineRepository disciplineRepository;
private final AuditStructureRepository auditStructureRepository;
@Autowired
public DisciplineService(
NamesService namesService,
DeviceGroupService deviceGroupService,
IDeviceGroupRepository iDeviceGroupRepository,
IDisciplineRepository iDisciplineRepository,
IAuditStructureRepository iAuditStructureRepository,
DisciplineRepository disciplineRepository,
AuditStructureRepository auditStructureRepository) {
this.namesService = namesService;
this.deviceGroupService = deviceGroupService;
this.iDeviceGroupRepository = iDeviceGroupRepository;
this.iDisciplineRepository = iDisciplineRepository;
this.iAuditStructureRepository = iAuditStructureRepository;
this.disciplineRepository = disciplineRepository;
this.auditStructureRepository = auditStructureRepository;
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// create structure
// create audit
// return
// structure element for created structure
// notification
UUID uuid = UUID.randomUUID();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// create structure
// create audit
Discipline discipline = new Discipline(uuid,
mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
when, username, null);
disciplineRepository.createDiscipline(discipline);
auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, discipline));
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(discipline, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DISCIPLINE, StructureCommand.CREATE, null, discipline, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// update structure
// create audit
// previous for notification
// additional
// update related names
// return
// structure element for updated structure
// notification
String uuid = structureElementCommand.getUuid().toString();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// update structure
// create audit
Discipline discipline = iDisciplineRepository.findByUuid(uuid);
discipline.setMnemonic(mnemonic);
discipline.setMnemonicEquivalence(equivalenceClassRepresentative);
discipline.setOrdering(structureElementCommand.getOrdering());
discipline.setDescription(structureElementCommand.getDescription());
disciplineRepository.updateDiscipline(discipline);
AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, discipline);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DISCIPLINE.name().toLowerCase(), uuid, auditStructure.getAuditId());
Discipline previous = new Discipline(previousAuditStructure);
// additional
namesService.updateNames(previous, discipline, username, holderStructures);
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(discipline, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DISCIPLINE, StructureCommand.UPDATE, previous, discipline, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// delete structure (update)
// create audit
// previous for notification
// additional
// delete related names
// delete sub structures (and related names)
// return
// structure element for deleted structure
// notification
String uuid = structureElementCommand.getUuid().toString();
// delete structure
// create audit
Discipline discipline = iDisciplineRepository.findByUuid(uuid);
discipline.setDeleted(Boolean.TRUE);
discipline.setAttributesProcessed(when, username, null);
disciplineRepository.updateDiscipline(discipline);
AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, discipline);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DISCIPLINE.name().toLowerCase(), uuid, auditStructure.getAuditId());
Discipline previous = new Discipline(previousAuditStructure);
// additional
// will propagate to sub structures
namesService.deleteNames(discipline, username, holderStructures);
List<StructureElementCommand> commands = Lists.newArrayList();
List<DeviceGroup> deviceGroups = iDeviceGroupRepository.findNotDeletedByParent(discipline.getId());
for (DeviceGroup deviceGroup : deviceGroups) {
commands.add(new StructureElementCommand(deviceGroup.getUuid(), Type.DEVICEGROUP, null, null, null, null));
}
for (StructureElementCommand command : commands) {
deviceGroupService.deleteStructure(command, when, username, holderStructures);
}
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.COMMAND, StructureCommand.DELETE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(discipline, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.DISCIPLINE, StructureCommand.DELETE, previous, discipline, holderStructures));
}
}
......@@ -18,13 +18,19 @@
package org.openepics.names.service;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.exception.ServiceException;
import org.openepics.names.util.ValidateUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.google.common.collect.Lists;
/**
* Utility class to assist in handling of logs.
......@@ -34,23 +40,28 @@ import org.springframework.stereotype.Service;
@Service
public class LogService {
private static final String DELIMITER = " ### ";
/**
* Number of elements from stacktrace to log. Default is 10.
* Comma-separated list of strings that, if any of given strings is contained in stack trace element, the latter will be included in log
* (ref. whitelist). Otherwise, stack trace element is eligible to exclusion.
* If filter is empty, then stack trace element is included.
*/
@Value("${naming.logging.stacktrace.length:10}")
int loggingStackTraceLength;
@Value("${naming.logging.filter.includes}")
List<String> loggingFilterIncludes;
/**
* String to be contained in stacktrace (row) in order for stacktrace to be included in log.
* If filter is empty, then stacktrace is included.
* Comma-separated list of strings that, if any of given strings is contained in stack trace element, the latter will be excluded from log
* (ref. blacklist), Otherwise, stack trace element is eligible to inclusion.
* If filter is empty, then stack trace element is included.
*/
@Value("${naming.logging.filter.include:org.openepics.names}")
String loggingFilterInclude;
@Value("${naming.logging.filter.excludes}")
List<String> loggingFilterExcludes;
/**
* String to be contained in stacktrace (row) in order for stacktrace to be excluded from log.
* If filter is empty, then stacktrace is included.
* Maximum number of elements from stack trace to log.
* Negative value will log entire stack trace with no concern to filters for inclusion or exclusion.
*/
@Value("${naming.logging.filter.exclude:org.openepics.names.util.ExceptionUtil}")
String loggingFilterExclude;
@Value("${naming.logging.stacktrace.length}")
int loggingStackTraceLength;
/**
* Log service exception.
......@@ -60,81 +71,88 @@ public class LogService {
* @param e service exception
*/
public void logServiceException(Logger logger, Level level, ServiceException e) {
if (logger == null || level == null || e == null) {
logServiceException(logger, level, e, null);
}
/**
* Log service exception.
*
* @param logger logger
* @param level log level
* @param e service exception
* @param msg message (additional and optional)
*/
public void logServiceException(Logger logger, Level level, ServiceException e, String msg) {
if (ValidateUtil.isAnyNull(logger, level, e)) {
return;
}
String msg = !StringUtils.isEmpty(e.getMessage())
? e.getMessage()
String msgException = !StringUtils.isEmpty(msg)
? DELIMITER + msg
: "";
String message = !StringUtils.isEmpty(e.getMessage())
? DELIMITER + e.getMessage()
: "";
String details = !StringUtils.isEmpty(e.getDetails())
? " ### " + e.getDetails()
? DELIMITER + e.getDetails()
: "";
String field = !StringUtils.isEmpty(e.getField())
? " ### " + e.getField()
? DELIMITER + e.getField()
: "";
msg = msg + details + field;
logger.log(level, msg);
}
msgException = msgException + message + details + field;
/**
* Log stack trace elements.
*
* @param logger logger
* @param level log level
* @param e service exception
*/
public void logStackTraceElements(Logger logger, Level level, ServiceException e) {
logStackTraceElements(logger, level, e, loggingStackTraceLength, loggingFilterInclude, loggingFilterExclude);
logger.log(level, msgException);
logStackTraceElements(logger, level, e);
}
/**
* Log stack trace elements.
* Log exception.
*
* @param logger logger
* @param level log level
* @param e exception
*/
public void logStackTraceElements(Logger logger, Level level, Exception e) {
logStackTraceElements(logger, level, e, loggingStackTraceLength, loggingFilterInclude, loggingFilterExclude);
public void logException(Logger logger, Level level, Exception e) {
logException(logger, level, e, null);
}
/**
* Log stack trace elements.
* Log exception.
*
* @param logger logger
* @param level log level
* @param e service exception
* @param maxNumberOfLogs max number of logs
* @param filterInclude filter include
* @param filterExclude filter exclude
* @param e exception
* @param msg message (additional and optional)
*/
public void logStackTraceElements(Logger logger, Level level, ServiceException e, int maxNumberOfLogs, String filterInclude, String filterExclude) {
if (logger == null || level == null || e == null || maxNumberOfLogs <= 0) {
public void logException(Logger logger, Level level, Exception e, String msg) {
if (ValidateUtil.isAnyNull(logger, level, e)) {
return;
}
logStackTraceElements(logger, level, e.getStackTrace(), maxNumberOfLogs, filterInclude, filterExclude);
if (!StringUtils.isEmpty(msg) ) {
logger.log(level, msg);
}
logStackTraceElements(logger, level, e);
}
/**
* Log stack trace elements.
*
* @param logger logger
* @param level log level
* @param e exception
* @param maxNumberOfLogs max number of logs
* @param filterInclude filter include
* @param filterExclude filter exclude
*/
public void logStackTraceElements(Logger logger, Level level, Exception e, int maxNumberOfLogs, String filterInclude, String filterExclude) {
if (logger == null || level == null || e == null || maxNumberOfLogs <= 0) {
private void logStackTraceElements(Logger logger, Level level, Exception e) {
if (ValidateUtil.isAnyNull(logger, level, e)) {
return;
}
logStackTraceElements(logger, level, e.getStackTrace(), maxNumberOfLogs, filterInclude, filterExclude);
if (loggingStackTraceLength < 0) {
// log stack trace
logger.log(level, e.getMessage(), e);
} else {
// log filtered stack trace
logger.log(level, e::toString);
logStackTraceElements(logger, level, e.getStackTrace());
}
}
/**
......@@ -143,29 +161,49 @@ public class LogService {
* @param logger logger
* @param level log level
* @param stackTraceElements stack trace elements
* @param maxNumberOfLogs max number of logs
* @param filterInclude filter include
* @param filterExclude filter exclude
*/
private void logStackTraceElements(Logger logger, Level level, StackTraceElement[] stackTraceElements, int maxNumberOfLogs, String filterInclude, String filterExclude) {
if (logger == null || level == null || stackTraceElements == null || maxNumberOfLogs <= 0) {
private void logStackTraceElements(Logger logger, Level level, StackTraceElement[] stackTraceElements) {
if (ValidateUtil.isAnyNull(logger, level, stackTraceElements)) {
return;
}
String str;
String str = null;
int count = 0;
boolean emptyFilterInclude = loggingFilterIncludes.isEmpty();
boolean emptyFilterExclude = loggingFilterExcludes.isEmpty();
List<Pattern> patternsFilterInclude = compilePatterns(loggingFilterIncludes);
List<Pattern> patternsFilterExclude = compilePatterns(loggingFilterExcludes);
for (StackTraceElement stackTraceElement : stackTraceElements) {
str = stackTraceElement.toString();
if ((StringUtils.isEmpty(filterInclude) || str.contains(filterInclude))
&& !(!StringUtils.isEmpty(filterExclude) && str.contains(filterExclude))) {
if ((emptyFilterInclude || ValidateUtil.isAnyMatch(patternsFilterInclude, str))
&& !(!emptyFilterExclude && ValidateUtil.isAnyMatch(patternsFilterExclude, str))) {
count++;
logger.log(level, str);
if (count == maxNumberOfLogs) {
if (count == loggingStackTraceLength) {
break;
}
}
}
}
/**
* Compiles the given regular expressions into patterns.
* Note that null and empty values are disregarded.
*
* @param regex regular expressions
* @return list of patterns
*/
private List<Pattern> compilePatterns(List<String> regex) {
List<Pattern> patterns = Lists.newArrayList();
if (!CollectionUtils.isEmpty(regex)) {
for (String s : regex) {
if (!StringUtils.isEmpty(s)) {
patterns.add(Pattern.compile(s));
}
}
}
return patterns;
}
}
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
/**
* This class provides mail services.
*
* @author Lars Johansson
*/
@Service
public class MailService {
private static final Logger LOGGER = Logger.getLogger(MailService.class.getName());
private static final String NAMING_PREFIX = "[NT] ";
private static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
private static final String TEXT_HTML_CHARSET_UTF_8 = "text/html; charset=utf-8";
@Value("${naming.mail.notification}")
boolean namingMailNotification;
@Value("${naming.mail.from}")
String namingMailFrom;
private final JavaMailSender emailSender;
private final LogService logService;
@Autowired
public MailService(
JavaMailSender emailSender,
LogService logService) {
this.emailSender = emailSender;
this.logService = logService;
}
/**
* Send email.
*
* @param toEmailAddresses list of email addresses (to)
* @param ccEmailAddresses list of email addresses (cc)
* @param replyToEmailAddresses list of email addresses (reply-to)
* @param subject subject
* @param content content
* @param withAttachment if attachment is available (one or more)
* @param attachmentNames names of attachments
* @param attachments attachments
*/
public void sendEmail(String[] toEmailAddresses, String[] ccEmailAddresses, String[] replyToEmailAddresses,
String subject, String content,
boolean withAttachment, List<String> attachmentNames, List<InputStream> attachments) {
try {
// content
// check
// need to have
// to email address
// subject
// content
// handle
// to
// cc
// reply to
// from
// date
// subject
// content
// attachment
// send
if (toEmailAddresses == null || toEmailAddresses.length == 0) {
LOGGER.log(Level.WARNING, "To email addresses unavailable, can not send email");
return;
}
if (StringUtils.isEmpty(subject)) {
LOGGER.log(Level.WARNING, "Subject unavailable, can not send email");
return;
}
if (StringUtils.isEmpty(content)) {
LOGGER.log(Level.WARNING, "Content unavailable, can not send email");
return;
}
MimeMessage message = emailSender.createMimeMessage();
// to
// cc
// reply to
final List<Address> toRecipients = new ArrayList<>();
for (final String toEmailAddress : toEmailAddresses) {
if (StringUtils.isEmpty(toEmailAddress)) {
LOGGER.log(Level.FINE, "To email address can not be used");
continue;
}
toRecipients.add(new InternetAddress(toEmailAddress));
}
if (toRecipients.isEmpty()) {
LOGGER.log(Level.WARNING, "To email addresses unavailable, can not send email");
return;
}
message.setRecipients(Message.RecipientType.TO, toRecipients.toArray(new Address[0]));
final List<Address> ccRecipients = new ArrayList<>();
if (ccEmailAddresses != null) {
for (final String ccEmailAddress : ccEmailAddresses) {
if (StringUtils.isEmpty(ccEmailAddress)) {
LOGGER.log(Level.FINE, "Cc email address can not be used");
continue;
}
ccRecipients.add(new InternetAddress(ccEmailAddress));
}
}
if (!ccRecipients.isEmpty()) {
message.setRecipients(Message.RecipientType.CC, ccRecipients.toArray(new Address[0]));
}
final List<Address> replyToAddresses = new ArrayList<>();
if (replyToEmailAddresses != null) {
for (final String replyToEmailAddress : replyToEmailAddresses) {
if (StringUtils.isEmpty(replyToEmailAddress)) {
LOGGER.log(Level.FINE, "Reply to email address can not be used");
continue;
}
replyToAddresses.add(new InternetAddress(replyToEmailAddress));
}
}
if (!replyToAddresses.isEmpty()) {
message.setReplyTo(replyToAddresses.toArray(new Address[0]));
}
// from
// date
// subject
message.setSentDate(new Date());
message.setFrom(new InternetAddress(namingMailFrom));
message.setSubject(NAMING_PREFIX + subject);
// attachment
// content
if (withAttachment
&& attachmentNames != null && !attachmentNames.isEmpty()
&& attachments != null && !attachments.isEmpty()
&& attachmentNames.size() == attachments.size()) {
MimeMultipart multipart = new MimeMultipart();
MimeBodyPart messagePart = new MimeBodyPart();
messagePart.setContent(content, TEXT_HTML_CHARSET_UTF_8);
multipart.addBodyPart(messagePart);
for (int i = 0; i < attachments.size(); i++) {
MimeBodyPart attachmentPart = new MimeBodyPart();
DataSource dataSource = new ByteArrayDataSource(attachments.get(i), APPLICATION_OCTET_STREAM);
attachmentPart.setDataHandler(new DataHandler(dataSource));
attachmentPart.setFileName(attachmentNames.get(i));
multipart.addBodyPart(attachmentPart);
}
message.setContent(multipart);
} else {
message.setContent(content, TEXT_HTML_CHARSET_UTF_8);
}
if (namingMailNotification) {
LOGGER.log(Level.FINE, () -> MessageFormat.format("Sending email with subject {0}", subject));
emailSender.send(message);
} else {
LOGGER.log(Level.INFO, "Sending email disabled");
}
} catch (MessagingException | IOException e) {
logService.logException(LOGGER, Level.WARNING, e);
}
}
}
/*
* Copyright (C) 2024 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import org.openepics.names.repository.AuditNameRepository;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.repository.DisciplineRepository;
import org.openepics.names.repository.NameRepository;
import org.openepics.names.repository.SubsystemRepository;
import org.openepics.names.repository.SystemGroupRepository;
import org.openepics.names.repository.SystemRepository;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.util.HolderRepositories;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
/**
* This class provides metrics services.
*
* @author Lars Johansson
*/
@Service
public class MetricsService {
// note
// history - count of history entries (all)
// active - count of active entries
// deleted - count of deleted entries
private static final String[] METRICS_NAME = { "ce.naming.name.count", "Count of name entries"};
private static final String[] METRICS_STRUCTURE = { "ce.naming.structure.count", "Count of structure entries"};
private static final String TYPE = "type";
private static final String STATUS = "status";
private static final String[] STATUS_METRICS = {"history", "active", "deleted"};
private final HolderRepositories holderRepositories;
@Autowired
public MetricsService(
MeterRegistry meterRegistry,
NameRepository nameRepository,
SystemGroupRepository systemGroupRepository,
SystemRepository systemRepository,
SubsystemRepository subsystemRepository,
DisciplineRepository disciplineRepository,
DeviceGroupRepository deviceGroupRepository,
DeviceTypeRepository deviceTypeRepository,
AuditNameRepository auditNameRepository,
AuditStructureRepository auditStructureRepository) {
this.holderRepositories = new HolderRepositories(
nameRepository,
systemGroupRepository,
systemRepository,
subsystemRepository,
disciplineRepository,
deviceGroupRepository,
deviceTypeRepository,
auditNameRepository,
auditStructureRepository);
registerGaugeMetrics(meterRegistry);
}
private void registerGaugeMetrics(final MeterRegistry meterRegistry){
// see also report
// prepare metrics for names
// history
// active
// deleted
Gauge.builder(METRICS_NAME[0],
() -> holderRepositories.auditNameRepository().countAuditNames(null))
.description(METRICS_NAME[1])
.tag(STATUS, STATUS_METRICS[0])
.register(meterRegistry);
Gauge.builder(METRICS_NAME[0],
() -> holderRepositories.nameRepository().countNames(Boolean.FALSE, null, null, null, null, null, null, null, null))
.description(METRICS_NAME[1])
.tag(STATUS, STATUS_METRICS[1])
.register(meterRegistry);
Gauge.builder(METRICS_NAME[0],
() -> holderRepositories.nameRepository().countNames(Boolean.TRUE, null, null, null, null, null, null, null, null))
.description(METRICS_NAME[1])
.tag(STATUS, STATUS_METRICS[2])
.register(meterRegistry);
// prepare metrics for structures
// history
// active
// deleted
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEMGROUP, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SYSTEMGROUP.toString())
.tag(STATUS, STATUS_METRICS[0])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.systemGroupRepository().countSystemGroups(Boolean.FALSE, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SYSTEMGROUP.toString())
.tag(STATUS, STATUS_METRICS[1])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.systemGroupRepository().countSystemGroups(Boolean.TRUE, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SYSTEMGROUP.toString())
.tag(STATUS, STATUS_METRICS[2])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEM, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SYSTEM.toString())
.tag(STATUS, STATUS_METRICS[0])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.systemRepository().countSystems(Boolean.FALSE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SYSTEM.toString())
.tag(STATUS, STATUS_METRICS[1])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.systemRepository().countSystems(Boolean.TRUE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SYSTEM.toString())
.tag(STATUS, STATUS_METRICS[2])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.auditStructureRepository().countAuditStructures(Type.SUBSYSTEM, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SUBSYSTEM.toString())
.tag(STATUS, STATUS_METRICS[0])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.subsystemRepository().countSubsystems(Boolean.FALSE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SUBSYSTEM.toString())
.tag(STATUS, STATUS_METRICS[1])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.subsystemRepository().countSubsystems(Boolean.TRUE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.SUBSYSTEM.toString())
.tag(STATUS, STATUS_METRICS[2])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.auditStructureRepository().countAuditStructures(Type.DISCIPLINE, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DISCIPLINE.toString())
.tag(STATUS, STATUS_METRICS[0])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.disciplineRepository().countDisciplines(Boolean.FALSE, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DISCIPLINE.toString())
.tag(STATUS, STATUS_METRICS[1])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.disciplineRepository().countDisciplines(Boolean.TRUE, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DISCIPLINE.toString())
.tag(STATUS, STATUS_METRICS[2])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICEGROUP, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DEVICEGROUP.toString())
.tag(STATUS, STATUS_METRICS[0])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.deviceGroupRepository().countDeviceGroups(Boolean.FALSE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DEVICEGROUP.toString())
.tag(STATUS, STATUS_METRICS[1])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.deviceGroupRepository().countDeviceGroups(Boolean.TRUE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DEVICEGROUP.toString())
.tag(STATUS, STATUS_METRICS[2])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICETYPE, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DEVICETYPE.toString())
.tag(STATUS, STATUS_METRICS[0])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.deviceTypeRepository().countDeviceTypes(Boolean.FALSE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DEVICETYPE.toString())
.tag(STATUS, STATUS_METRICS[1])
.register(meterRegistry);
Gauge.builder(METRICS_STRUCTURE[0],
() -> holderRepositories.deviceTypeRepository().countDeviceTypes(Boolean.TRUE, null, null, null, null, null, null, null))
.description(METRICS_STRUCTURE[1])
.tag(TYPE, Type.DEVICETYPE.toString())
.tag(STATUS, STATUS_METRICS[2])
.register(meterRegistry);
}
}
......@@ -18,17 +18,16 @@
package org.openepics.names.service;
import java.util.Collections;
import java.util.Comparator;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.repository.DisciplineRepository;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IAuditNameRepository;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository;
......@@ -36,14 +35,20 @@ import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.AuditNameRepository;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.repository.DisciplineRepository;
import org.openepics.names.repository.NameRepository;
import org.openepics.names.repository.SubsystemRepository;
import org.openepics.names.repository.SystemGroupRepository;
import org.openepics.names.repository.SystemRepository;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.AuditName;
import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.model.Discipline;
import org.openepics.names.repository.model.Name;
import org.openepics.names.repository.model.Structure;
import org.openepics.names.repository.model.Subsystem;
import org.openepics.names.repository.model.System;
import org.openepics.names.repository.model.SystemGroup;
......@@ -53,15 +58,13 @@ import org.openepics.names.rest.beans.element.NameElement;
import org.openepics.names.rest.beans.element.NameElementCommand;
import org.openepics.names.rest.beans.response.ResponsePageNameElements;
import org.openepics.names.util.EssNamingConvention;
import org.openepics.names.util.ExceptionUtil;
import org.openepics.names.util.HolderIRepositories;
import org.openepics.names.util.HolderRepositories;
import org.openepics.names.util.HolderSystemDeviceStructure;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.NameElementUtil;
import org.openepics.names.util.NameUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.ValidateNameElementUtil;
import org.openepics.names.util.ValidateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
......@@ -77,25 +80,21 @@ import com.google.common.collect.Lists;
@Service
public class NamesService {
// HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return
//
// for each method
// document what values come from NameElement and what values come from persistence layer
// somehow provide this information to user
//
// note
// default
// active means valid not deleted
// obsolete values are not shown unless history is requested
// handling of system structure, device structure
// parent system structure uuid (system group, system, subsystem) - ability to find structure
// parent system structure uuid (system group, system, subsystem)
// parent device structure uuid (device type)
// namecommand
// cud - create update delete
private static final Logger LOGGER = Logger.getLogger(NamesService.class.getName());
private EssNamingConvention namingConvention;
private HolderIRepositories holderIRepositories;
private HolderRepositories holderRepositories;
// convenience, also part of holderRepositories
private NameRepository nameRepository;
private final EssNamingConvention namingConvention;
private final HolderIRepositories holderIRepositories;
private final HolderRepositories holderRepositories;
@Autowired
public NamesService(
......@@ -106,13 +105,17 @@ public class NamesService {
IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository,
IAuditNameRepository iAuditNameRepository,
IAuditStructureRepository iAuditStructureRepository,
NameRepository nameRepository,
SystemGroupRepository systemGroupRepository,
SystemRepository systemRepository,
SubsystemRepository subsystemRepository,
DisciplineRepository disciplineRepository,
DeviceGroupRepository deviceGroupRepository,
DeviceTypeRepository deviceTypeRepository) {
DeviceTypeRepository deviceTypeRepository,
AuditNameRepository auditNameRepository,
AuditStructureRepository auditStructureRepository) {
this.namingConvention = new EssNamingConvention();
this.holderIRepositories = new HolderIRepositories(
......@@ -122,7 +125,9 @@ public class NamesService {
iSubsystemRepository,
iDisciplineRepository,
iDeviceGroupRepository,
iDeviceTypeRepository);
iDeviceTypeRepository,
iAuditNameRepository,
iAuditStructureRepository);
this.holderRepositories = new HolderRepositories(
nameRepository,
systemGroupRepository,
......@@ -130,389 +135,296 @@ public class NamesService {
subsystemRepository,
disciplineRepository,
deviceGroupRepository,
deviceTypeRepository);
this.nameRepository = nameRepository;
deviceTypeRepository,
auditNameRepository,
auditStructureRepository);
}
@Transactional
public List<NameElement> createNames(List<NameElementCommand> nameElements) {
// validate
// outside of @Transactional
public List<NameElement> createNames(List<NameElementCommand> nameElementCommands, String username) {
// validation outside method
// transaction
// do
// for each name element
// create name, latest, with data
// add name element for created
// return
// name elements for created names
// for each name element
// create name
// handle name element for created name
// no notify
// return name elements for created names
LOGGER.log(Level.FINE, "createNames, nameElements.size: {0}", String.valueOf(nameElements != null ? nameElements.size() : "null"));
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date requested = new Date();
String requestedBy = TextUtil.TEST_WHO;
Date when = new Date();
final List<NameElement> createdNameElements = Lists.newArrayList();
for (NameElementCommand nameElement : nameElements) {
// create name within current transaction
createdNameElements.add(createName(nameElement, holder, requested, requestedBy));
for (NameElementCommand nameElementCommand : nameElementCommands) {
NameElement createdNameElement = createName(nameElementCommand, when, username, holderStructures);
createdNameElements.add(createdNameElement);
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_NAME, TextUtil.ELEMENT_IN, nameElementCommand));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_NAME, TextUtil.ELEMENT_OUT, createdNameElement));
}
}
LOGGER.log(Level.FINE, "createNames, createdNameElements.size: {0}", createdNameElements.size());
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Create names",
nameElementCommands.size(),
createdNameElements.size()));
return createdNameElements;
}
@Transactional(propagation = Propagation.MANDATORY)
public NameElement createName(NameElementCommand nameElementCommand, Date when, String username, HolderStructures holderStructures) {
return createName(nameElementCommand, when, username, holderStructures, null);
}
@Transactional(propagation = Propagation.MANDATORY)
public NameElement createName(NameElementCommand nameElement, HolderSystemDeviceStructure holder, Date requested, String requestedBy) {
public NameElement createName(NameElementCommand nameElementCommand, Date when, String username, HolderStructures holderStructures, Structure structure) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// find out
// find & prepare
// create name
// create audit
// return name element for created name
UUID uuid = UUID.randomUUID();
UUID parentSystemStructure = nameElementCommand.getParentSystemStructure();
UUID parentDeviceStructure = nameElementCommand.getParentDeviceStructure();
String index = nameElementCommand.getIndex();
String description = nameElementCommand.getDescription();
String comment = null;
// find & prepare
// system structure - system group, system, subsystem - one of the three expected to be non-null, other two expected to be null
// device structure - device type - may be null
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
System system = holderIRepositories.getSystemRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
DeviceType deviceType = null;
if (nameElement.getParentdevicestructure() != null) {
deviceType = holderIRepositories.getDeviceTypeRepository().findLatestByUuid(nameElement.getParentdevicestructure().toString());
SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findByUuid(parentSystemStructure.toString());
System system = holderIRepositories.systemRepository().findByUuid(parentSystemStructure.toString());
Subsystem subsystem = holderIRepositories.subsystemRepository().findByUuid(parentSystemStructure.toString());
DeviceType deviceType = null;
if (parentDeviceStructure != null) {
deviceType = holderIRepositories.deviceTypeRepository().findByUuid(parentDeviceStructure.toString());
}
String derivedName = null;
if (systemGroup != null) {
derivedName = NameUtil.getName(systemGroup, deviceType, nameElement.getIndex(), holder);
derivedName = NameUtil.getName(systemGroup, deviceType, index, holderStructures);
} else if (system != null) {
derivedName = NameUtil.getName(system, deviceType, nameElement.getIndex(), holder);
derivedName = NameUtil.getName(system, deviceType, index, holderStructures);
} else if (subsystem != null) {
derivedName = NameUtil.getName(subsystem, deviceType, nameElement.getIndex(), holder);
derivedName = NameUtil.getName(subsystem, deviceType, index, holderStructures);
}
// create
Name name = new Name(UUID.randomUUID(),
systemGroup != null ? systemGroup.getUuid() : null, system != null ? system.getUuid() : null, subsystem != null ? subsystem.getUuid() : null, nameElement.getParentdevicestructure(),
nameElement.getIndex(), derivedName, namingConvention.equivalenceClassRepresentative(derivedName),
nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
requested, requestedBy, nameElement.getComment());
nameRepository.createName(name);
// possibly validate that created
// approved, latest, not deleted, uuid
// add
return NameElementUtil.getNameElement(name);
// create name
// create audit
Name name = new Name(uuid,
systemGroup != null ? systemGroup.getId() : null,
system != null ? system.getId() : null,
subsystem != null ? subsystem.getId() : null,
deviceType != null ? deviceType.getId() : null,
index, derivedName, namingConvention.equivalenceClassRepresentative(derivedName), description,
Status.APPROVED, Boolean.FALSE,
when, username, comment);
holderRepositories.nameRepository().createName(name);
holderRepositories.auditNameRepository().createAuditName(new AuditName(TextUtil.CREATE, name));
return NameElementUtil.getNameElement(name, holderStructures, structure);
}
// ----------------------------------------------------------------------------------------------------
public ResponsePageNameElements readNames(Boolean deleted,
String uuid, String name, String nameequivalence, String systemstructure, String devicestructure, String index, String description,
String uuid, String name, String systemStructure, String deviceStructure, String index, String description, String who,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
return readNames(deleted,
uuid, name, nameequivalence, systemstructure, devicestructure, index, description,
uuid, name, systemStructure, deviceStructure, index, description, who,
Boolean.FALSE, orderBy, isAsc, offset, limit);
}
public ResponsePageNameElements readNames(Boolean deleted,
String uuid, String name, String nameequivalence, String systemstructure, String devicestructure, String index, String description,
String uuid, String name, String systemStructure, String deviceStructure, String index, String description, String who,
Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
LOGGER.log(Level.FINE, "readNames, deleted: {0}", deleted);
LOGGER.log(Level.FINE, "readNames, uuid: {0}", uuid);
LOGGER.log(Level.FINE, "readNames, name: {0}", name);
LOGGER.log(Level.FINE, "readNames, nameequivalence: {0}", nameequivalence);
LOGGER.log(Level.FINE, "readNames, systemstructure: {0}", systemstructure);
LOGGER.log(Level.FINE, "readNames, devicestructure: {0}", devicestructure);
LOGGER.log(Level.FINE, "readNames, index: {0}", index);
LOGGER.log(Level.FINE, "readNames, description: {0}", description);
LOGGER.log(Level.FINE, "readNames, includeHistory: {0}", includeHistory);
LOGGER.log(Level.FINE, "readNames, orderBy: {0}", orderBy);
LOGGER.log(Level.FINE, "readNames, isAsc: {0}", isAsc);
LOGGER.log(Level.FINE, "readNames, offset: {0}", offset);
LOGGER.log(Level.FINE, "readNames, limit: {0}", limit);
// validate input
// queryFields and queryValues
// uuid
// do
// read names
// return
// name elements for names
// validate input
ValidateNameElementUtil.validateNamesInputRead(
deleted,
uuid, name, nameequivalence, systemstructure, devicestructure, description,
includeHistory,
orderBy, isAsc,
offset, limit);
// do
List<Name> names = nameRepository.readNames(deleted, uuid, name, nameequivalence, systemstructure, devicestructure, index, description, includeHistory, orderBy, isAsc, offset, limit);
Long totalCount = nameRepository.countNames(deleted, uuid, name, nameequivalence, systemstructure, devicestructure, index, description, includeHistory);
final List<NameElement> nameElements = Lists.newArrayList();
for (Name namee : names) {
nameElements.add(NameElementUtil.getNameElement(namee));
// validation outside method
// read names
// return name elements for names
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "deleted", deleted));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "uuid", uuid));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "name", name));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "systemStructure", systemStructure));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "deviceStructure", deviceStructure));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "index", index));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "description", description));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "who", who));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "includeHistory", includeHistory));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "orderBy", orderBy));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "isAsc", isAsc));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "offset", offset));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "limit", limit));
}
ResponsePageNameElements response = new ResponsePageNameElements(nameElements, totalCount, nameElements.size(), offset, limit);
LOGGER.log(Level.FINE, "readNames, response: {0}", response);
return response;
}
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
public ResponsePageNameElements readNames(String name,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
// one name entry will give one name element
// history does not affect totalCount, sorting, pagination
List<NameElement> nameElements = null;
Long totalCount = null;
if (Boolean.TRUE.equals(includeHistory)) {
List<AuditName> auditNames = holderRepositories.auditNameRepository().readAuditNames(uuid, offset, limit);
totalCount = holderRepositories.auditNameRepository().countAuditNames(uuid);
LOGGER.log(Level.FINE, "readNames, name: {0}", name);
// validate input
// name or uuid
// to work with both uuid and name
// do
// name or uuid
// return
// name elements
// validate input
ValidateUtil.validateInputName(name);
// do
final List<NameElement> nameElements = Lists.newArrayList();
try {
UUID.fromString(name);
Name latestByUuid = holderIRepositories.getNameRepository().findLatestByUuid(name);
if (latestByUuid != null) {
nameElements.add(NameElementUtil.getNameElement(latestByUuid));
return new ResponsePageNameElements(nameElements, Long.valueOf(nameElements.size()), nameElements.size(), offset, limit);
}
} catch (IllegalArgumentException e) {
return readNames(false,
null, name, null, null, null, null, null,
orderBy, isAsc, offset, limit);
nameElements = NameElementUtil.getNameElementsForAuditNames(auditNames, holderStructures);
} else {
List<Name> names = holderRepositories.nameRepository().readNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who, orderBy, isAsc, offset, limit);
totalCount = holderRepositories.nameRepository().countNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who);
nameElements = NameElementUtil.getNameElements(names, holderStructures);
}
return new ResponsePageNameElements(nameElements, Long.valueOf(nameElements.size()), nameElements.size(), offset, limit);
ResponsePageNameElements response = new ResponsePageNameElements(nameElements, totalCount, nameElements.size(), offset, limit);
LOGGER.log(Level.FINE,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_RESPONSE,
TextUtil.READ_NAMES,
response.toString()));
return response;
}
public ResponsePageNameElements readNamesSystemStructure(String mnemonicpath,
public ResponsePageNameElements readNamesStructure(String uuid, Boolean deleted,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
// validation outside method
// read by structure uuid
// return name elements
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_STRUCTURE, "uuid", uuid));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_STRUCTURE, "deleted", deleted));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_STRUCTURE, "orderBy", orderBy));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_STRUCTURE, "isAsc", isAsc));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_STRUCTURE, "offset", offset));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_STRUCTURE, "limit", limit));
}
LOGGER.log(Level.FINE, "readNamesSystemStructure, mnemonicpath: {0}", mnemonicpath);
// validate input
// mnemonic path
// do
// mnemonic path
// return
// name elements
// validate input
ValidateUtil.validateInputMnemonicpath(mnemonicpath);
// there are different kinds of references to structure ids for names, directly and indirectly, both are included
// directly
// system group
// system
// subsystem
// device type
// indirectly
// system group through system
// system group through subsystem
// system through system
// discipline through device type
// device group through device type
// name does not refer directly to discipline, device group
// e.g. name Sys-Sub:Dis-Dev-001
// - name refers to Sub that in turn refers to Sys. Sub is directly referenced. Sys is indirectly referenced.
// - name refers to Dev that in turn refers to Dis. Dev is directly referenced. Dis is indirectly referenced.
// go through all structures and see if / where uuid is found
// system structure and device structure
// uuid in 0 or 1 of kind of structure
// negligible impact on performance for going through different structures
// order by
// order by may be not fully ordered when there are multiple read operations
// pagination
// separate pagination when result may be from multiple read operations
// read operations should not contain pagination in such cases
// one uuid at a time
// no need to make sure that names are not found and added twice or more to result
// otherwise ordering and pagination will be messy
// consider multiplicity if search for both system structure uuid and device structure uuid
List<Name> names = Lists.newArrayList();
// directly
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP, uuid, deleted, orderBy, isAsc));
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEM, uuid, deleted, orderBy, isAsc));
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_DEVICETYPE, uuid, deleted, orderBy, isAsc));
// indirectly
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP_THROUGH_SYSTEM, uuid, deleted, orderBy, isAsc));
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP_THROUGH_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEM_THROUGH_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_DISCIPLINE_THROUGH_DEVICETYPE, uuid, deleted, orderBy, isAsc));
names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_DEVICEGROUP_THROUGH_DEVICETYPE, uuid, deleted, orderBy, isAsc));
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// pagination
Long totalCount = Long.valueOf(names.size());
final List<NameElement> nameElements = paginate(NameElementUtil.getNameElements(names, holderStructures), offset, limit);
ResponsePageNameElements response = new ResponsePageNameElements(nameElements, totalCount, nameElements.size(), offset, limit);
// do
return readNames(false,
null, null, null, mnemonicpath, null, null, null,
orderBy, isAsc, offset, limit);
LOGGER.log(Level.FINE,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_RESPONSE,
TextUtil.READ_NAMES_STRUCTURE,
response.toString()));
return response;
}
public ResponsePageNameElements readNamesDeviceStructure(String mnemonicpath,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
LOGGER.log(Level.FINE, "readNamesDeviceStructure, mnemonicpath: {0}", mnemonicpath);
private List<NameElement> paginate(List<NameElement> list, Integer offset, Integer limit) {
// intended as pagination when list may contain result from multiple read operations
// read operations should not contain pagination in such cases
if (offset == null || limit == null) {
return list;
}
// validate input
// mnemonic path
// do
// mnemonic path
// return
// name elements
List<NameElement> listPagination = Lists.newArrayList();
int offsetItems = offset * limit;
int availableItems = list.size() - offsetItems;
if (availableItems > 0) {
for (int i = offsetItems; i < Math.min(offsetItems+availableItems, offsetItems+limit); i++) {
listPagination.add(list.get(i));
}
}
return listPagination;
}
// validate input
ValidateUtil.validateInputMnemonicpath(mnemonicpath);
public ResponsePageNameElements readNamesHistory(String uuid, Integer offset, Integer limit) {
// validation outside method
// read history for name
// return name elements for names
// do
return readNames(false,
null, null, null, null,mnemonicpath, null, null,
orderBy, isAsc, offset, limit);
}
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "uuid", uuid));
public ResponsePageNameElements readNamesHistory(String uuid,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
LOGGER.log(Level.FINE, "readNamesHistory, uuid: {0}", uuid);
// note
// HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return
// validate input
// uuid
// do
// read history for name
// return
// name elements for names
// validate input
ValidateUtil.validateInputUuid(uuid);
// do
ResponsePageNameElements response = readNames(null,
return readNames(null,
uuid, null, null, null, null, null, null,
Boolean.TRUE, orderBy, isAsc, offset, limit);
Collections.sort(response.getList(), new Comparator<NameElement>() {
@Override
public int compare(NameElement e1, NameElement e2) {
return e1.getWhen().compareTo(e2.getWhen());
}
});
return response;
Boolean.TRUE, FieldName.WHEN, Boolean.TRUE, offset, limit);
}
// ----------------------------------------------------------------------------------------------------
public String equivalenceName(String name) {
LOGGER.log(Level.FINE, "equivalenceName, name: {0}", name);
// validate input
// do
// exists
// validate input
ValidateUtil.validateInputName(name);
// do
return namingConvention.equivalenceClassRepresentative(name);
}
public Boolean existsName(String name) {
LOGGER.log(Level.FINE, "existsName, name: {0}", name);
// validation outside method
// read exists
// validate input
// do
// exists
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.EXISTS_NAME, "name", name));
// validate input
ValidateUtil.validateInputName(name);
// do
List<Name> names = nameRepository.readNames(false,
null, name, null, null, null, null, null);
List<Name> names = holderRepositories.nameRepository().readNames(false,
null, name, null, null, null, null, null, null);
return !names.isEmpty();
}
public Boolean isLegacyName(String name) {
LOGGER.log(Level.FINE, "isLegacyName, name: {0}", name);
// validate input
// do
// exists
// validate input
ValidateUtil.validateInputName(name);
// do
List<Name> names = nameRepository.readNames(false,
null, name, null, null, null, null, null);
ExceptionUtil.validateConditionDataNotFoundException(names != null && names.size() == 1, "name not found", name, null);
Name toBeChecked = names.get(0);
// system structure
if (toBeChecked.getSystemgroupUuid() != null) {
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemgroupUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(systemGroup != null,
TextUtil.SYSTEMGROUP_IS_NOT_AVAILABLE, name, null);
if (systemGroup.isDeleted()) {
return Boolean.TRUE;
}
} else if (toBeChecked.getSystemUuid() != null) {
org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(system != null,
TextUtil.SYSTEM_IS_NOT_AVAILABLE, name, null);
if (system.isDeleted()) {
return Boolean.TRUE;
}
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(systemGroup != null,
TextUtil.SYSTEMGROUP_IS_NOT_AVAILABLE, name, null);
if (systemGroup.isDeleted()) {
return Boolean.TRUE;
}
} else if (toBeChecked.getSubsystemUuid() != null) {
Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSubsystemUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(subsystem != null,
TextUtil.SUBSYSTEM_IS_NOT_AVAILABLE, name, null);
if (subsystem.isDeleted()) {
return Boolean.TRUE;
}
org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(subsystem.getParentUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(system != null,
TextUtil.SYSTEM_IS_NOT_AVAILABLE, name, null);
if (system.isDeleted()) {
return Boolean.TRUE;
}
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(systemGroup != null,
TextUtil.SYSTEMGROUP_IS_NOT_AVAILABLE, name, null);
if (systemGroup.isDeleted()) {
return Boolean.TRUE;
}
}
// device structure
if (toBeChecked.getDevicetypeUuid() != null) {
DeviceType deviceType = holderIRepositories.getDeviceTypeRepository().findLatestNotDeletedByUuid(toBeChecked.getDevicetypeUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(deviceType != null,
TextUtil.DEVICETYPE_IS_NOT_AVAILABLE, name, null);
if (deviceType.isDeleted()) {
return Boolean.TRUE;
}
DeviceGroup deviceGroup = holderIRepositories.getDeviceGroupRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(deviceGroup != null,
TextUtil.DEVICEGROUP_IS_NOT_AVAILABLE, name, null);
if (deviceGroup.isDeleted()) {
return Boolean.TRUE;
}
Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString());
ExceptionUtil.validateConditionDataNotAvailableException(discipline != null,
TextUtil.DEVICEGROUP_IS_NOT_AVAILABLE, name, null);
if (discipline.isDeleted()) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
public Boolean isValidToCreateName(String name) {
LOGGER.log(Level.FINE, "isValidToCreateName, name: {0}", name);
// validation outside method
// validate data - not exists
// validate input
// validate data
// not exists
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_VALID_TO_CREATE_NAME, "name", name));
// validate input
ValidateUtil.validateInputName(name);
// initiate holder of containers for system and device structure content, for performance reasons
// holder of valid content for system and device structures
// note false to not include deleted entries
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories, false);
HolderStructures holderStructures = new HolderStructures(holderIRepositories, false);
// validate data
ValidateNameElementUtil.validateNameDataCreate(name, namingConvention, holderRepositories, holder);
ValidateNameElementUtil.validateNameDataCreate(name, namingConvention, holderRepositories, holderStructures);
return Boolean.TRUE;
}
......@@ -520,247 +432,354 @@ public class NamesService {
// ----------------------------------------------------------------------------------------------------
public void validateNamesCreate(NameElementCommand nameElement) {
validateNamesCreate(nameElement, new HolderSystemDeviceStructure(holderIRepositories));
validateNamesCreate(nameElement, new HolderStructures(holderIRepositories));
}
public void validateNamesCreate(NameElementCommand nameElement, HolderSystemDeviceStructure holder) {
// validate authority
// elsewhere
// naming user & admin
// validate input
// name element
// validate input itself
// validate data
// name element
// validate towards repository
// validate input
ValidateNameElementUtil.validateNameElementInputCreate(nameElement);
public void validateNamesCreate(NameElementCommand nameElement, HolderStructures holderStructures) {
// validate name element
// input vs given task
// data vs given task
// validate data
ValidateNameElementUtil.validateNameElementDataCreate(nameElement, namingConvention, holderIRepositories, nameRepository, holder);
ValidateNameElementUtil.validateNameElementInputCreate(nameElement);
ValidateNameElementUtil.validateNameElementDataCreate(nameElement, namingConvention,
holderIRepositories, holderRepositories, holderStructures);
}
public void validateNamesCreate(List<NameElementCommand> nameElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (NameElementCommand nameElement : nameElements) {
validateNamesCreate(nameElement, holder);
validateNamesCreate(nameElement, holderStructures);
}
}
public void validateNamesUpdate(NameElementCommand nameElement) {
validateNamesUpdate(nameElement, new HolderSystemDeviceStructure(holderIRepositories));
validateNamesUpdate(nameElement, new HolderStructures(holderIRepositories));
}
public void validateNamesUpdate(NameElementCommand nameElement, HolderSystemDeviceStructure holder) {
// validate authority
// elsewhere
// naming user & admin
// validate input
// name element
// validate input itself
// validate data
// name element
// validate towards repository
// validate input
ValidateNameElementUtil.validateNameElementInputUpdate(nameElement);
public void validateNamesUpdate(NameElementCommand nameElement, HolderStructures holderStructures) {
// validate name element
// input vs given task
// data vs given task
// validate data
ValidateNameElementUtil.validateNameElementDataUpdate(nameElement, namingConvention, holderIRepositories, nameRepository, holder);
ValidateNameElementUtil.validateNameElementInputUpdate(nameElement);
ValidateNameElementUtil.validateNameElementDataUpdate(nameElement, namingConvention,
holderIRepositories, holderRepositories, holderStructures);
}
public void validateNamesUpdate(List<NameElementCommand> nameElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (NameElementCommand nameElement : nameElements) {
validateNamesUpdate(nameElement, holder);
validateNamesUpdate(nameElement, holderStructures);
}
}
public void validateNamesDelete(NameElementCommand nameElement) {
validateNamesDelete(nameElement, new HolderSystemDeviceStructure(holderIRepositories));
validateNamesDelete(nameElement, new HolderStructures(holderIRepositories));
}
public void validateNamesDelete(NameElementCommand nameElement, HolderSystemDeviceStructure holder) {
// validate authority
// elsewhere
// naming user & admin
// validate input
// uuid
// validate data
// retrieve name (uuid, latest, not deleted)
// validate input
ValidateNameElementUtil.validateNameElementInputDelete(nameElement);
public void validateNamesDelete(NameElementCommand nameElement, HolderStructures holderStructures) {
// validate name element
// input vs given task
// data vs given task
// validate data
ValidateNameElementUtil.validateNameElementDataDelete(nameElement, namingConvention, holderIRepositories, nameRepository, holder);
ValidateNameElementUtil.validateNameElementInputDelete(nameElement);
ValidateNameElementUtil.validateNameElementDataDelete(nameElement, namingConvention,
holderIRepositories, holderRepositories, holderStructures);
}
public void validateNamesDelete(List<NameElementCommand> nameElements) {
// validate authority
// elsewhere
// naming user & admin
// validate input
// name element
// validate input itself
// validate data
// name element
// validate towards repository
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (NameElementCommand nameElement : nameElements) {
validateNamesDelete(nameElement, holder);
validateNamesDelete(nameElement, holderStructures);
}
}
// ----------------------------------------------------------------------------------------------------
@Transactional
public List<NameElement> updateNames(List<NameElementCommand> nameElements) {
// validate
// outside of @Transactional
public List<NameElement> updateNames(List<NameElementCommand> nameElementCommands, String username) {
// validation outside method
// transaction
// do
// for each name element
// update name to not latest
// insert name to latest, not deleted, with data
// read
// return
// name elements for updated names
LOGGER.log(Level.FINE, "updateNames, nameElements.size: {0}", String.valueOf(nameElements != null ? nameElements.size() : "null"));
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date requested = new Date();
String requestedBy = TextUtil.TEST_WHO;
// for each name element
// find & prepare
// update name
// create audit
// handle name element for updated name
// no notify
// return name elements for updated names
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
Date when = new Date();
final List<NameElement> updatedNameElements = Lists.newArrayList();
for (NameElementCommand nameElement : nameElements) {
// update not latest, not deleted
// create latest, not deleted
for (NameElementCommand nameElementCommand : nameElementCommands) {
UUID uuid = nameElementCommand.getUuid();
UUID parentSystemStructure = nameElementCommand.getParentSystemStructure();
UUID parentDeviceStructure = nameElementCommand.getParentDeviceStructure();
String index = nameElementCommand.getIndex();
String description = nameElementCommand.getDescription();
String comment = null;
// find & prepare
// system structure - system group, system, subsystem - one of the three expected to be non-null, other two expected to be null
// device structure - device type - may be null
SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findByUuid(parentSystemStructure.toString());
System system = holderIRepositories.systemRepository().findByUuid(parentSystemStructure.toString());
Subsystem subsystem = holderIRepositories.subsystemRepository().findByUuid(parentSystemStructure.toString());
DeviceType deviceType = null;
if (parentDeviceStructure != null) {
deviceType = holderIRepositories.deviceTypeRepository().findByUuid(parentDeviceStructure.toString());
}
String derivedName = null;
if (systemGroup != null) {
derivedName = NameUtil.getName(systemGroup, deviceType, index, holderStructures);
} else if (system != null) {
derivedName = NameUtil.getName(system, deviceType, index, holderStructures);
} else if (subsystem != null) {
derivedName = NameUtil.getName(subsystem, deviceType, index, holderStructures);
}
Name name = holderIRepositories.getNameRepository().findLatestByUuid(nameElement.getUuid().toString());
// update name
// create audit
Name name = holderIRepositories.nameRepository().findByUuid(uuid.toString());
if (name == null) {
continue;
}
// skip if name element has same content as name
// proceed without fail
if (NameElementUtil.hasSameContent(nameElement, name, holderIRepositories, holder)) {
if (NameElementUtil.hasSameContent(nameElementCommand, name, holderIRepositories, holderStructures)) {
continue;
}
// update
name.setLatest(Boolean.FALSE);
nameRepository.updateName(name);
// find out system group, system, subsystem
// one of the three expected to be non-null, other two expected to be null
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
System system = holderIRepositories.getSystemRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
DeviceType deviceType = null;
if (nameElement.getParentdevicestructure() != null) {
deviceType = holderIRepositories.getDeviceTypeRepository().findLatestByUuid(nameElement.getParentdevicestructure().toString());
}
String derivedName = null;
if (systemGroup != null) {
derivedName = NameUtil.getName(systemGroup, deviceType, nameElement.getIndex(), holder);
} else if (system != null) {
derivedName = NameUtil.getName(system, deviceType, nameElement.getIndex(), holder);
} else if (subsystem != null) {
derivedName = NameUtil.getName(subsystem, deviceType, nameElement.getIndex(), holder);
name.setInstanceIndex(index);
name.setConventionName(derivedName);
name.setConventionNameEquivalence(namingConvention.equivalenceClassRepresentative(derivedName));
name.setDescription(description);
name.setAttributesRequested(when, username, comment);
holderRepositories.nameRepository().updateName(name);
holderRepositories.auditNameRepository().createAuditName(new AuditName(TextUtil.UPDATE, name));
NameElement updatedNameElement = NameElementUtil.getNameElement(name, holderStructures);
updatedNameElements.add(updatedNameElement);
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_NAME, TextUtil.ELEMENT_IN, nameElementCommand));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_NAME, TextUtil.ELEMENT_OUT, updatedNameElement));
}
}
// create
name = new Name(nameElement.getUuid(),
systemGroup != null ? systemGroup.getUuid() : null, system != null ? system.getUuid() : null, subsystem != null ? subsystem.getUuid() : null, nameElement.getParentdevicestructure(),
nameElement.getIndex(), derivedName, namingConvention.equivalenceClassRepresentative(derivedName),
nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
requested, requestedBy, nameElement.getComment());
nameRepository.createName(name);
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Update names",
nameElementCommands.size(),
updatedNameElements.size()));
return updatedNameElements;
}
// possibly validate that updated
@Transactional(propagation = Propagation.MANDATORY)
public List<NameElement> updateNames(Structure previousStructure, Structure structure, String username, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// find out names referenced by structure - not for device group
// prepare name element commands
// update names
// return name elements for updated names
List<NameElement> updatedNameElements = Lists.newArrayList();
if (previousStructure != null
&& structure != null
&& !StringUtils.equals(structure.getMnemonic(), previousStructure.getMnemonic())
&& !StringUtils.isEmpty(structure.getMnemonic())) {
List<Name> names = null;
List<NameElementCommand> nameElements = Lists.newArrayList();
UUID parentSystemStructureUuid = null;
UUID parentDeviceStructureUuid = null;
if (previousStructure instanceof SystemGroup && structure instanceof SystemGroup) {
names = holderIRepositories.nameRepository().findNotDeletedBySystemGroupUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getSystemGroupUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
} else if (previousStructure instanceof System && structure instanceof System) {
names = holderIRepositories.nameRepository().findNotDeletedBySystemUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getSystemUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
names = holderIRepositories.nameRepository().findNotDeletedBySystemUuidThroughSubsystem(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getSubsystemUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
} else if (previousStructure instanceof Subsystem && structure instanceof Subsystem) {
names = holderIRepositories.nameRepository().findNotDeletedBySubsystemUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getSubsystemUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
} else if (previousStructure instanceof Discipline && structure instanceof Discipline) {
names = holderIRepositories.nameRepository().findNotDeletedByDisciplineUuidThroughDeviceType(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getParentSystemStructureUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
} else if (previousStructure instanceof DeviceType && structure instanceof DeviceType) {
names = holderIRepositories.nameRepository().findNotDeletedByDeviceTypeUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getParentSystemStructureUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
}
// add
updatedNameElements.add(NameElementUtil.getNameElement(name));
// update names
updatedNameElements = updateNames(nameElements, username);
}
LOGGER.log(Level.FINE, "updateNames, updatedNameElements.size: {0}", updatedNameElements.size());
return updatedNameElements;
}
// ----------------------------------------------------------------------------------------------------
@Transactional
public List<NameElement> deleteNames(List<NameElementCommand> nameElements) {
// validate
// outside of @Transactional
public List<NameElement> deleteNames(List<NameElementCommand> nameElementCommands, String username) {
// validation outside method
// transaction
// do
// update name to not latest
// insert name to latest, deleted
// read
// return
// name element for deleted name
// for each name element
// delete name (update)
// create audit
// handle name element for deleted name (updated)
// no notify
// return name elements for deleted names
LOGGER.log(Level.FINE, "deleteNames, nameElements.size: {0}", String.valueOf(nameElements != null ? nameElements.size() : "null"));
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date requested = new Date();
String requestedBy = TextUtil.TEST_WHO;
Date when = new Date();
final List<NameElement> deletedNameElements = Lists.newArrayList();
for (NameElementCommand nameElement : nameElements) {
Name name = holderIRepositories.getNameRepository().findLatestByUuid(nameElement.getUuid().toString());
for (NameElementCommand nameElementCommand : nameElementCommands) {
UUID uuid = nameElementCommand.getUuid();
String comment = null;
// update
// create audit
Name name = holderIRepositories.nameRepository().findByUuid(uuid.toString());
if (name == null) {
continue;
}
name.setDeleted(Boolean.TRUE);
name.setAttributesRequested(when, username, comment);
holderRepositories.nameRepository().updateName(name);
holderRepositories.auditNameRepository().createAuditName(new AuditName(TextUtil.DELETE, name));
name.setLatest(Boolean.FALSE);
nameRepository.updateName(name);
// find out system group, system, subsystem
// one of the three expected to be non-null, other two expected to be null
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
System system = holderIRepositories.getSystemRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestByUuid(nameElement.getParentsystemstructure().toString());
DeviceType deviceType = null;
if (nameElement.getParentdevicestructure() != null) {
deviceType = holderIRepositories.getDeviceTypeRepository().findLatestByUuid(nameElement.getParentdevicestructure().toString());
}
NameElement deletedNameElement = NameElementUtil.getNameElement(name, holderStructures);
deletedNameElements.add(deletedNameElement);
String derivedName = null;
if (systemGroup != null) {
derivedName = NameUtil.getName(systemGroup, deviceType, nameElement.getIndex(), holder);
} else if (system != null) {
derivedName = NameUtil.getName(system, deviceType, nameElement.getIndex(), holder);
} else if (subsystem != null) {
derivedName = NameUtil.getName(subsystem, deviceType, nameElement.getIndex(), holder);
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_NAME, TextUtil.ELEMENT_IN, nameElementCommand));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_NAME, TextUtil.ELEMENT_OUT, deletedNameElement));
}
}
name = new Name(nameElement.getUuid(),
systemGroup != null ? systemGroup.getUuid() : null, system != null ? system.getUuid() : null, subsystem != null ? subsystem.getUuid() : null, nameElement.getParentdevicestructure(),
nameElement.getIndex(), derivedName, namingConvention.equivalenceClassRepresentative(derivedName),
nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
requested, requestedBy, nameElement.getComment());
nameRepository.createName(name);
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Delete names",
nameElementCommands.size(),
deletedNameElements.size()));
return deletedNameElements;
}
// possibly validate that deleted
@Transactional(propagation = Propagation.MANDATORY)
public List<NameElement> deleteNames(Structure structure, String username, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// find out names referenced by structure
// prepare name element commands
// delete names (update)
// no notify
// return name elements for deleted names (updated)
List<NameElement> deletedNameElements = Lists.newArrayList();
if (structure != null) {
List<Name> names = null;
List<NameElementCommand> nameElements = Lists.newArrayList();
UUID parentSystemStructureUuid = null;
UUID parentDeviceStructureUuid = null;
if (structure instanceof SystemGroup) {
names = holderIRepositories.nameRepository().findNotDeletedBySystemGroupUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getSystemGroupUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
} else if (structure instanceof System) {
names = holderIRepositories.nameRepository().findNotDeletedBySystemUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getSystemUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
} else if (structure instanceof Subsystem) {
names = holderIRepositories.nameRepository().findNotDeletedBySubsystemUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getSubsystemUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
} else if (structure instanceof DeviceType) {
names = holderIRepositories.nameRepository().findNotDeletedByDeviceTypeUuid(structure.getUuid().toString());
for (Name name : names) {
parentSystemStructureUuid = NameElementUtil.getParentSystemStructureUuid(name, holderStructures);
parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
nameElements.add(
new NameElementCommand(
name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.getInstanceIndex(), name.getDescription()));
}
}
// add
deletedNameElements.add(NameElementUtil.getNameElement(name));
// delete names
deletedNameElements = deleteNames(nameElements, username);
}
LOGGER.log(Level.FINE, "deleteNames, deletedNameElements.size: {0}", deletedNameElements.size());
return deletedNameElements;
}
......
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.compress.utils.Lists;
import org.openepics.names.util.NameCommand;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.ValidateUtil;
import org.openepics.names.util.notification.NotificationName;
import org.openepics.names.util.notification.NotificationStructure;
import org.openepics.names.util.notification.NotificationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
/**
* This class provides notification services.
*
* @author Lars Johansson
*/
@Service
public class NotificationService {
private static final Logger LOGGER = Logger.getLogger(NotificationService.class.getName());
private static final String NOTIFY_NAMES_CREATED_UPDATED_DELETED =
"Notify names, # created: {0}, # updated: {1}, # deleted: {2}";
private static final String NOTIFY_STRUCTURES_CREATED_UPDATED_DELETED =
"Notify structures, # created: {0}, # updated: {1}, # deleted: {2}";
private static final String CHANGES_NOTIFICATION_NAMES = "[Changes for names]";
private static final String CHANGES_NOTIFICATION_STRUCTURES = "[Changes for structures]";
private static final String ADD_FOOTER = "addfooter";
private static final String BACKEND_URL = "backendurl";
@Value("${naming.mail.administrator}")
List<String> namingMailAdministrator;
@Value("${naming.mail.notification.names}")
List<String> namingMailNotificationNames;
@Value("${naming.mail.notification.structures}")
List<String> namingMailNotificationStructures;
@Value("${naming.swagger.url}")
String namingSwaggerUrl;
private final MailService mailService;
@Autowired
public NotificationService(
MailService mailService) {
this.mailService = mailService;
}
/**
* Send notifications for names to administrators and affected users by email.
*
* @param notifications list of name notifications
* @param nameCommand name command
*/
public void notifyNames(List<NotificationName> notifications, NameCommand nameCommand) {
if (NameCommand.CREATE.equals(nameCommand)) {
notifyNames(notifications, null, null);
} else if (NameCommand.UPDATE.equals(nameCommand)) {
notifyNames(null, notifications, null);
} else if (NameCommand.DELETE.equals(nameCommand)) {
notifyNames(null, null, notifications);
}
}
/**
* Send notifications for names to administrators and affected users by email.
*
* @param created list of notifications for created names
* @param updated list of notifications for updated names
* @param deleted list of notifications for deleted names
*/
public void notifyNames(
List<NotificationName> created,
List<NotificationName> updated,
List<NotificationName> deleted) {
NotificationUtil.sortByNewName(created);
NotificationUtil.sortByNewName(updated);
NotificationUtil.sortByNewName(deleted);
int numberCreated = getListSize(created);
int numberUpdated = getListSize(updated);
int numberDeleted = getListSize(deleted);
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
NOTIFY_NAMES_CREATED_UPDATED_DELETED,
numberCreated,
numberUpdated,
numberDeleted));
if (ValidateUtil.areAllZero(numberCreated, numberUpdated, numberDeleted)) {
return;
}
// email content
final Context ctx = new Context();
ctx.setVariable("numberCreated", numberCreated);
ctx.setVariable("numberUpdated", numberUpdated);
ctx.setVariable("numberDeleted", numberDeleted);
ctx.setVariable("created", created);
ctx.setVariable("updated", updated);
ctx.setVariable("deleted", deleted);
ctx.setVariable(ADD_FOOTER, true);
ctx.setVariable(BACKEND_URL, namingSwaggerUrl);
TemplateEngine engine = generateTemplateEngine();
// email addresses for notification
// administrators
// set of users - about changes for names
List<String> toEmailAddresses = Lists.newArrayList();
if (!namingMailAdministrator.isEmpty()) {
toEmailAddresses.addAll(namingMailAdministrator);
}
if (!namingMailNotificationNames.isEmpty()) {
toEmailAddresses.addAll(namingMailNotificationNames);
}
// send notification
String[] ccEmailAddresses = null;
String[] replyToEmailAddresses = null;
String subject = CHANGES_NOTIFICATION_NAMES + " - " + namingSwaggerUrl;
mailService.sendEmail(toEmailAddresses.toArray(new String[0]), ccEmailAddresses, replyToEmailAddresses,
subject, engine.process("templates/notification_names.html", ctx), false, null, null);
}
/**
* Send notifications for structures to administrators and affected users by email.
*
* @param notifications list of structure notifications
* @param structureCommand structure command
*/
public void notifyStructures(List<NotificationStructure> notifications, StructureCommand structureCommand) {
if (StructureCommand.CREATE.equals(structureCommand)) {
notifyStructures(notifications, null, null);
} else if (StructureCommand.UPDATE.equals(structureCommand)) {
notifyStructures(null, notifications, null);
} else if (StructureCommand.DELETE.equals(structureCommand)) {
notifyStructures(null, null, notifications);
}
}
/**
* Send notifications for structures to administrators and affected users by email.
*
* @param created list of notifications for created structures
* @param updated list of notifications for updated structures
* @param deleted list of notifications for deleted structures
*/
public void notifyStructures(
List<NotificationStructure> created,
List<NotificationStructure> updated,
List<NotificationStructure> deleted) {
NotificationUtil.sortByNewMnemonicpath(created);
NotificationUtil.sortByNewMnemonicpath(updated);
NotificationUtil.sortByNewMnemonicpath(deleted);
int numberCreated = getListSize(created);
int numberUpdated = getListSize(updated);
int numberDeleted = getListSize(deleted);
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
NOTIFY_STRUCTURES_CREATED_UPDATED_DELETED,
numberCreated,
numberUpdated,
numberDeleted));
if (ValidateUtil.areAllZero(numberCreated, numberUpdated, numberDeleted)) {
return;
}
// email content
final Context ctx = new Context();
ctx.setVariable("numberCreated", numberCreated);
ctx.setVariable("numberUpdated", numberUpdated);
ctx.setVariable("numberDeleted", numberDeleted);
ctx.setVariable("created", created);
ctx.setVariable("updated", updated);
ctx.setVariable("deleted", deleted);
ctx.setVariable(ADD_FOOTER, true);
ctx.setVariable(BACKEND_URL, namingSwaggerUrl);
TemplateEngine engine = generateTemplateEngine();
// email addresses for notification
// administrators
// set of users - about changes for structures
List<String> toEmailAddresses = Lists.newArrayList();
if (!namingMailAdministrator.isEmpty()) {
toEmailAddresses.addAll(namingMailAdministrator);
}
if (!namingMailNotificationStructures.isEmpty()) {
toEmailAddresses.addAll(namingMailNotificationStructures);
}
// send notification
String[] ccEmailAddresses = null;
String[] replyToEmailAddresses = null;
String subject = CHANGES_NOTIFICATION_STRUCTURES + " - " + namingSwaggerUrl;
mailService.sendEmail(toEmailAddresses.toArray(new String[0]), ccEmailAddresses, replyToEmailAddresses,
subject, engine.process("templates/notification_structures.html", ctx), false, null, null);
}
/**
* Return list size, zero if empty list.
*
* @param list list
* @return list size
*/
private int getListSize(List<?> list) {
return list != null ? list.size() : 0;
}
/**
* Generates the Thymeleaf template engine
*
* @return generate template engine
*/
private TemplateEngine generateTemplateEngine() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCacheable(false);
templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
TemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver);
return engine;
}
}
......@@ -18,18 +18,15 @@
package org.openepics.names.service;
import java.util.Collections;
import java.util.Comparator;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.repository.DisciplineRepository;
import org.openepics.names.repository.IAuditNameRepository;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository;
......@@ -37,10 +34,16 @@ import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.AuditNameRepository;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.repository.DisciplineRepository;
import org.openepics.names.repository.NameRepository;
import org.openepics.names.repository.SubsystemRepository;
import org.openepics.names.repository.SystemGroupRepository;
import org.openepics.names.repository.SystemRepository;
import org.openepics.names.repository.model.AuditStructure;
import org.openepics.names.repository.model.DeviceGroup;
import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.model.Discipline;
......@@ -48,22 +51,22 @@ import org.openepics.names.repository.model.Subsystem;
import org.openepics.names.repository.model.System;
import org.openepics.names.repository.model.SystemGroup;
import org.openepics.names.rest.beans.FieldStructure;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.NameElement;
import org.openepics.names.rest.beans.element.NameElementCommand;
import org.openepics.names.rest.beans.element.StructureElement;
import org.openepics.names.rest.beans.element.StructureElementCommand;
import org.openepics.names.rest.beans.response.ResponsePageStructureElements;
import org.openepics.names.util.EssNamingConvention;
import org.openepics.names.util.HolderIRepositories;
import org.openepics.names.util.HolderRepositories;
import org.openepics.names.util.HolderSystemDeviceStructure;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.StructureChoice;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.Utilities;
import org.openepics.names.util.ValidateStructureElementUtil;
import org.openepics.names.util.StructureElementUtil.StructureChoice;
import org.openepics.names.util.ValidateUtil;
import org.openepics.names.util.notification.NotificationStructure;
import org.openepics.names.util.notification.StructureElementNotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -78,29 +81,39 @@ import com.google.common.collect.Lists;
@Service
public class StructuresService {
// HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return
// for each method
// document what values come from StructureElement and what values come from persistence layer
// somehow provide this information to user
// latest
// automatically not show structures that do not come into play
// = automatically exclude (approved and not latest)
// otherwise refer to history
// note
// default
// active means valid not deleted
// obsolete values are not shown unless history is requested
// sorting
// sorting not applicable when multiple repositories are queried in same method
// structurecommand
// cud - create update delete
private static final Logger LOGGER = Logger.getLogger(StructuresService.class.getName());
private static final String SYSTEM_STRUCTURE_ONLY = "System structure only";
protected static final String SYSTEM_STRUCTURE_ONLY = "System structure only";
private EssNamingConvention namingConvention;
private HolderIRepositories holderIRepositories;
private HolderRepositories holderRepositories;
private NamesService namesService;
private final EssNamingConvention namingConvention;
private final NotificationService notificationService;
private final SystemGroupService systemGroupService;
private final SystemService systemService;
private final SubsystemService subsystemService;
private final DisciplineService disciplineService;
private final DeviceGroupService deviceGroupService;
private final DeviceTypeService deviceTypeService;
private final HolderIRepositories holderIRepositories;
private final HolderRepositories holderRepositories;
@Autowired
public StructuresService(
NotificationService notificationService,
SystemGroupService systemGroupService,
SystemService systemService,
SubsystemService subsystemService,
DisciplineService disciplineService,
DeviceGroupService deviceGroupService,
DeviceTypeService deviceTypeService,
INameRepository iNameRepository,
ISystemGroupRepository iSystemGroupRepository,
ISystemRepository iSystemRepository,
......@@ -108,6 +121,8 @@ public class StructuresService {
IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository,
IAuditNameRepository iAuditNameRepository,
IAuditStructureRepository iAuditStructureRepository,
NameRepository nameRepository,
SystemGroupRepository systemGroupRepository,
SystemRepository systemRepository,
......@@ -115,9 +130,17 @@ public class StructuresService {
DisciplineRepository disciplineRepository,
DeviceGroupRepository deviceGroupRepository,
DeviceTypeRepository deviceTypeRepository,
NamesService namesService) {
AuditNameRepository auditNameRepository,
AuditStructureRepository auditStructureRepository) {
this.namingConvention = new EssNamingConvention();
this.notificationService = notificationService;
this.systemGroupService = systemGroupService;
this.systemService = systemService;
this.subsystemService = subsystemService;
this.disciplineService = disciplineService;
this.deviceGroupService = deviceGroupService;
this.deviceTypeService = deviceTypeService;
this.holderIRepositories = new HolderIRepositories(
iNameRepository,
iSystemGroupRepository,
......@@ -125,7 +148,9 @@ public class StructuresService {
iSubsystemRepository,
iDisciplineRepository,
iDeviceGroupRepository,
iDeviceTypeRepository);
iDeviceTypeRepository,
iAuditNameRepository,
iAuditStructureRepository);
this.holderRepositories = new HolderRepositories(
nameRepository,
systemGroupRepository,
......@@ -133,575 +158,320 @@ public class StructuresService {
subsystemRepository,
disciplineRepository,
deviceGroupRepository,
deviceTypeRepository);
this.namesService = namesService;
deviceTypeRepository,
auditNameRepository,
auditStructureRepository);
}
@Transactional
public List<StructureElement> createStructures(List<StructureElementCommand> structureElements) {
// validate
// outside of @Transactional
public List<StructureElement> createStructures(List<StructureElementCommand> structureElements, String username) {
// validation outside method
// transaction
// do
// for each structure element
// create structure to pending, not latest, not deleted, with data
// add structure element for created
// return
// structure elements for created structures
LOGGER.log(Level.FINE, "createStructures, structureElements.size: {0}", String.valueOf(structureElements != null ? structureElements.size() : "null"));
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date requested = new Date();
String requestedBy = TextUtil.TEST_WHO;
// for each structure element command
// create structure
// handle
// notification
// structure element for created structure
// notify
// return structure elements for created structures
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
Date when = new Date();
List<NotificationStructure> notifications = Lists.newArrayList();
final List<StructureElement> createdStructureElements = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
// note
// namingConvention.equivalenceClassRepresentative return null for null input
UUID uuid = UUID.randomUUID();
String name = structureElement.getName();
String mnemonic = structureElement.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
String description = structureElement.getDescription();
String requestedComment = structureElement.getComment();
if (Type.SYSTEMGROUP.equals(structureElement.getType())) {
// note rules for mnemonic for system group
// create
SystemGroup systemGroup = new SystemGroup(uuid,
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getSystemGroupRepository().createSystemGroup(systemGroup);
// possibly validate that created
// add
createdStructureElements.add(StructureElementUtil.getStructureElementRequested(systemGroup, holder));
} else if (Type.SYSTEM.equals(structureElement.getType())) {
// create
System system = new System(uuid, structureElement.getParent(),
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getSystemRepository().createSystem(system);
// possibly validate that created
// add
createdStructureElements.add(StructureElementUtil.getStructureElementRequested(system, holder));
} else if (Type.SUBSYSTEM.equals(structureElement.getType())) {
// create
Subsystem subsystem = new Subsystem(uuid, structureElement.getParent(),
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getSubsystemRepository().createSubsystem(subsystem);
// possibly validate that created
// add
createdStructureElements.add(StructureElementUtil.getStructureElementRequested(subsystem, holder));
} else if (Type.DISCIPLINE.equals(structureElement.getType())) {
// create
Discipline discipline = new Discipline(uuid,
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getDisciplineRepository().createDiscipline(discipline);
// possibly validate that created
// add
createdStructureElements.add(StructureElementUtil.getStructureElementRequested(discipline, holder));
} else if (Type.DEVICEGROUP.equals(structureElement.getType())) {
// note rules for mnemonic for device group
// create
DeviceGroup deviceGroup = new DeviceGroup(uuid, structureElement.getParent(),
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getDeviceGroupRepository().createDeviceGroup(deviceGroup);
// possibly validate that created
// add
createdStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceGroup, holder));
} else if (Type.DEVICETYPE.equals(structureElement.getType())) {
// create
DeviceType deviceType = new DeviceType(uuid, structureElement.getParent(),
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getDeviceTypeRepository().createDeviceType(deviceType);
// possibly validate that created
// add
createdStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceType, holder));
Type type = structureElement.getType();
StructureElementNotification structureElementNotification = null;
if (Type.SYSTEMGROUP.equals(type)) {
structureElementNotification = systemGroupService.createStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.SYSTEM.equals(type)) {
structureElementNotification = systemService.createStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.SUBSYSTEM.equals(type)) {
structureElementNotification = subsystemService.createStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.DISCIPLINE.equals(type)) {
structureElementNotification = disciplineService.createStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.DEVICEGROUP.equals(type)) {
structureElementNotification = deviceGroupService.createStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.DEVICETYPE.equals(type)) {
structureElementNotification = deviceTypeService.createStructure(structureElement, when, username, namingConvention, holderStructures);
} else {
continue;
}
Utilities.addToCollection(notifications, structureElementNotification.notificationStructure());
Utilities.addToCollection(createdStructureElements, structureElementNotification.structureElement());
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, "type", type));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.ELEMENT_IN, structureElement));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.ELEMENT_OUT, structureElementNotification.structureElement()));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.NOTIFICATION, structureElementNotification.notificationStructure()));
}
}
LOGGER.log(Level.FINE, "createStructures, createdStructureElements.size: {0}", createdStructureElements.size());
// notify
notificationService.notifyStructures(notifications, StructureCommand.CREATE);
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Create structures",
structureElements.size(),
createdStructureElements.size()));
return createdStructureElements;
}
// ----------------------------------------------------------------------------------------------------
public ResponsePageStructureElements readStructures(Type type, Status[] statuses, Boolean deleted,
String uuid, String parentUuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
public ResponsePageStructureElements readStructures(Type type, Boolean deleted,
String uuid, String parent, String mnemonic, String mnemonicPath, String description, String who,
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
return readStructures(type, statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
return readStructures(type, deleted,
uuid, parent, mnemonic, mnemonicPath, description, who,
Boolean.FALSE, orderBy, isAsc, offset, limit, StructureChoice.STRUCTURE);
}
public ResponsePageStructureElements readStructures(Type type, Status[] statuses, Boolean deleted,
String uuid, String parentUuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
public ResponsePageStructureElements readStructures(Type type, Boolean deleted,
String uuid, String parent, String mnemonic, String mnemonicPath, String description, String who,
Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit,
StructureChoice structureChoice) {
LOGGER.log(Level.FINE, "readStructures, type: {0}", type);
LOGGER.log(Level.FINE, "readStructures, statuses.length: {0}", String.valueOf(statuses != null ? statuses.length : "null"));
LOGGER.log(Level.FINE, "readStructures, deleted: {0}", deleted);
LOGGER.log(Level.FINE, "readStructures, uuid: {0}", uuid);
LOGGER.log(Level.FINE, "readStructures, parentUuid: {0}", parentUuid);
LOGGER.log(Level.FINE, "readStructures, name: {0}", name);
LOGGER.log(Level.FINE, "readStructures, mnemonic: {0}", mnemonic);
LOGGER.log(Level.FINE, "readStructures, mnemonicequivalence: {0}", mnemonicequivalence);
LOGGER.log(Level.FINE, "readStructures, mnemonicpath: {0}", mnemonicpath);
LOGGER.log(Level.FINE, "readStructures, description: {0}", description);
LOGGER.log(Level.FINE, "readStructures, includeHistory: {0}", includeHistory);
LOGGER.log(Level.FINE, "readStructures, orderBy: {0}", orderBy);
LOGGER.log(Level.FINE, "readStructures, isAsc: {0}", isAsc);
LOGGER.log(Level.FINE, "readStructures, offset: {0}", offset);
LOGGER.log(Level.FINE, "readStructures, limit: {0}", limit);
LOGGER.log(Level.FINE, "readStructures, structureChoice: {0}", structureChoice);
if (statuses != null && statuses.length > 0) {
for (Status status : statuses) {
LOGGER.log(Level.FINE, "readStructures, status: {0}", status);
}
// validation outside method
// read structures
// return structure elements for structures
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "type", type));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "deleted", deleted));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "uuid", uuid));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "parent", parent));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "mnemonic", mnemonic));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "mnemonicPath", mnemonicPath));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "description", description));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "who", who));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "includeHistory", includeHistory));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "orderBy", orderBy));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "isAsc", isAsc));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "offset", offset));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "limit", limit));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "structureChoice", structureChoice));
}
// validate input
// type
// queryFields and queryValues
// uuid
// do
// read structures
// return
// structure elements for structures
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// validate input
ValidateStructureElementUtil.validateStructuresInputRead(type, statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory, orderBy, isAsc, offset, limit);
List<StructureElement> structureElements = Lists.newArrayList();
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// systemgroup and discipline do not have parent uuid
// order by works if type is available
// pagination after queries since type is not required
// do
final List<StructureElement> structureElements = Lists.newArrayList();
Long totalCount = null;
if (Type.SYSTEMGROUP.equals(type)) {
// system group has no parent uuid
List<SystemGroup> systemGroups = null;
if (StringUtils.isEmpty(parentUuid)) {
systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(statuses, deleted,
uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory, orderBy, isAsc, offset, limit);
totalCount = holderRepositories.getSystemGroupRepository().countSystemGroups(statuses, deleted,
uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory);
if (StringUtils.isEmpty(parent) && (Type.SYSTEMGROUP.equals(type) || type == null)) {
if (Boolean.TRUE.equals(includeHistory)) {
List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
} else {
systemGroups = Lists.newArrayList();
totalCount = 0L;
List<SystemGroup> systemGroups = holderRepositories.systemGroupRepository().readSystemGroups(deleted, uuid, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForSystemGroups(systemGroups, holderStructures, structureChoice));
}
LOGGER.log(Level.FINE, "readStructures, systemGroups.size: {0}", systemGroups.size());
structureElements.addAll(StructureElementUtil.getStructureElementsForSystemGroups(systemGroups, holder, structureChoice));
} else if (Type.SYSTEM.equals(type)) {
List<System> systems = holderRepositories.getSystemRepository().readSystems(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory, orderBy, isAsc, offset, limit);
totalCount = holderRepositories.getSystemRepository().countSystems(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory);
LOGGER.log(Level.FINE, "readStructures, systems.size: {0}", systems.size());
structureElements.addAll(StructureElementUtil.getStructureElementsForSystems(systems, holder, structureChoice));
} else if (Type.SUBSYSTEM.equals(type)) {
List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory, orderBy, isAsc, offset, limit);
totalCount = holderRepositories.getSubsystemRepository().countSubsystems(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory);
LOGGER.log(Level.FINE, "readStructures, subsystems.size: {0}", subsystems.size());
structureElements.addAll(StructureElementUtil.getStructureElementsForSubsystems(subsystems, holder, structureChoice));
} else if (Type.DISCIPLINE.equals(type)) {
// discipline has no parent uuid
List<Discipline> disciplines = null;
if (StringUtils.isEmpty(parentUuid)) {
disciplines = holderRepositories.getDisciplineRepository().readDisciplines(statuses, deleted,
uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory, orderBy, isAsc, offset, limit);
totalCount = holderRepositories.getDisciplineRepository().countDisciplines(statuses, deleted,
uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory);
}
if (Type.SYSTEM.equals(type) || type == null) {
if (Boolean.TRUE.equals(includeHistory)) {
List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
} else {
disciplines = Lists.newArrayList();
totalCount = 0L;
List<System> systems = holderRepositories.systemRepository().readSystems(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForSystems(systems, holderStructures, structureChoice));
}
LOGGER.log(Level.FINE, "readStructures, disciplines.size: {0}", disciplines.size());
structureElements.addAll(StructureElementUtil.getStructureElementsForDisciplines(disciplines, holder, structureChoice));
} else if (Type.DEVICEGROUP.equals(type)) {
List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory, orderBy, isAsc, offset, limit);
totalCount = holderRepositories.getDeviceGroupRepository().countDeviceGroups(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory);
LOGGER.log(Level.FINE, "readStructures, deviceGroups.size: {0}", deviceGroups.size());
structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceGroups(deviceGroups, holder, structureChoice));
} else if (Type.DEVICETYPE.equals(type)) {
List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory, orderBy, isAsc, offset, limit);
totalCount = holderRepositories.getDeviceTypeRepository().countDeviceTypes(statuses, deleted,
uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
includeHistory);
LOGGER.log(Level.FINE, "readStructures, deviceTypes.size: {0}", deviceTypes.size());
structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceTypes(deviceTypes, holder, structureChoice));
}
ResponsePageStructureElements response = new ResponsePageStructureElements(structureElements, totalCount, structureElements.size(), offset, limit);
LOGGER.log(Level.FINE, "readStructures, response: {0}", response);
return response;
}
public ResponsePageStructureElements readStructuresChildren(String uuid, Type type,
Status[] statuses, Boolean deleted, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
// validate input
// type, uuid
// do
// read structure latest by uuid for type
// return
// structure elements for structures
LOGGER.log(Level.FINE, "readStructuresChildren, uuid: {0}", uuid);
LOGGER.log(Level.FINE, "readStructuresChildren, type: {0}", type);
// validate input
ValidateUtil.validateInputUuid(uuid);
boolean type_systemGroup = type != null && Type.SYSTEMGROUP.equals(type);
boolean type_system = type != null && Type.SYSTEM.equals(type);
boolean type_subsystem = type != null && Type.SUBSYSTEM.equals(type);
boolean type_discipline = type != null && Type.DISCIPLINE.equals(type);
boolean type_deviceGroup = type != null && Type.DEVICEGROUP.equals(type);
boolean type_deviceType = type != null && Type.DEVICETYPE.equals(type);
boolean type_either = type_systemGroup || type_system || type_subsystem || type_discipline || type_deviceGroup || type_deviceType;
// do
final List<StructureElement> structureElements = Lists.newArrayList();
ResponsePageStructureElements response = null;
if (type_either) {
if (type_systemGroup) {
response = readStructures(Type.SYSTEM, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
} else if (type_system) {
response = readStructures(Type.SUBSYSTEM, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
} else if (type_discipline) {
response = readStructures(Type.DEVICEGROUP, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
} else if (type_deviceGroup) {
response = readStructures(Type.DEVICETYPE, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
if (Type.SUBSYSTEM.equals(type) || type == null) {
if (Boolean.TRUE.equals(includeHistory)) {
List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
} else {
// no children in structures for subsystem and device type
response = new ResponsePageStructureElements(structureElements, Long.valueOf(structureElements.size()), structureElements.size(), offset, limit);
List<Subsystem> subsystems = holderRepositories.subsystemRepository().readSubsystems(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForSubsystems(subsystems, holderStructures, structureChoice));
}
} else {
// go through all structures and see if / where uuid is found
// uuid in 0 or 1 of structures
ResponsePageStructureElements responseSystemGroup = readStructures(Type.SYSTEM, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseSystem = readStructures(Type.SUBSYSTEM, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDiscipline = readStructures(Type.DEVICEGROUP, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDeviceGroup = readStructures(Type.DEVICETYPE, new Status[] {Status.APPROVED}, false,
null, uuid, null, null, null, null, null,
orderBy, isAsc, offset, limit);
structureElements.addAll(responseSystemGroup.getList());
structureElements.addAll(responseSystem.getList());
structureElements.addAll(responseDiscipline.getList());
structureElements.addAll(responseDeviceGroup.getList());
// uuid is in max one structure
response = new ResponsePageStructureElements(structureElements, Long.valueOf(structureElements.size()), structureElements.size(), offset, limit);
}
return response;
}
public ResponsePageStructureElements readStructuresMnemonic(String mnemonic,
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
// validate input
// mnemonic
// do
// read structure latest by mnemonic
// return
// structure elements for structures
if (StringUtils.isEmpty(parent) && (Type.DISCIPLINE.equals(type) || type == null)) {
if (Boolean.TRUE.equals(includeHistory)) {
List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
} else {
List<Discipline> disciplines = holderRepositories.disciplineRepository().readDisciplines(deleted, uuid, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForDisciplines(disciplines, holderStructures, structureChoice));
}
}
LOGGER.log(Level.FINE, "readStructuresMnemonic, mnemonic: {0}", mnemonic);
if (Type.DEVICEGROUP.equals(type) || type == null) {
if (Boolean.TRUE.equals(includeHistory)) {
List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
} else {
List<DeviceGroup> deviceGroups = holderRepositories.deviceGroupRepository().readDeviceGroups(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceGroups(deviceGroups, holderStructures, structureChoice));
}
}
// validate input
ValidateUtil.validateInputMnemonic(mnemonic);
if (Type.DEVICETYPE.equals(type) || type == null) {
if (Boolean.TRUE.equals(includeHistory)) {
List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
} else {
List<DeviceType> deviceTypes = holderRepositories.deviceTypeRepository().readDeviceTypes(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceTypes(deviceTypes, holderStructures, structureChoice));
}
}
// do
// TODO handle orderBy, isAsc, offset, limit
// pagination for normal read and history
Long totalCount = Long.valueOf(structureElements.size());
structureElements = paginate(structureElements, offset, limit);
ResponsePageStructureElements responseSystemGroup = readStructures(Type.SYSTEMGROUP, new Status[] {Status.APPROVED}, false, null, null, null, mnemonic, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseSystem = readStructures(Type.SYSTEM, new Status[] {Status.APPROVED}, false, null, null, null, mnemonic, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseSubsystem = readStructures(Type.SUBSYSTEM, new Status[] {Status.APPROVED}, false, null, null, null, mnemonic, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDiscipline = readStructures(Type.DISCIPLINE, new Status[] {Status.APPROVED}, false, null, null, null, mnemonic, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDeviceGroup = readStructures(Type.DEVICEGROUP, new Status[] {Status.APPROVED}, false, null, null, null, mnemonic, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDeviceType = readStructures(Type.DEVICETYPE, new Status[] {Status.APPROVED}, false, null, null, null, mnemonic, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements response = new ResponsePageStructureElements(structureElements, totalCount, structureElements.size(), offset, limit);
LOGGER.log(Level.FINE,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_RESPONSE,
TextUtil.READ_STRUCTURES,
response.toString()));
return response;
}
List<StructureElement> structureElements = Lists.newArrayList();
structureElements.addAll(responseSystemGroup.getList());
structureElements.addAll(responseSystem.getList());
structureElements.addAll(responseSubsystem.getList());
structureElements.addAll(responseDiscipline.getList());
structureElements.addAll(responseDeviceGroup.getList());
structureElements.addAll(responseDeviceType.getList());
private List<StructureElement> paginate(List<StructureElement> list, Integer offset, Integer limit) {
// intended as pagination when list may contain result from multiple read operations
// read operations should not contain pagination in such cases
if (offset == null || limit == null) {
return list;
}
return new ResponsePageStructureElements(structureElements, Long.valueOf(structureElements.size()), structureElements.size(), 0, structureElements.size());
List<StructureElement> listPagination = Lists.newArrayList();
int offsetItems = offset * limit;
int availableItems = list.size() - offsetItems;
if (availableItems > 0) {
for (int i = offsetItems; i < Math.min(offsetItems+availableItems, offsetItems+limit); i++) {
listPagination.add(list.get(i));
}
}
return listPagination;
}
public ResponsePageStructureElements readStructuresMnemonicpath(String mnemonicpath,
public ResponsePageStructureElements readStructuresChildren(String uuid,
Boolean deleted,
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
// validation outside method
// read structure by uuid for type
// return structure elements for structures
// validate input
// mnemonicpath
// do
// read structure latest by mnemonicpath
// return
// structure elements for structures
LOGGER.log(Level.FINE, "readStructuresMnemonicpath, mnemonicpath: {0}", mnemonicpath);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES_CHILDREN, "uuid", uuid));
}
// validate input
ValidateUtil.validateInputMnemonic(mnemonicpath);
final List<StructureElement> structureElements = Lists.newArrayList();
// do
// TODO handle orderBy, isAsc, offset, limit
// no children in structures for subsystem and device type
// go through all structures and see if / where uuid is found
// uuid in 0 or 1 of kind of structure
// negligible impact on performance for going through different structures
ResponsePageStructureElements responseSystemGroup = readStructures(Type.SYSTEMGROUP, new Status[] {Status.APPROVED}, false, null, null, null, null, null, mnemonicpath, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseSystem = readStructures(Type.SYSTEM, new Status[] {Status.APPROVED}, false, null, null, null, null, null, mnemonicpath, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseSubsystem = readStructures(Type.SUBSYSTEM, new Status[] {Status.APPROVED}, false, null, null, null, null, null, mnemonicpath, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDiscipline = readStructures(Type.DISCIPLINE, new Status[] {Status.APPROVED}, false, null, null, null, null, null, mnemonicpath, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDeviceGroup = readStructures(Type.DEVICEGROUP, new Status[] {Status.APPROVED}, false, null, null, null, null, null, mnemonicpath, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDeviceType = readStructures(Type.DEVICETYPE, new Status[] {Status.APPROVED}, false, null, null, null, null, null, mnemonicpath, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseSystemGroup = readStructures(Type.SYSTEM, deleted, null, uuid, null, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseSystem = readStructures(Type.SUBSYSTEM, deleted, null, uuid, null, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDiscipline = readStructures(Type.DEVICEGROUP, deleted, null, uuid, null, null, null, null, orderBy, isAsc, offset, limit);
ResponsePageStructureElements responseDeviceGroup = readStructures(Type.DEVICETYPE, deleted, null, uuid, null, null, null, null, orderBy, isAsc, offset, limit);
List<StructureElement> structureElements = Lists.newArrayList();
structureElements.addAll(responseSystemGroup.getList());
structureElements.addAll(responseSystem.getList());
structureElements.addAll(responseSubsystem.getList());
structureElements.addAll(responseDiscipline.getList());
structureElements.addAll(responseDeviceGroup.getList());
structureElements.addAll(responseDeviceType.getList());
return new ResponsePageStructureElements(structureElements, Long.valueOf(structureElements.size()), structureElements.size(), 0, structureElements.size());
// uuid is in max one kind of structure
return new ResponsePageStructureElements(structureElements, Long.valueOf(structureElements.size()), structureElements.size(), offset, limit);
}
/**
* Read history for structure by uuid.
*
* @param uuid uuid
* @param type type
* @return list of structure elements
*/
public ResponsePageStructureElements readStructuresHistory(String uuid, Type type,
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
public ResponsePageStructureElements readStructuresHistory(String uuid, Integer offset, Integer limit) {
// validation outside method
// read history for structure
// return structure elements for structures
// note
// HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return
// type may speed up read
// validate input
// uuid
// do
// read history for structure
// return
// structure elements for structures
LOGGER.log(Level.FINE, "readStructuresHistory, uuid: {0}", uuid);
LOGGER.log(Level.FINE, "readStructuresHistory, type: {0}", type);
// validate input
ValidateUtil.validateInputUuid(uuid);
boolean type_systemGroup = type != null && Type.SYSTEMGROUP.equals(type);
boolean type_system = type != null && Type.SYSTEM.equals(type);
boolean type_subsystem = type != null && Type.SUBSYSTEM.equals(type);
boolean type_discipline = type != null && Type.DISCIPLINE.equals(type);
boolean type_deviceGroup = type != null && Type.DEVICEGROUP.equals(type);
boolean type_deviceType = type != null && Type.DEVICETYPE.equals(type);
boolean type_either = type_systemGroup || type_system || type_subsystem || type_discipline || type_deviceGroup || type_deviceType;
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES_HISTORY, "uuid", uuid));
}
// mnemonic path does not make same sense for history
// (very) tricky to find mnemonic path for uuid at proper time (history)
// very (!) tricky to find mnemonic path for uuid at proper time (history)
// therefore empty mnemonic path for history for structure
// do
final List<StructureElement> structureElements = Lists.newArrayList();
ResponsePageStructureElements response = null;
if (type_either) {
if (type_systemGroup) {
response = readStructures(Type.SYSTEMGROUP, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
} else if (type_system) {
response = readStructures(Type.SYSTEM, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
} else if (type_subsystem) {
response = readStructures(Type.SUBSYSTEM, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
} else if (type_discipline) {
response = readStructures(Type.DISCIPLINE, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
} else if (type_deviceGroup) {
response = readStructures(Type.DEVICEGROUP, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
} else if (type_deviceType) {
response = readStructures(Type.DEVICETYPE, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
}
} else {
// go through all structures and see if / where uuid is found
// uuid in 0 or 1 of structures
ResponsePageStructureElements responseSystemGroup = readStructures(Type.SYSTEMGROUP, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
ResponsePageStructureElements responseSystem = readStructures(Type.SYSTEM, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
ResponsePageStructureElements responseSubsystem = readStructures(Type.SUBSYSTEM, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
ResponsePageStructureElements responseDiscipline = readStructures(Type.DISCIPLINE, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
ResponsePageStructureElements responseDeviceGroup = readStructures(Type.DEVICEGROUP, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
ResponsePageStructureElements responseDeviceType = readStructures(Type.DEVICETYPE, null, null, uuid, null, null, null, null, null, null, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY);
structureElements.addAll(responseSystemGroup.getList());
structureElements.addAll(responseSystem.getList());
structureElements.addAll(responseSubsystem.getList());
structureElements.addAll(responseDiscipline.getList());
structureElements.addAll(responseDeviceGroup.getList());
structureElements.addAll(responseDeviceType.getList());
// uuid is in max one structure
response = new ResponsePageStructureElements(structureElements, Long.valueOf(structureElements.size()), structureElements.size(), offset, limit);
}
Collections.sort(response.getList(), new Comparator<StructureElement>() {
@Override
public int compare(StructureElement e1, StructureElement e2) {
return e1.getWhen().compareTo(e2.getWhen());
}
});
// go through structures and see if / where uuid is found
// uuid in 0 or 1 kind of structures
// uuid is in max one kind of structure
ResponsePageStructureElements response = readStructures(Type.SYSTEMGROUP, null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY);
response = response.getTotalCount() == 0 ? readStructures(Type.SYSTEM, null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
response = response.getTotalCount() == 0 ? readStructures(Type.SUBSYSTEM, null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
response = response.getTotalCount() == 0 ? readStructures(Type.DISCIPLINE, null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
response = response.getTotalCount() == 0 ? readStructures(Type.DEVICEGROUP, null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
response = response.getTotalCount() == 0 ? readStructures(Type.DEVICETYPE, null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
return response;
}
// ----------------------------------------------------------------------------------------------------
public String equivalenceMnemonic(String mnemonic) {
// validate input
// do
// exists
LOGGER.log(Level.FINE, "equivalenceMnemonic, mnemonic: {0}", mnemonic);
// validate input
ValidateUtil.validateInputMnemonic(mnemonic);
// do
return namingConvention.equivalenceClassRepresentative(mnemonic);
}
public Boolean existsStructure(Type type, String mnemonicpath) {
// validate input
// do
// exists
LOGGER.log(Level.FINE, "existsStructure, mnemonicpath: {0}", mnemonicpath);
public Boolean existsStructure(Type type, String mnemonicPath) {
// validation outside method
// read exists
// validate input
ValidateUtil.validateInputType(type);
ValidateUtil.validateInputMnemonicpath(mnemonicpath);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.EXISTS_STRUCTURE, "type", type));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.EXISTS_STRUCTURE, "mnemonicPath", mnemonicPath));
}
// do
if (Type.SYSTEMGROUP.equals(type)) {
List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false,
null, null, null, null, mnemonicpath, null);
List<SystemGroup> systemGroups = holderRepositories.systemGroupRepository().readSystemGroups(false, null, null, null, mnemonicPath, null, null);
return !systemGroups.isEmpty();
} else if (Type.SYSTEM.equals(type)) {
List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false,
null, null, null, null, null, mnemonicpath, null);
List<System> systems = holderRepositories.systemRepository().readSystems(false, null, null, null, null, mnemonicPath, null, null);
return !systems.isEmpty();
} else if (Type.SUBSYSTEM.equals(type)) {
List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false,
null, null, null, null, null, mnemonicpath, null);
List<Subsystem> subsystems = holderRepositories.subsystemRepository().readSubsystems(false, null, null, null, null, mnemonicPath, null, null);
return !subsystems.isEmpty();
} else if (Type.DISCIPLINE.equals(type)) {
List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false,
null, null, null, null, mnemonicpath, null);
List<Discipline> disciplines = holderRepositories.disciplineRepository().readDisciplines(false, null, null, null, mnemonicPath, null, null);
return !disciplines.isEmpty();
} else if (Type.DEVICEGROUP.equals(type)) {
List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, false,
null, null, null, null, null, mnemonicpath, null);
return !deviceGroups.isEmpty();
return Boolean.FALSE;
} else if (Type.DEVICETYPE.equals(type)) {
List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false,
null, null, null, null, null, mnemonicpath, null);
List<DeviceType> deviceTypes = holderRepositories.deviceTypeRepository().readDeviceTypes(false, null, null, null, null, mnemonicPath, null, null);
return !deviceTypes.isEmpty();
}
return Boolean.FALSE;
}
public Boolean isValidToCreateStructure(Type type, String mnemonicpath) {
// validate input
// validate data
// not exists
LOGGER.log(Level.FINE, "isValidToCreateStructure, mnemonicpath: {0}", mnemonicpath);
public Boolean isValidToCreateStructure(Type type, String mnemonicPath) {
// validation outside method
// validate data - not exists
// validate input
ValidateUtil.validateInputType(type);
ValidateUtil.validateInputMnemonicpath(mnemonicpath);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_VALID_TO_CREATE_STRUCTURE, "type", type));
LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_VALID_TO_CREATE_STRUCTURE, "mnemonicPath", mnemonicPath));
}
// initiate holder of containers for system and device structure content, for performance reasons
// holder of valid content for system and device structures
// note false to not include deleted entries
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories, false);
HolderStructures holderStructures = new HolderStructures(holderIRepositories, false);
// validate data
ValidateStructureElementUtil.validateStructureDataCreate(type, mnemonicpath, namingConvention, holderIRepositories, holder);
ValidateStructureElementUtil.validateStructureDataCreate(type, mnemonicPath, namingConvention, holderIRepositories, holderStructures);
return Boolean.TRUE;
}
......@@ -709,973 +479,189 @@ public class StructuresService {
// ----------------------------------------------------------------------------------------------------
public void validateStructuresCreate(StructureElementCommand structureElement) {
validateStructuresCreate(structureElement, new HolderSystemDeviceStructure(holderIRepositories));
validateStructuresCreate(structureElement, new HolderStructures(holderIRepositories));
}
public void validateStructuresCreate(StructureElementCommand structureElement, HolderSystemDeviceStructure holder) {
// validate input
// type
// structure element
// validate input itself
// validate data
// structure element
// validate data
// itself
// relative other data
// validate input
ValidateStructureElementUtil.validateStructureElementInputCreate(structureElement, namingConvention);
public void validateStructuresCreate(StructureElementCommand structureElement, HolderStructures holderStructures) {
// validate structure element
// input vs given task
// data vs given task
// validate data
ValidateStructureElementUtil.validateStructureElementDataCreate(structureElement, namingConvention, holderRepositories, holder);
ValidateStructureElementUtil.validateStructureElementInputCreate(structureElement, namingConvention);
ValidateStructureElementUtil.validateStructureElementDataCreate(structureElement, namingConvention, holderRepositories, holderStructures);
}
public void validateStructuresCreate(List<StructureElementCommand> structureElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (StructureElementCommand structureElement : structureElements) {
validateStructuresCreate(structureElement, holder);
validateStructuresCreate(structureElement, holderStructures);
}
}
public void validateStructuresUpdate(StructureElementCommand structureElement) {
validateStructuresUpdate(structureElement, new HolderSystemDeviceStructure(holderIRepositories));
validateStructuresUpdate(structureElement, new HolderStructures(holderIRepositories));
}
public void validateStructuresUpdate(StructureElementCommand structureElement, HolderSystemDeviceStructure holder) {
// validate input
// type
// structure element
// validate input itself
// validate data
// structure element
// validate data
// itself
// relative other data
// validate input
ValidateStructureElementUtil.validateStructureElementInputUpdate(structureElement, namingConvention);
public void validateStructuresUpdate(StructureElementCommand structureElement, HolderStructures holderStructures) {
// validate structure element
// input vs given task
// data vs given task
// validate data
ValidateStructureElementUtil.validateStructureElementDataUpdate(structureElement, namingConvention, holderRepositories, holder);
ValidateStructureElementUtil.validateStructureElementInputUpdate(structureElement, namingConvention);
ValidateStructureElementUtil.validateStructureElementDataUpdate(structureElement, namingConvention, holderRepositories, holderStructures);
}
public void validateStructuresUpdate(List<StructureElementCommand> structureElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (StructureElementCommand structureElement : structureElements) {
validateStructuresUpdate(structureElement, holder);
validateStructuresUpdate(structureElement, holderStructures);
}
}
public void validateStructuresDelete(StructureElementCommand structureElement) {
validateStructuresDelete(structureElement, new HolderSystemDeviceStructure(holderIRepositories));
validateStructuresDelete(structureElement, new HolderStructures(holderIRepositories));
}
public void validateStructuresDelete(StructureElementCommand structureElement, HolderSystemDeviceStructure holder) {
// validate input
// type
// structure element
// validate input itself
// validate data
// structure element
// validate data
// itself
// relative other data
// validate input
ValidateStructureElementUtil.validateStructureElementInputDelete(structureElement, namingConvention);
public void validateStructuresDelete(StructureElementCommand structureElement, HolderStructures holderStructures) {
// validate structure element
// input vs given task
// data vs given task
// validate data
ValidateStructureElementUtil.validateStructureElementDataDelete(structureElement, namingConvention, holderRepositories, holder);
ValidateStructureElementUtil.validateStructureElementInputDelete(structureElement, namingConvention);
ValidateStructureElementUtil.validateStructureElementDataDelete(structureElement, namingConvention, holderRepositories, holderStructures);
}
public void validateStructuresDelete(List<StructureElementCommand> structureElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
for (StructureElementCommand structureElement : structureElements) {
validateStructuresDelete(structureElement, holder);
}
}
public void validateStructuresApprove(StructureElementCommand structureElement) {
validateStructuresApprove(structureElement, new HolderSystemDeviceStructure(holderIRepositories));
}
public void validateStructuresApprove(StructureElementCommand structureElement, HolderSystemDeviceStructure holder) {
// validate input
// type
// structure element
// validate input itself
// validate data
// structure element
// validate data
// itself
// relative other data
// validate input
ValidateStructureElementUtil.validateStructureElementInputApprove(structureElement, namingConvention);
// validate data
ValidateStructureElementUtil.validateStructureElementDataApprove(structureElement, namingConvention, holderRepositories, holder);
}
public void validateStructuresApprove(List<StructureElementCommand> structureElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
for (StructureElementCommand structureElement : structureElements) {
validateStructuresApprove(structureElement, holder);
}
}
public void validateStructuresCancel(StructureElementCommand structureElement) {
validateStructuresCancel(structureElement, new HolderSystemDeviceStructure(holderIRepositories));
}
public void validateStructuresCancel(StructureElementCommand structureElement, HolderSystemDeviceStructure holder) {
// validate input
// type
// structure element
// validate input itself
// validate data
// structure element
// validate data
// itself
// relative other data
// validate input
ValidateStructureElementUtil.validateStructureElementInputCancel(structureElement, namingConvention);
// validate data
ValidateStructureElementUtil.validateStructureElementDataCancel(structureElement, namingConvention, holderRepositories, holder);
}
public void validateStructuresCancel(List<StructureElementCommand> structureElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
for (StructureElementCommand structureElement : structureElements) {
validateStructuresCancel(structureElement, holder);
}
}
public void validateStructuresReject(StructureElementCommand structureElement) {
validateStructuresReject(structureElement, new HolderSystemDeviceStructure(holderIRepositories));
}
public void validateStructuresReject(StructureElementCommand structureElement, HolderSystemDeviceStructure holder) {
// validate input
// type
// structure element
// validate input itself
// validate data
// structure element
// validate data
// itself
// relative other data
// validate input
ValidateStructureElementUtil.validateStructureElementInputReject(structureElement, namingConvention);
// validate data
ValidateStructureElementUtil.validateStructureElementDataReject(structureElement, namingConvention, holderRepositories, holder);
}
public void validateStructuresReject(List<StructureElementCommand> structureElements) {
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (StructureElementCommand structureElement : structureElements) {
validateStructuresReject(structureElement, holder);
validateStructuresDelete(structureElement, holderStructures);
}
}
// ----------------------------------------------------------------------------------------------------
@Transactional
public List<StructureElement> updateStructures(List<StructureElementCommand> structureElements) {
// validate
// outside of @Transactional
public List<StructureElement> updateStructures(List<StructureElementCommand> structureElements, String username) {
// validation outside method
// transaction
// do
// for each structure element
// create structure to pending, not latest, not deleted, with data
// add structure element for updated
// return
// structure elements for updated structures
LOGGER.log(Level.FINE, "updateStructures, structureElements.size: {0}", String.valueOf(structureElements != null ? structureElements.size() : "null"));
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date requested = new Date();
String requestedBy = TextUtil.TEST_WHO;
// for each structure element command
// update structure
// handle
// notification
// structure element for updated structure
// notify
// return structure elements for updated structures
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
Date when = new Date();
List<NotificationStructure> notifications = Lists.newArrayList();
final List<StructureElement> updatedStructureElements = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
// note
// namingConvention.equivalenceClassRepresentative return null for null input
UUID uuid = structureElement.getUuid();
String name = structureElement.getName();
String mnemonic = structureElement.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
String description = structureElement.getDescription();
String requestedComment = structureElement.getComment();
if (Type.SYSTEMGROUP.equals(structureElement.getType())) {
// note rules for mnemonic for system group
// create
SystemGroup systemGroup = new SystemGroup(uuid,
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getSystemGroupRepository().createSystemGroup(systemGroup);
// possibly validate that created
// add
updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(systemGroup, holder));
} else if (Type.SYSTEM.equals(structureElement.getType())) {
// create
System system = new System(uuid, structureElement.getParent(),
name, structureElement.getMnemonic(), equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getSystemRepository().createSystem(system);
// possibly validate that created
// add
updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(system, holder));
} else if (Type.SUBSYSTEM.equals(structureElement.getType())) {
// create
Subsystem subsystem = new Subsystem(uuid, structureElement.getParent(),
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getSubsystemRepository().createSubsystem(subsystem);
// possibly validate that created
// add
updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(subsystem, holder));
} else if (Type.DISCIPLINE.equals(structureElement.getType())) {
// create
Discipline discipline = new Discipline(uuid,
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getDisciplineRepository().createDiscipline(discipline);
// possibly validate that created
// add
updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(discipline, holder));
} else if (Type.DEVICEGROUP.equals(structureElement.getType())) {
// note rules for mnemonic for device group
// create
DeviceGroup deviceGroup = new DeviceGroup(uuid, structureElement.getParent(),
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getDeviceGroupRepository().createDeviceGroup(deviceGroup);
// possibly validate that created
// add
updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceGroup, holder));
} else if (Type.DEVICETYPE.equals(structureElement.getType())) {
// create
DeviceType deviceType = new DeviceType(uuid, structureElement.getParent(),
name, mnemonic, equivalenceClassRepresentative,
description, Status.PENDING, Boolean.FALSE, Boolean.FALSE,
requested, requestedBy, requestedComment);
holderRepositories.getDeviceTypeRepository().createDeviceType(deviceType);
// possibly validate that created
// add
updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceType, holder));
Type type = structureElement.getType();
StructureElementNotification structureElementNotification = null;
if (Type.SYSTEMGROUP.equals(type)) {
structureElementNotification = systemGroupService.updateStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.SYSTEM.equals(type)) {
structureElementNotification = systemService.updateStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.SUBSYSTEM.equals(type)) {
structureElementNotification = subsystemService.updateStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.DISCIPLINE.equals(type)) {
structureElementNotification = disciplineService.updateStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.DEVICEGROUP.equals(type)) {
structureElementNotification = deviceGroupService.updateStructure(structureElement, when, username, namingConvention, holderStructures);
} else if (Type.DEVICETYPE.equals(type)) {
structureElementNotification = deviceTypeService.updateStructure(structureElement, when, username, namingConvention, holderStructures);
} else {
continue;
}
}
LOGGER.log(Level.FINE, "updateStructures, updatedStructureElements.size: {0}", updatedStructureElements.size());
return updatedStructureElements;
}
Utilities.addToCollection(notifications, structureElementNotification.notificationStructure());
Utilities.addToCollection(updatedStructureElements, structureElementNotification.structureElement());
// ----------------------------------------------------------------------------------------------------
@Transactional
public List<StructureElement> deleteStructures(List<StructureElementCommand> structureElements) {
// validate
// outside of @Transactional
// transaction
// do
// for each structure element
// find
// create structure to pending, not latest, deleted, with data
// add structure element for deleted
// return
// structure elements for deleted structures
// TODO continue ---> validation error
LOGGER.log(Level.FINE, "deleteStructures, structureElements.size: {0}", String.valueOf(structureElements != null ? structureElements.size() : "null"));
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date requested = new Date();
String requestedBy = TextUtil.TEST_WHO;
final List<StructureElement> deletedStructureElements = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
String queryValue = structureElement.getUuid().toString();
if (Type.SYSTEMGROUP.equals(structureElement.getType())) {
// find
List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null);
if (systemGroups == null || systemGroups.size() != 1) {
continue;
}
SystemGroup toBeDeleted = systemGroups.get(0);
// create
SystemGroup systemGroup = new SystemGroup(toBeDeleted.getUuid(),
toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()),
toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE,
requested, requestedBy, structureElement.getComment());
holderRepositories.getSystemGroupRepository().createSystemGroup(systemGroup);
// possibly validate that created
// add
deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(systemGroup, holder));
} else if (Type.SYSTEM.equals(structureElement.getType())) {
// find
List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
if (systems == null || systems.size() != 1) {
continue;
}
System toBeDeleted = systems.get(0);
// create
System system = new System(toBeDeleted.getUuid(), toBeDeleted.getParentUuid(),
toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()),
toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE,
requested, requestedBy, structureElement.getComment());
holderRepositories.getSystemRepository().createSystem(system);
// possibly validate that created
// add
deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(system, holder));
} else if (Type.SUBSYSTEM.equals(structureElement.getType())) {
// find
List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
if (subsystems == null || subsystems.size() != 1) {
continue;
}
Subsystem toBeDeleted = subsystems.get(0);
// create
Subsystem subsystem = new Subsystem(toBeDeleted.getUuid(), toBeDeleted.getParentUuid(),
toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()),
toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE,
requested, requestedBy, structureElement.getComment());
holderRepositories.getSubsystemRepository().createSubsystem(subsystem);
// possibly validate that created
// add
deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(subsystem, holder));
} else if (Type.DISCIPLINE.equals(structureElement.getType())) {
// find
List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null);
if (disciplines == null || disciplines.size() != 1) {
continue;
}
Discipline toBeDeleted = disciplines.get(0);
// create
Discipline discipline = new Discipline(toBeDeleted.getUuid(),
toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()),
toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE,
requested, requestedBy, structureElement.getComment());
holderRepositories.getDisciplineRepository().createDiscipline(discipline);
// possibly validate that created
// add
deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(discipline, holder));
} else if (Type.DEVICEGROUP.equals(structureElement.getType())) {
// find
List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
if (deviceGroups == null || deviceGroups.size() != 1) {
continue;
}
DeviceGroup toBeDeleted = deviceGroups.get(0);
// create
DeviceGroup deviceGroup = new DeviceGroup(toBeDeleted.getUuid(), toBeDeleted.getParentUuid(),
toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()),
toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE,
requested, requestedBy, structureElement.getComment());
holderRepositories.getDeviceGroupRepository().createDeviceGroup(deviceGroup);
// possibly validate that created
// add
deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceGroup, holder));
} else if (Type.DEVICETYPE.equals(structureElement.getType())) {
// find
List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
if (deviceTypes == null || deviceTypes.size() != 1) {
continue;
}
DeviceType toBeDeleted = deviceTypes.get(0);
// create
DeviceType deviceType = new DeviceType(toBeDeleted.getUuid(), toBeDeleted.getParentUuid(),
toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()),
toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE,
requested, requestedBy, structureElement.getComment());
holderRepositories.getDeviceTypeRepository().createDeviceType(deviceType);
// possibly validate that created
// add
deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceType, holder));
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, "type", type));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.ELEMENT_IN, structureElement));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.ELEMENT_OUT, structureElementNotification.structureElement()));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.NOTIFICATION, structureElementNotification.notificationStructure()));
}
}
LOGGER.log(Level.FINE, "deleteStructures, deletedStructureElements.size: {0}", deletedStructureElements.size());
return deletedStructureElements;
// notify
notificationService.notifyStructures(notifications, StructureCommand.UPDATE);
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Update structures",
structureElements.size(),
updatedStructureElements.size()));
return updatedStructureElements;
}
// ----------------------------------------------------------------------------------------------------
@Transactional
public List<StructureElement> approveStructures(List<StructureElementCommand> structureElements) {
// validate
// outside of @Transactional
public List<StructureElement> deleteStructures(List<StructureElementCommand> structureElements, String username) {
// validation outside method
// transaction
// do
// update structure to status APPROVED
// return
// updated structure element
// TODO continue ---> validation error
LOGGER.log(Level.FINE, "approveStructures, structureElements.size: {0}", String.valueOf(structureElements != null ? structureElements.size() : "null"));
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// approve
// set not latest for current latest
// set approved, latest for pending
// possibly
// if deleted, names that belong to structure may be deleted, otherwise they are alive but become legacy names - legacy way for now
// TODO if not deleted, rename names that belong to structure if different mnemonic
// if that way, then compare what's about to be approved with what is latest
// do
// update
// set not latest for current latest
// set approved, latest for pending
Date processed = new Date();
String processedBy = TextUtil.TEST_WHO;
final List<StructureElement> approvedStructureElements = Lists.newArrayList();
// for each structure element command
// delete structure
// handle
// notification
// structure element for deleted structure
// notify
// return structure elements for deleted structures
// holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
Date when = new Date();
List<NotificationStructure> notifications = Lists.newArrayList();
final List<StructureElement> deletedStructureElements = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
String queryValue = structureElement.getUuid().toString();
String processedComment = structureElement.getComment();
if (Type.SYSTEMGROUP.equals(structureElement.getType())) {
// find
List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null);
SystemGroup systemGroup = null;
if (systemGroups != null && systemGroups.size() == 1) {
systemGroup = systemGroups.get(0);
// update not latest
systemGroup.setLatest(Boolean.FALSE);
holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup);
}
// find
systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null,
queryValue, null, null, null, null, null);
if (systemGroups == null || systemGroups.size() != 1) {
continue;
}
systemGroup = systemGroups.get(0);
// approve
systemGroup.setAttributesStatusProcessed(Status.APPROVED, processed, processedBy, processedComment);
systemGroup.setLatest(Boolean.TRUE);
holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup);
// possibly validate that approved
// automatically create name when system structure is approved (after create)
// create name within current transaction
if (!StringUtils.isEmpty(systemGroup.getMnemonic())) {
NameElementCommand nameElement = new NameElementCommand(null, systemGroup.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
LOGGER.log(Level.FINE, "approveStructures, nameElement created, name: {0}", createdNameElement.getName());
}
// add
approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(systemGroup, holder));
} else if (Type.SYSTEM.equals(structureElement.getType())) {
// find
List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
System system = null;
if (systems != null && systems.size() == 1) {
system = systems.get(0);
// update not latest
system.setLatest(Boolean.FALSE);
holderRepositories.getSystemRepository().updateSystem(system);
}
// find
systems = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (systems == null || systems.size() != 1) {
continue;
}
system = systems.get(0);
// approve
system.setAttributesStatusProcessed(Status.APPROVED, processed, processedBy, processedComment);
system.setLatest(Boolean.TRUE);
holderRepositories.getSystemRepository().updateSystem(system);
// possibly validate that approved
// automatically create name when system structure is approved (after create)
// create name within current transaction
if (!StringUtils.isEmpty(system.getMnemonic())) {
NameElementCommand nameElement = new NameElementCommand(null, system.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
LOGGER.log(Level.FINE, "approveStructures, nameElement created, name: {0}", createdNameElement.getName());
}
// add
approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(system, holder));
} else if (Type.SUBSYSTEM.equals(structureElement.getType())) {
// find
List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
Subsystem subsystem = null;
if (subsystems != null && subsystems.size() == 1) {
subsystem = subsystems.get(0);
// update not latest
subsystem.setLatest(Boolean.FALSE);
holderRepositories.getSubsystemRepository().updateSubsystem(subsystem);
}
// find
subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (subsystems == null || subsystems.size() != 1) {
continue;
}
subsystem = subsystems.get(0);
// approve
subsystem.setAttributesStatusProcessed(Status.APPROVED, processed, processedBy, processedComment);
subsystem.setLatest(Boolean.TRUE);
holderRepositories.getSubsystemRepository().updateSubsystem(subsystem);
// possibly validate that approved
// automatically create name when system structure is approved (after create)
// create name within current transaction
if (!StringUtils.isEmpty(subsystem.getMnemonic())) {
NameElementCommand nameElement = new NameElementCommand(null, subsystem.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
LOGGER.log(Level.FINE, "approveStructures, nameElement created, name: {0}", createdNameElement.getName());
}
// add
approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(subsystem, holder));
} else if (Type.DISCIPLINE.equals(structureElement.getType())) {
List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null);
Discipline discipline = null;
if (disciplines != null && disciplines.size() == 1) {
discipline = disciplines.get(0);
// update not latest
discipline.setLatest(Boolean.FALSE);
holderRepositories.getDisciplineRepository().updateDiscipline(discipline);
}
// find
disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null,
queryValue, null, null, null, null, null);
if (disciplines == null || disciplines.size() != 1) {
continue;
}
discipline = disciplines.get(0);
// approve
discipline.setAttributesStatusProcessed(Status.APPROVED, processed, processedBy, processedComment);
discipline.setLatest(Boolean.TRUE);
holderRepositories.getDisciplineRepository().updateDiscipline(discipline);
// possibly validate that approved
// add
approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(discipline, holder));
} else if (Type.DEVICEGROUP.equals(structureElement.getType())) {
// find
List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
DeviceGroup deviceGroup = null;
if (deviceGroups != null && deviceGroups.size() == 1) {
deviceGroup = deviceGroups.get(0);
// update not latest
deviceGroup.setLatest(Boolean.FALSE);
holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup);
}
// find
deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (deviceGroups == null || deviceGroups.size() != 1) {
continue;
}
deviceGroup = deviceGroups.get(0);
// approve
deviceGroup.setAttributesStatusProcessed(Status.APPROVED, processed, processedBy, processedComment);
deviceGroup.setLatest(Boolean.TRUE);
holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup);
// possibly validate that approved
// add
approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceGroup, holder));
} else if (Type.DEVICETYPE.equals(structureElement.getType())) {
// find
List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, Boolean.FALSE,
queryValue, null, null, null, null, null, null);
DeviceType deviceType = null;
if (deviceTypes != null && deviceTypes.size() == 1) {
deviceType = deviceTypes.get(0);
// update not latest
deviceType.setLatest(Boolean.FALSE);
holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType);
}
// find
deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (deviceTypes == null || deviceTypes.size() != 1) {
continue;
}
deviceType = deviceTypes.get(0);
// approve
deviceType.setAttributesStatusProcessed(Status.APPROVED, processed, processedBy, processedComment);
deviceType.setLatest(Boolean.TRUE);
holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType);
// possibly validate that approved
// add
approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceType, holder));
Type type = structureElement.getType();
StructureElementNotification structureElementNotification = null;
if (Type.SYSTEMGROUP.equals(type)) {
structureElementNotification = systemGroupService.deleteStructure(structureElement, when, username, holderStructures);
} else if (Type.SYSTEM.equals(type)) {
structureElementNotification = systemService.deleteStructure(structureElement, when, username, holderStructures);
} else if (Type.SUBSYSTEM.equals(type)) {
structureElementNotification = subsystemService.deleteStructure(structureElement, when, username, holderStructures);
} else if (Type.DISCIPLINE.equals(type)) {
structureElementNotification = disciplineService.deleteStructure(structureElement, when, username, holderStructures);
} else if (Type.DEVICEGROUP.equals(type)) {
structureElementNotification = deviceGroupService.deleteStructure(structureElement, when, username, holderStructures);
} else if (Type.DEVICETYPE.equals(type)) {
structureElementNotification = deviceTypeService.deleteStructure(structureElement, when, username, holderStructures);
} else {
continue;
}
}
LOGGER.log(Level.FINE, "approveStructures, approvedStructureElements.size: {0}", approvedStructureElements.size());
return approvedStructureElements;
}
@Transactional
public List<StructureElement> cancelStructures(List<StructureElementCommand> structureElements) {
// validate
// outside of @Transactional
// transaction
// do
// update structure to status CANCELLED
// return
// updated structure element
// TODO continue ---> validation error
LOGGER.log(Level.FINE, "cancelStructures, structureElements.size: {0}", String.valueOf(structureElements != null ? structureElements.size() : "null"));
Utilities.addToCollection(notifications, structureElementNotification.notificationStructure());
Utilities.addToCollection(deletedStructureElements, structureElementNotification.structureElement());
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date processed = new Date();
String processedBy = TextUtil.TEST_WHO;
final List<StructureElement> cancelledStructureElements = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
String queryValue = structureElement.getUuid().toString();
String processedComment = structureElement.getComment();
if (Type.SYSTEMGROUP.equals(structureElement.getType())) {
// find
List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null,
queryValue, null, null, null, null, null);
if (systemGroups == null || systemGroups.size() != 1) {
continue;
}
SystemGroup systemGroup = systemGroups.get(0);
// cancel
systemGroup.setAttributesStatusProcessed(Status.CANCELLED, processed, processedBy, processedComment);
holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup);
// possibly validate that cancelled
// add
cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(systemGroup, holder));
} else if (Type.SYSTEM.equals(structureElement.getType())) {
// find
List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (systems == null || systems.size() != 1) {
continue;
}
System system = systems.get(0);
// cancel
system.setAttributesStatusProcessed(Status.CANCELLED, processed, processedBy, processedComment);
holderRepositories.getSystemRepository().updateSystem(system);
// possibly validate that cancelled
// add
cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(system, holder));
} else if (Type.SUBSYSTEM.equals(structureElement.getType())) {
// find
List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (subsystems == null || subsystems.size() != 1) {
continue;
}
Subsystem subsystem = subsystems.get(0);
// cancel
subsystem.setAttributesStatusProcessed(Status.CANCELLED, processed, processedBy, processedComment);
holderRepositories.getSubsystemRepository().updateSubsystem(subsystem);
// possibly validate that cancelled
// add
cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(subsystem, holder));
} else if (Type.DISCIPLINE.equals(structureElement.getType())) {
// find
List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null,
queryValue, null, null, null, null, null);
if (disciplines == null || disciplines.size() != 1) {
continue;
}
Discipline discipline = disciplines.get(0);
// cancel
discipline.setAttributesStatusProcessed(Status.CANCELLED, processed, processedBy, processedComment);
holderRepositories.getDisciplineRepository().updateDiscipline(discipline);
// possibly validate that cancelled
// add
cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(discipline, holder));
} else if (Type.DEVICEGROUP.equals(structureElement.getType())) {
// find
List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (deviceGroups == null || deviceGroups.size() != 1) {
continue;
}
DeviceGroup deviceGroup = deviceGroups.get(0);
// cancel
deviceGroup.setAttributesStatusProcessed(Status.CANCELLED, processed, processedBy, processedComment);
holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup);
// possibly validate that cancelled
// add
cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceGroup, holder));
} else if (Type.DEVICETYPE.equals(structureElement.getType())) {
List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (deviceTypes == null || deviceTypes.size() != 1) {
continue;
}
DeviceType deviceType = deviceTypes.get(0);
// cancel
deviceType.setAttributesStatusProcessed(Status.CANCELLED, processed, processedBy, processedComment);
holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType);
// possibly validate that cancelled
// add
cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceType, holder));
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, "type", type));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.ELEMENT_IN, structureElement));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.ELEMENT_OUT, structureElementNotification.structureElement()));
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.NOTIFICATION, structureElementNotification.notificationStructure()));
}
}
LOGGER.log(Level.FINE, "cancelStructures, cancelledStructureElements.size: {0}", cancelledStructureElements.size());
return cancelledStructureElements;
}
@Transactional
public List<StructureElement> rejectStructures(List<StructureElementCommand> structureElements) {
// validate
// outside of @Transactional
// transaction
// do
// update structure to status REJECTED
// return
// updated structure element
// TODO continue ---> validation error
LOGGER.log(Level.FINE, "rejectStructures, structureElements.size: {0}", String.valueOf(structureElements != null ? structureElements.size() : "null"));
// notify
notificationService.notifyStructures(notifications, StructureCommand.DELETE);
// initiate holder of containers for system and device structure content, for performance reasons
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories);
// do
Date processed = new Date();
String processedBy = TextUtil.TEST_WHO;
final List<StructureElement> rejectedStructureElements = Lists.newArrayList();
for (StructureElementCommand structureElement : structureElements) {
String queryValue = structureElement.getUuid().toString();
String processedComment = structureElement.getComment();
if (Type.SYSTEMGROUP.equals(structureElement.getType())) {
// find
List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null,
queryValue, null, null, null, null, null);
if (systemGroups == null || systemGroups.size() != 1) {
continue;
}
SystemGroup systemGroup = systemGroups.get(0);
// reject
systemGroup.setAttributesStatusProcessed(Status.REJECTED, processed, processedBy, processedComment);
holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup);
// possibly validate that rejected
// add
rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(systemGroup, holder));
} else if (Type.SYSTEM.equals(structureElement.getType())) {
// find
List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (systems == null || systems.size() != 1) {
continue;
}
System system = systems.get(0);
// reject
system.setAttributesStatusProcessed(Status.REJECTED, processed, processedBy, processedComment);
holderRepositories.getSystemRepository().updateSystem(system);
// possibly validate that rejected
// add
rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(system, holder));
} else if (Type.SUBSYSTEM.equals(structureElement.getType())) {
// find
List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (subsystems == null || subsystems.size() != 1) {
continue;
}
Subsystem subsystem = subsystems.get(0);
// reject
subsystem.setAttributesStatusProcessed(Status.REJECTED, processed, processedBy, processedComment);
holderRepositories.getSubsystemRepository().updateSubsystem(subsystem);
// possibly validate that rejected
// add
rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(subsystem, holder));
} else if (Type.DISCIPLINE.equals(structureElement.getType())) {
// find
List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null,
queryValue, null, null, null, null, null);
if (disciplines == null || disciplines.size() != 1) {
continue;
}
Discipline discipline = disciplines.get(0);
// reject
discipline.setAttributesStatusProcessed(Status.REJECTED, processed, processedBy, processedComment);
holderRepositories.getDisciplineRepository().updateDiscipline(discipline);
// possibly validate that rejected
// add
rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(discipline, holder));
} else if (Type.DEVICEGROUP.equals(structureElement.getType())) {
// find
List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (deviceGroups == null || deviceGroups.size() != 1) {
continue;
}
DeviceGroup deviceGroup = deviceGroups.get(0);
// reject
deviceGroup.setAttributesStatusProcessed(Status.REJECTED, processed, processedBy, processedComment);
holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup);
// possibly validate that rejected
// add
rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceGroup, holder));
} else if (Type.DEVICETYPE.equals(structureElement.getType())) {
List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null,
queryValue, null, null, null, null, null, null);
if (deviceTypes == null || deviceTypes.size() != 1) {
continue;
}
DeviceType deviceType = deviceTypes.get(0);
// reject
deviceType.setAttributesStatusProcessed(Status.REJECTED, processed, processedBy, processedComment);
holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType);
// possibly validate that rejected
// add
rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceType, holder));
}
}
LOGGER.log(Level.FINE, "rejectStructures, rejectedStructureElements.size: {0}", rejectedStructureElements.size());
return rejectedStructureElements;
LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Delete structures",
structureElements.size(),
deletedStructureElements.size()));
return deletedStructureElements;
}
}
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import java.text.MessageFormat;
import java.util.Date;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.SubsystemRepository;
import org.openepics.names.repository.model.AuditStructure;
import org.openepics.names.repository.model.Subsystem;
import org.openepics.names.repository.model.System;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.NameElementCommand;
import org.openepics.names.rest.beans.element.StructureElementCommand;
import org.openepics.names.util.EssNamingConvention;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.StructureChoice;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.StructureUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.notification.NotificationUtil;
import org.openepics.names.util.notification.StructureElementNotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* This class provides structures services for subsystem.
*
* @author Lars Johansson
*/
@Service
public class SubsystemService {
private static final Logger LOGGER = Logger.getLogger(SubsystemService.class.getName());
private final NamesService namesService;
private final ISystemRepository iSystemRepository;
private final ISubsystemRepository iSubsystemRepository;
private final IAuditStructureRepository iAuditStructureRepository;
private final SubsystemRepository subsystemRepository;
private final AuditStructureRepository auditStructureRepository;
@Autowired
public SubsystemService(
NamesService namesService,
ISystemRepository iSystemRepository,
ISubsystemRepository iSubsystemRepository,
IAuditStructureRepository iAuditStructureRepository,
SubsystemRepository subsystemRepository,
AuditStructureRepository auditStructureRepository) {
this.namesService = namesService;
this.iSystemRepository = iSystemRepository;
this.iSubsystemRepository = iSubsystemRepository;
this.iAuditStructureRepository = iAuditStructureRepository;
this.subsystemRepository = subsystemRepository;
this.auditStructureRepository = auditStructureRepository;
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// create structure
// create audit
// additional
// automatically create name when system structure is created
// conditions on name and structure entry
// system structure should exist - mnemonic
// name should not exist - system structure mnemonic path
// return
// structure element for created structure
// notification
UUID uuid = UUID.randomUUID();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// create structure
// create audit
System system = iSystemRepository.findByUuid(structureElementCommand.getParent().toString());
Subsystem subsystem = new Subsystem(uuid, system.getId(),
mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
when, username, null);
subsystemRepository.createSubsystem(subsystem);
auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, subsystem));
// additional
boolean hasMnemonic = !StringUtils.isEmpty(subsystem.getMnemonic());
boolean existsName = hasMnemonic && namesService.existsName(StructureUtil.getMnemonicPath(subsystem, holderStructures));
if (hasMnemonic && !existsName) {
NameElementCommand nameElement = new NameElementCommand(null, subsystem.getUuid(), null, null, StructuresService.SYSTEM_STRUCTURE_ONLY);
namesService.createName(nameElement, when, username, holderStructures, subsystem);
}
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(subsystem, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.SUBSYSTEM, StructureCommand.CREATE, null, subsystem, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// update structure
// create audit
// previous for notification
// additional - update related names
// return
// structure element for updated structure
// notification
String uuid = structureElementCommand.getUuid().toString();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// update structure
// create audit
Subsystem subsystem = iSubsystemRepository.findByUuid(uuid);
subsystem.setMnemonic(mnemonic);
subsystem.setMnemonicEquivalence(equivalenceClassRepresentative);
subsystem.setOrdering(structureElementCommand.getOrdering());
subsystem.setDescription(structureElementCommand.getDescription());
subsystemRepository.updateSubsystem(subsystem);
AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, subsystem);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SUBSYSTEM.name().toLowerCase(), uuid, auditStructure.getAuditId());
Subsystem previous = new Subsystem(previousAuditStructure);
// additional
namesService.updateNames(previous, subsystem, username, holderStructures);
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(subsystem, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.SUBSYSTEM, StructureCommand.UPDATE, previous, subsystem, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// delete structure (update)
// create audit
// previous for notification
// additional
// delete related names
// return
// structure element for deleted structure
// notification
String uuid = structureElementCommand.getUuid().toString();
// delete structure
// create audit
Subsystem subsystem = iSubsystemRepository.findByUuid(uuid);
subsystem.setDeleted(Boolean.TRUE);
subsystem.setAttributesProcessed(when, username, null);
subsystemRepository.updateSubsystem(subsystem);
AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, subsystem);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SUBSYSTEM.name().toLowerCase(), uuid, auditStructure.getAuditId());
Subsystem previous = new Subsystem(previousAuditStructure);
// additional
namesService.deleteNames(subsystem, username, holderStructures);
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.COMMAND, StructureCommand.DELETE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(subsystem, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.SUBSYSTEM, StructureCommand.DELETE, previous, subsystem, holderStructures));
}
}
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.service;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IAuditStructureRepository;
import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.SystemGroupRepository;
import org.openepics.names.repository.model.AuditStructure;
import org.openepics.names.repository.model.System;
import org.openepics.names.repository.model.SystemGroup;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.Type;
import org.openepics.names.rest.beans.element.NameElementCommand;
import org.openepics.names.rest.beans.element.StructureElementCommand;
import org.openepics.names.util.EssNamingConvention;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.StructureChoice;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.StructureUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.notification.NotificationUtil;
import org.openepics.names.util.notification.StructureElementNotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;
/**
* This class provides structures services for system group.
*
* @author Lars Johansson
*/
@Service
public class SystemGroupService {
private static final Logger LOGGER = Logger.getLogger(SystemGroupService.class.getName());
private final NamesService namesService;
private final SystemService systemService;
private final ISystemGroupRepository iSystemGroupRepository;
private final ISystemRepository iSystemRepository;
private final IAuditStructureRepository iAuditStructureRepository;
private final SystemGroupRepository systemGroupRepository;
private final AuditStructureRepository auditStructureRepository;
@Autowired
public SystemGroupService(
NamesService namesService,
SystemService systemService,
ISystemGroupRepository iSystemGroupRepository,
ISystemRepository iSystemRepository,
IAuditStructureRepository iAuditStructureRepository,
SystemGroupRepository systemGroupRepository,
AuditStructureRepository auditStructureRepository) {
this.namesService = namesService;
this.systemService = systemService;
this.iSystemGroupRepository = iSystemGroupRepository;
this.iSystemRepository = iSystemRepository;
this.iAuditStructureRepository = iAuditStructureRepository;
this.systemGroupRepository = systemGroupRepository;
this.auditStructureRepository = auditStructureRepository;
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// create structure
// create audit
// additional
// automatically create name when system structure is created
// conditions on name and structure entry
// system structure should exist - mnemonic
// name should not exist - system structure mnemonic path
// return
// structure element for created structure
// notification
UUID uuid = UUID.randomUUID();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// create structure
// create audit
SystemGroup systemGroup = new SystemGroup(uuid,
mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
when, username, null);
systemGroupRepository.createSystemGroup(systemGroup);
auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, systemGroup));
// additional
boolean hasMnemonic = !StringUtils.isEmpty(systemGroup.getMnemonic());
boolean existsName = hasMnemonic && namesService.existsName(StructureUtil.getMnemonicPath(systemGroup, holderStructures));
if (hasMnemonic && !existsName) {
NameElementCommand nameElement = new NameElementCommand(null, systemGroup.getUuid(), null, null, StructuresService.SYSTEM_STRUCTURE_ONLY);
namesService.createName(nameElement, when, username, holderStructures, systemGroup);
}
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(systemGroup, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.SYSTEMGROUP, StructureCommand.CREATE, null, systemGroup, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
EssNamingConvention namingConvention, HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// update structure
// create audit
// previous for notification
// additional
// update related names
// return
// structure element for updated structure
// notification
String uuid = structureElementCommand.getUuid().toString();
String mnemonic = structureElementCommand.getMnemonic();
mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
// update structure
// create audit
SystemGroup systemGroup = iSystemGroupRepository.findByUuid(uuid);
systemGroup.setMnemonic(mnemonic);
systemGroup.setMnemonicEquivalence(equivalenceClassRepresentative);
systemGroup.setOrdering(structureElementCommand.getOrdering());
systemGroup.setDescription(structureElementCommand.getDescription());
systemGroupRepository.updateSystemGroup(systemGroup);
AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, systemGroup);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SYSTEMGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
SystemGroup previous = new SystemGroup(previousAuditStructure);
// additional
namesService.updateNames(previous, systemGroup, username, holderStructures);
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(systemGroup, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.SYSTEMGROUP, StructureCommand.UPDATE, previous, systemGroup, holderStructures));
}
@Transactional(propagation = Propagation.MANDATORY)
public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
HolderStructures holderStructures) {
// validation outside method
// transaction
// support a current transaction, throw an exception if none exists
// delete structure (update)
// create audit
// previous for notification
// additional
// delete related names
// delete sub structures (and related names)
// return
// structure element for deleted structure
// notification
String uuid = structureElementCommand.getUuid().toString();
// delete structure
// create audit
SystemGroup systemGroup = iSystemGroupRepository.findByUuid(uuid);
systemGroup.setDeleted(Boolean.TRUE);
systemGroup.setAttributesProcessed(when, username, null);
systemGroupRepository.updateSystemGroup(systemGroup);
AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, systemGroup);
auditStructureRepository.createAuditStructure(auditStructure);
// previous
AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SYSTEMGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
SystemGroup previous = new SystemGroup(previousAuditStructure);
// additional
// will propagate to sub structures
namesService.deleteNames(systemGroup, username, holderStructures);
List<StructureElementCommand> commands = Lists.newArrayList();
List<System> systems = iSystemRepository.findNotDeletedByParent(systemGroup.getId());
for (System system : systems) {
commands.add(new StructureElementCommand(system.getUuid(), Type.SYSTEM, null, null, null, null));
}
for (StructureElementCommand command : commands) {
systemService.deleteStructure(command, when, username, holderStructures);
}
LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.COMMAND, StructureCommand.DELETE));
return new StructureElementNotification(
StructureElementUtil.getStructureElementProcessed(systemGroup, holderStructures, StructureChoice.STRUCTURE),
NotificationUtil.prepareNotification(Type.SYSTEMGROUP, StructureCommand.DELETE, previous, systemGroup, holderStructures));
}
}