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 4531 additions and 1949 deletions
/*
* 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.rest.controller;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openepics.names.exception.ServiceException;
import org.openepics.names.rest.api.v1.IConvert;
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.Response;
import org.openepics.names.rest.beans.response.ResponseString;
import org.openepics.names.service.LogService;
import org.openepics.names.util.ExcelUtil;
import org.openepics.names.util.NameCommand;
import org.openepics.names.util.StructureCommand;
import org.openepics.names.util.TextUtil;
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.fasterxml.jackson.databind.ObjectMapper;
/**
* This part of REST API provides conversion of names and structures data from one format to another, e.g. Excel to Json, for Naming application.
*
* @author Lars Johansson
*/
@RestController
@EnableAutoConfiguration
public class ConvertController implements IConvert {
private static final Logger LOGGER = Logger.getLogger(ConvertController.class.getName());
private final LogService logService;
private final ObjectMapper mapper;
@Autowired
public ConvertController(
LogService logService) {
this.logService = logService;
this.mapper = new ObjectMapper();
}
@Override
public ResponseEntity<ResponseString> convertExcel2JsonNames(MultipartFile file) {
// convert from input
// ( convert )
// Excel according to template for names (NameElementCommand)
// rows are converted to array of name element commands (json)
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<NameElementCommand> commands = ExcelUtil.excelToNameElementCommands(file.getInputStream(), NameCommand.UPDATE);
return new ResponseEntity<>(new ResponseString(mapper.writeValueAsString(commands.toArray())), Response.getHeaderJson(), HttpStatus.OK);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logException(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponseEntity<ResponseString> convertExcel2JsonStructures(MultipartFile file) {
// convert from input
// ( convert )
// Excel according to template for structures (StructureElementCommand)
// rows are converted to array of structure element commands (json)
try {
if (ExcelUtil.hasExcelFormat(file)) {
List<StructureElementCommand> commands = ExcelUtil.excelToStructureElementCommands(file.getInputStream(), StructureCommand.UPDATE);
return new ResponseEntity<>(new ResponseString(mapper.writeValueAsString(commands.toArray())), Response.getHeaderJson(), HttpStatus.OK);
} else {
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
}
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e;
} catch (IOException e) {
logService.logException(LOGGER, Level.WARNING, e);
throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
} catch (Exception e) {
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
// ----------------------------------------------------------------------------------------------------
@Override
public ResponseEntity<Resource> convertJson2ExcelNames(List<NameElement> nameElements) {
// convert from input
// ( convert )
// json according to array of name elements (NameElement)
try {
InputStreamResource isr = new InputStreamResource(ExcelUtil.nameElementsToExcel(nameElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, TextUtil.ATTACHMENT_FILENAME_NAME_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
@Override
public ResponseEntity<Resource> convertJson2ExcelStructures(List<StructureElement> structureElements) {
// convert from input
// ( convert )
// json according to array of structure elements (StructureElement)
try {
InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, TextUtil.ATTACHMENT_FILENAME_STRUCTURE_ELEMENT_XLSX)
.contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
.body(isr);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e;
} catch (Exception e) {
logService.logException(LOGGER, Level.WARNING, e);
throw e;
}
}
}
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
package org.openepics.names.rest.controller; package org.openepics.names.rest.controller;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
...@@ -46,34 +45,34 @@ import io.swagger.v3.oas.annotations.tags.Tag; ...@@ -46,34 +45,34 @@ import io.swagger.v3.oas.annotations.tags.Tag;
@EnableAutoConfiguration @EnableAutoConfiguration
public class HealthcheckController { public class HealthcheckController {
// note // methods
// global exception handler available // read GET /healthcheck - readHealthcheck()
/*
Methods
read GET /healthcheck - readHealthcheck()
*/
/** /**
* Perform healthcheck for Naming application in general and healtcheck endpoint in particular. * Perform healthcheck for Naming application.
* To be used mainly for checking HTTP response code, in particular HTTP STATUS OK - 200. * To be used mainly for checking HTTP response code, in particular HTTP STATUS OK - 200.
* *
* @return server timestamp * @return server timestamp
*/ */
@Operation( @Operation(
summary = "Perform healthcheck for Naming application in general and healtcheck endpoint in particular", summary = "Perform healthcheck for Naming application",
description = "Perform healthcheck for Naming application in general and healtcheck endpoint in particular. " description = """
+ "To be used mainly for checking HTTP response code, in particular HTTP STATUS OK - 200." Perform healthcheck for Naming application.
) To be used mainly for checking HTTP response code, in particular HTTP STATUS OK - 200.
""")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Method completed OK. Return healthcheck as server timestamp.", content = @Content(mediaType = "text/plain", schema = @Schema(implementation = String.class))) @ApiResponse(
responseCode = "200",
description = "Method completed OK. Return healthcheck as server timestamp.",
content = @Content(mediaType = "text/plain", schema = @Schema(implementation = String.class)))
}) })
@GetMapping @GetMapping(
public String readHealthcheck() { produces = {"text/plain"})
public String healthcheck() {
// return healthcheck as server timestamp // return healthcheck as server timestamp
// datetime - dateStyle, timeStyle - full // datetime - dateStyle, timeStyle - full
return SimpleDateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()); return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date());
} }
} }
...@@ -22,16 +22,26 @@ import java.util.List; ...@@ -22,16 +22,26 @@ import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.openepics.names.exception.ServiceException;
import org.openepics.names.rest.api.v1.INames; import org.openepics.names.rest.api.v1.INames;
import org.openepics.names.rest.beans.FieldName; import org.openepics.names.rest.beans.FieldName;
import org.openepics.names.rest.beans.NameElement; import org.openepics.names.rest.beans.element.NameElement;
import org.openepics.names.rest.beans.element.NameElementCommand;
import org.openepics.names.rest.beans.element.NameElementCommandConfirm;
import org.openepics.names.rest.beans.element.NameElementCommandCreate;
import org.openepics.names.rest.beans.element.NameElementCommandUpdate;
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.ResponsePageNameElements;
import org.openepics.names.service.LogService;
import org.openepics.names.service.NamesService; import org.openepics.names.service.NamesService;
import org.openepics.names.util.ExceptionUtil; import org.openepics.names.service.security.dto.UserDetails;
import org.openepics.names.util.LogUtil; import org.openepics.names.service.security.util.SecurityUtil;
import org.openepics.names.util.ServiceHttpStatusException; import org.openepics.names.util.NameElementUtil;
import org.openepics.names.util.response.Response; import org.openepics.names.util.TextUtil;
import org.openepics.names.util.response.ResponseBoolean; import org.openepics.names.util.ValidateNameElementUtil;
import org.openepics.names.util.response.ResponseBooleanList; import org.openepics.names.util.ValidateUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -50,35 +60,40 @@ import com.google.common.collect.Lists; ...@@ -50,35 +60,40 @@ import com.google.common.collect.Lists;
public class NamesController implements INames { public class NamesController implements INames {
// note // note
// global exception handler available // 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(NamesController.class.getName()); private static final Logger LOGGER = Logger.getLogger(NamesController.class.getName());
private NamesService namesService; private final LogService logService;
private final NamesService namesService;
@Autowired @Autowired
public NamesController( public NamesController(
LogService logService,
NamesService namesService) { NamesService namesService) {
this.logService = logService;
this.namesService = namesService; this.namesService = namesService;
} }
@Override @Override
public List<NameElement> createNames(List<NameElement> nameElements) { public ResponseEntity<List<NameElement>> createNames(UserDetails user,
// validate authority List<NameElementCommandCreate> nameElementCommands) {
// naming user & admin // validate authority - user & admin
// convert
// validate // validate
// do // create names
try { try {
namesService.validateNamesCreate(nameElements); List<NameElementCommand> commands = NameElementUtil.convertCommandCreate2Command(nameElementCommands);
return namesService.createNames(nameElements); namesService.validateNamesCreate(commands);
} catch (ServiceHttpStatusException e) { return new ResponseEntity<>(namesService.createNames(commands, SecurityUtil.getUsername(user)), Response.getHeaderJson(), HttpStatus.CREATED);
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
...@@ -86,265 +101,270 @@ public class NamesController implements INames { ...@@ -86,265 +101,270 @@ public class NamesController implements INames {
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public List<NameElement> readNames( public ResponsePageNameElements readNames(Boolean deleted,
Boolean deleted, FieldName[] queryFields, String[] queryValues, String name, String systemStructure, String deviceStructure, String index, String description, String who,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { FieldName orderBy, Boolean isAsc, Integer page, Integer pageSize) {
try { // validate
return namesService.readNames( // read names
deleted, queryFields, queryValues,
orderBy, isAsc, offset, limit);
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
}
}
@Override
public List<NameElement> readNames(
String name,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
try { try {
return namesService.readNames(name, orderBy, isAsc, offset, limit); ValidateNameElementUtil.validateNamesInputRead(
} catch (ServiceHttpStatusException e) { deleted,
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); null, name, systemStructure, deviceStructure, index, description, who,
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); null,
orderBy, isAsc,
page, pageSize);
return namesService.readNames(deleted,
null, name, systemStructure, deviceStructure, index, description, who,
orderBy, isAsc, page, pageSize);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
@Override @Override
public List<NameElement> readNamesSystemStructure( public ResponseEntity<ResponsePageNameElements> readName(String uuid) {
String mnemonicpath, // validate
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { // read name
try { try {
return namesService.readNamesSystemStructure(mnemonicpath, orderBy, isAsc, offset, limit); // use offset, limit
} catch (ServiceHttpStatusException e) { // have limit for size of search result
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); ValidateUtil.validateInputUuid(uuid);
ResponsePageNameElements nameElements = namesService.readNames(null,
uuid, null, null, null, null, null, null,
null, null, Integer.valueOf(INames.DEFAULT_PAGE), Integer.valueOf(INames.DEFAULT_PAGE_SIZE));
HttpStatus status = null;
if (nameElements.getListSize() == 0) {
status = HttpStatus.NOT_FOUND;
} else {
status = HttpStatus.OK;
}
return new ResponseEntity<>(nameElements, Response.getHeaderJson(), status);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
@Override @Override
public List<NameElement> readNamesDeviceStructure( public ResponseEntity<ResponsePageNameElements> readNamesStructure(String uuid, Boolean deleted,
String mnemonicpath, FieldName orderBy, Boolean isAsc, Integer page, Integer pageSize) {
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { // validate
// read names
try { try {
return namesService.readNamesDeviceStructure(mnemonicpath, orderBy, isAsc, offset, limit); ValidateUtil.validateInputUuid(uuid);
} catch (ServiceHttpStatusException e) { ResponsePageNameElements nameElements = namesService.readNamesStructure(uuid, deleted,
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); orderBy, isAsc, page, pageSize);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
HttpStatus status = null;
if (nameElements.getListSize() == 0) {
status = HttpStatus.NOT_FOUND;
} else {
status = HttpStatus.OK;
}
return new ResponseEntity<>(nameElements, Response.getHeaderJson(), status);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
@Override @Override
public List<NameElement> readNamesHistory( public ResponseEntity<ResponsePageNameElements> readNamesHistory(String uuid) {
String uuid, // validate
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { // read names
try { try {
return namesService.readNamesHistory(uuid, orderBy, isAsc, offset, limit); ValidateUtil.validateInputUuid(uuid);
} catch (ServiceHttpStatusException e) { ResponsePageNameElements nameElements = namesService.readNamesHistory(uuid,
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); Integer.valueOf(INames.DEFAULT_PAGE), Integer.valueOf(INames.DEFAULT_PAGE_SIZE));
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
HttpStatus status = null;
if (nameElements.getListSize() == 0) {
status = HttpStatus.NOT_FOUND;
} else {
status = HttpStatus.OK;
}
return new ResponseEntity<>(nameElements, Response.getHeaderJson(), status);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override
public String equivalenceName(String name) {
try {
return namesService.equivalenceName(name);
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
}
}
@Override @Override
public ResponseEntity<ResponseBoolean> existsName(String name) { public ResponseEntity<ResponseBoolean> existsName(String name) {
try { // validate
return new ResponseEntity<>(new ResponseBoolean(namesService.existsName(name)), Response.HEADER_JSON, HttpStatus.OK); // read names
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK);
}
}
@Override
public ResponseEntity<ResponseBoolean> isLegacyName(String name) {
try { try {
return new ResponseEntity<>(new ResponseBoolean(namesService.isLegacyName(name)), Response.HEADER_JSON, HttpStatus.OK); ValidateUtil.validateInputName(name);
} catch (ServiceHttpStatusException e) { return new ResponseEntity<>(new ResponseBoolean(namesService.existsName(name)), Response.getHeaderJson(), HttpStatus.OK);
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()), Response.getHeaderJson(), HttpStatus.OK);
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.getHeaderJson(), HttpStatus.OK);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK);
} }
} }
@Override @Override
public ResponseEntity<ResponseBoolean> isValidToCreateName(String name) { public ResponseEntity<ResponseBoolean> isValidToCreateName(String name) {
// validate
// read names
try { try {
return new ResponseEntity<>(new ResponseBoolean(namesService.isValidToCreateName(name)), Response.HEADER_JSON, HttpStatus.OK); ValidateUtil.validateInputName(name);
} catch (ServiceHttpStatusException e) { return new ResponseEntity<>(new ResponseBoolean(namesService.isValidToCreateName(name)), Response.getHeaderJson(), HttpStatus.OK);
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()), Response.getHeaderJson(), HttpStatus.OK);
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.getHeaderJson(), HttpStatus.OK);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK);
} }
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public ResponseEntity<ResponseBooleanList> validateNamesCreate(List<NameElement> nameElements) { public ResponseEntity<ResponseBooleanList> validateNamesCreate(List<NameElementCommandCreate> nameElementCommands) {
// convert
// validate
List<NameElementCommand> commands = NameElementUtil.convertCommandCreate2Command(nameElementCommands);
boolean response = true; boolean response = true;
String reason = ""; String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList(); List<ResponseBoolean> responses = Lists.newArrayList();
for (NameElement nameElement : nameElements) { for (NameElementCommand command : commands) {
try { try {
namesService.validateNamesCreate(nameElement); namesService.validateNamesCreate(command);
responses.add(new ResponseBoolean(Boolean.TRUE)); responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) { } catch (ServiceException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
} }
} }
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
} }
@Override @Override
public ResponseEntity<ResponseBooleanList> validateNamesUpdate(List<NameElement> nameElements) { public ResponseEntity<ResponseBooleanList> validateNamesUpdate(List<NameElementCommandUpdate> nameElementCommands) {
// convert
// validate
List<NameElementCommand> commands = NameElementUtil.convertCommandUpdate2Command(nameElementCommands);
boolean response = true; boolean response = true;
String reason = ""; String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList(); List<ResponseBoolean> responses = Lists.newArrayList();
for (NameElement nameElement : nameElements) { for (NameElementCommand command : commands) {
try { try {
namesService.validateNamesUpdate(nameElement); namesService.validateNamesUpdate(command);
responses.add(new ResponseBoolean(Boolean.TRUE)); responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) { } catch (ServiceException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
} }
} }
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
} }
@Override @Override
public ResponseEntity<ResponseBooleanList> validateNamesDelete(List<NameElement> nameElements) { public ResponseEntity<ResponseBooleanList> validateNamesDelete(List<NameElementCommandConfirm> nameElementCommands) {
// convert
// validate
List<NameElementCommand> commands = NameElementUtil.convertCommandConfirm2Command(nameElementCommands);
boolean response = true; boolean response = true;
String reason = ""; String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList(); List<ResponseBoolean> responses = Lists.newArrayList();
for (NameElement nameElement : nameElements) { for (NameElementCommand command : commands) {
try { try {
namesService.validateNamesDelete(nameElement); namesService.validateNamesDelete(command);
responses.add(new ResponseBoolean(Boolean.TRUE)); responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) { } catch (ServiceException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
} }
} }
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public List<NameElement> updateNames(List<NameElement> nameElements) { public List<NameElement> updateNames(UserDetails user,
// validate authority List<NameElementCommandUpdate> nameElementCommands) {
// naming user & admin // validate authority - user & admin
// convert
// validate // validate
// do // update names
try { try {
namesService.validateNamesUpdate(nameElements); List<NameElementCommand> commands = NameElementUtil.convertCommandUpdate2Command(nameElementCommands);
return namesService.updateNames(nameElements); namesService.validateNamesUpdate(commands);
} catch (ServiceHttpStatusException e) { return namesService.updateNames(commands, SecurityUtil.getUsername(user));
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
...@@ -352,24 +372,25 @@ public class NamesController implements INames { ...@@ -352,24 +372,25 @@ public class NamesController implements INames {
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public List<NameElement> deleteNames(List<NameElement> nameElements) { public ResponseEntity<Response> deleteNames(UserDetails user,
// validate authority List<NameElementCommandConfirm> nameElementCommands) {
// naming user & admin // validate authority - user & admin
// convert
// validate // validate
// do // delete names
try { try {
namesService.validateNamesDelete(nameElements); List<NameElementCommand> commands = NameElementUtil.convertCommandConfirm2Command(nameElementCommands);
return namesService.deleteNames(nameElements); namesService.validateNamesDelete(commands);
} catch (ServiceHttpStatusException e) { namesService.deleteNames(commands, SecurityUtil.getUsername(user));
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(HttpStatus.NO_CONTENT);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
} }
\ No newline at end of file
/*
* 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);
}
}
/*
* Copyright (C) 2022 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 java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
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;
import org.openepics.names.rest.beans.element.StructureElement;
import org.openepics.names.rest.beans.response.ResponsePageNameElements;
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.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;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
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
@RequestMapping("/report")
@EnableAutoConfiguration
public class ReportController {
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;
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_DELETED = "# deleted: ";
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 final NamesService namesService;
private final StructuresService structuresService;
private final HolderWipRepositories holderWipRepositories;
@Autowired
public ReportController(
NamesService namesService,
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);
}
/**
* Return report about Naming.
*
* @return report about Naming (text)
*/
@Operation(
summary = "About Naming",
description = """
About Naming.
Return report about Naming (text).
Content
- Metrics for Naming
1) Overview
2) ESS names
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).",
content = @Content(mediaType = "text/plain", schema = @Schema(implementation = String.class)))
})
@GetMapping(
path = {"/about"},
produces = {"text/plain"})
public String reportAbout() {
// report metrics about Naming
// 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);
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 + 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_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_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_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_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_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_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(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)
.append(" 2) # entries - ESS names").append(NEWLINE)
.append(" 3) # entries - System structure").append(NEWLINE)
.append(" 4) # entries - Device structure").append(NEWLINE)
.append(" 5) Device structure - P&ID Disciplines").append(NEWLINE)
.append(DIVIDER_128).append(NEWLINE);
// report overview
// report ess names
// report system structure
// report device structure
// report device structure - p&id discipline
sb.append("1) # entries - Overview").append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
sb.append("ESS Name " + metricsOverviewEssName).append(NEWLINE);
sb.append("System Group " + metricsOverviewSystemGroup).append(NEWLINE);
sb.append("System " + metricsOverviewSystem).append(NEWLINE);
sb.append("Subsystem " + metricsOverviewSubsystem).append(NEWLINE);
sb.append("Discipline " + metricsOverviewDiscipline).append(NEWLINE);
sb.append("Device Group " + metricsOverviewDeviceGroup).append(NEWLINE);
sb.append("Device Type " + metricsOverviewDeviceType).append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
sb.append("2) # entries - ESS names").append(NEWLINE);
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_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);
// lifecycle (# active, # deleted, # pending, ...
sb.append("System Group " + metricsSystemstructureSystemGroup).append(NEWLINE);
sb.append("System " + metricsSystemstructureSystem).append(NEWLINE);
sb.append("Subsystem " + metricsSystemstructureSubsystem).append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
sb.append("4) # entries - Device structure").append(NEWLINE);
sb.append(DIVIDER_96).append(NEWLINE);
// lifecycle (# active, # deleted, # pending, ...
sb.append("Discipline " + metricsDevicestructureDiscipline).append(NEWLINE);
sb.append("Device Group " + metricsDevicestructureDeviceGroup).append(NEWLINE);
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);
// 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);
}
return sb.toString();
}
/**
* 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);
}
/**
* 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;
}
}
}
...@@ -22,18 +22,27 @@ import java.util.List; ...@@ -22,18 +22,27 @@ import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.openepics.names.exception.ServiceException;
import org.openepics.names.rest.api.v1.IStructures; import org.openepics.names.rest.api.v1.IStructures;
import org.openepics.names.rest.beans.FieldStructure; import org.openepics.names.rest.beans.FieldStructure;
import org.openepics.names.rest.beans.Status;
import org.openepics.names.rest.beans.StructureElement;
import org.openepics.names.rest.beans.Type; 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.service.StructuresService;
import org.openepics.names.util.ExceptionUtil; import org.openepics.names.service.security.dto.UserDetails;
import org.openepics.names.util.LogUtil; import org.openepics.names.service.security.util.SecurityUtil;
import org.openepics.names.util.ServiceHttpStatusException; import org.openepics.names.util.StructureElementUtil;
import org.openepics.names.util.response.Response; import org.openepics.names.util.TextUtil;
import org.openepics.names.util.response.ResponseBoolean; import org.openepics.names.util.ValidateStructureElementUtil;
import org.openepics.names.util.response.ResponseBooleanList; import org.openepics.names.util.ValidateUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -52,42 +61,40 @@ import com.google.common.collect.Lists; ...@@ -52,42 +61,40 @@ import com.google.common.collect.Lists;
public class StructuresController implements IStructures { public class StructuresController implements IStructures {
// note // note
// global exception handler available // controller layer to call validation prior to invoking service layer
// business logic may be validation
// TODO validate authority // different kinds of validation
// either
// no or
// naming user
// naming admin
// naming user & admin
private static final Logger LOGGER = Logger.getLogger(StructuresController.class.getName()); private static final Logger LOGGER = Logger.getLogger(StructuresController.class.getName());
private StructuresService structuresService; private final LogService logService;
private final StructuresService structuresService;
@Autowired @Autowired
public StructuresController( public StructuresController(
LogService logService,
StructuresService structuresService) { StructuresService structuresService) {
this.logService = logService;
this.structuresService = structuresService; this.structuresService = structuresService;
} }
@Override @Override
public List<StructureElement> createStructures(List<StructureElement> structureElements) { public ResponseEntity<List<StructureElement>> createStructures(UserDetails user,
// validate authority List<StructureElementCommandCreate> structureElementCommands) {
// naming user & admin // validate authority - user & admin
// convert
// validate // validate
// do // create structures
try { try {
structuresService.validateStructuresCreate(structureElements); List<StructureElementCommand> commands = StructureElementUtil.convertCommandCreate2Command(structureElementCommands);
return structuresService.createStructures(structureElements); structuresService.validateStructuresCreate(commands);
} catch (ServiceHttpStatusException e) { return new ResponseEntity<>(structuresService.createStructures(commands, SecurityUtil.getUsername(user)), Response.getHeaderJson(), HttpStatus.CREATED);
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
...@@ -95,92 +102,111 @@ public class StructuresController implements IStructures { ...@@ -95,92 +102,111 @@ public class StructuresController implements IStructures {
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public List<StructureElement> readStructures( public ResponsePageStructureElements readStructures(Type type, Boolean deleted,
Type type, Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, String parent, String mnemonic, String mnemonicPath, String description, String who,
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
try { // validate
return structuresService.readStructures( // read structures
type, statuses, deleted, queryFields, queryValues,
orderBy, isAsc, offset, limit);
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
}
}
@Override
public List<StructureElement> readStructuresChildren(
Type type, String uuid,
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
try { try {
return structuresService.readStructuresChildren( ValidateStructureElementUtil.validateStructuresInputRead(type, deleted,
type, uuid, null, parent, mnemonic, mnemonicPath, description, who,
orderBy, isAsc, offset, limit); null, orderBy, isAsc, page, pageSize);
} catch (ServiceHttpStatusException e) { return structuresService.readStructures(type, deleted,
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); null, parent, mnemonic, mnemonicPath, description, who,
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); orderBy, isAsc, page, pageSize);
} catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
@Override @Override
public List<StructureElement> readStructuresMnemonic( public ResponseEntity<ResponsePageStructureElements> readStructure(String uuid) {
String mnemonic, // validate
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { // read structure
try { try {
return structuresService.readStructuresMnemonic(mnemonic, orderBy, isAsc, offset, limit); // use offset, limit
} catch (ServiceHttpStatusException e) { // have limit for size of search result
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); 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);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
@Override @Override
public List<StructureElement> readStructuresMnemonicpath( public ResponseEntity<ResponsePageStructureElements> readStructuresChildren(String uuid, Boolean deleted,
String mnemonicpath, FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { // validate
// read structures
try { try {
return structuresService.readStructuresMnemonicpath(mnemonicpath, orderBy, isAsc, offset, limit); ValidateUtil.validateInputUuid(uuid);
} catch (ServiceHttpStatusException e) { ResponsePageStructureElements structureElements = structuresService.readStructuresChildren(uuid, deleted,
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); orderBy, isAsc, page, pageSize);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
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.logException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
@Override @Override
public List<StructureElement> readStructuresHistory( public ResponseEntity<ResponsePageStructureElements> readStructuresHistory(String uuid) {
String uuid, Type type, // validate
FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { // read structures
try { try {
return structuresService.readStructuresHistory( ValidateUtil.validateInputUuid(uuid);
uuid, type, ResponsePageStructureElements structureElements = structuresService.readStructuresHistory(uuid,
orderBy, isAsc, offset, limit); Integer.valueOf(IStructures.DEFAULT_PAGE), Integer.valueOf(IStructures.DEFAULT_PAGE_SIZE));
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); HttpStatus status = null;
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); 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);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
...@@ -188,265 +214,158 @@ public class StructuresController implements IStructures { ...@@ -188,265 +214,158 @@ public class StructuresController implements IStructures {
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public String equivalenceMnemonic(String mnemonic) { public ResponseEntity<ResponseBoolean> existsStructure(Type type, String mnemonicPath) {
try { // validate
return structuresService.equivalenceMnemonic(mnemonic); // read structures
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
}
}
@Override
public ResponseEntity<ResponseBoolean> existsStructure(Type type, String mnemonic) {
try { try {
return new ResponseEntity<>(new ResponseBoolean(structuresService.existsStructure(type, mnemonic)), Response.HEADER_JSON, HttpStatus.OK); ValidateUtil.validateInputType(type);
} catch (ServiceHttpStatusException e) { ValidateUtil.validateInputMnemonicPath(mnemonicPath);
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(new ResponseBoolean(structuresService.existsStructure(type, mnemonicPath)), Response.getHeaderJson(), HttpStatus.OK);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); logService.logServiceException(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()), Response.getHeaderJson(), HttpStatus.OK);
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.getHeaderJson(), HttpStatus.OK);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK);
} }
} }
@Override @Override
public ResponseEntity<ResponseBoolean> isValidToCreateStructure(Type type, String mnemonicpath) { public ResponseEntity<ResponseBoolean> isValidToCreateStructure(Type type, String mnemonicPath) {
// validate
// read structures
try { try {
return new ResponseEntity<>(new ResponseBoolean(structuresService.isValidToCreateStructure(type, mnemonicpath)), Response.HEADER_JSON, HttpStatus.OK); ValidateUtil.validateInputType(type);
} catch (ServiceHttpStatusException e) { ValidateUtil.validateInputMnemonicPath(mnemonicPath);
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(new ResponseBoolean(structuresService.isValidToCreateStructure(type, mnemonicPath)), Response.getHeaderJson(), HttpStatus.OK);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); logService.logServiceException(LOGGER, Level.WARNING, e);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()), Response.getHeaderJson(), HttpStatus.OK);
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.getHeaderJson(), HttpStatus.OK);
return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK);
} }
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public ResponseEntity<ResponseBooleanList> validateStructuresCreate(List<StructureElement> structureElements) { public ResponseEntity<ResponseBooleanList> validateStructuresCreate(List<StructureElementCommandCreate> structureElementCommands) {
boolean response = true; // convert
String reason = ""; // validate
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElement structureElement : structureElements) {
try {
structuresService.validateStructuresCreate(structureElement);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) {
response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()));
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) {
response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED));
}
}
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK);
}
@Override List<StructureElementCommand> commands = StructureElementUtil.convertCommandCreate2Command(structureElementCommands);
public ResponseEntity<ResponseBooleanList> validateStructuresUpdate(List<StructureElement> structureElements) {
boolean response = true; boolean response = true;
String reason = ""; String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList(); List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElement structureElement : structureElements) { for (StructureElementCommand command : commands) {
try { try {
structuresService.validateStructuresUpdate(structureElement); structuresService.validateStructuresCreate(command);
responses.add(new ResponseBoolean(Boolean.TRUE)); responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) { } catch (ServiceException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
} }
} }
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
} }
@Override @Override
public ResponseEntity<ResponseBooleanList> validateStructuresDelete(List<StructureElement> structureElements) { public ResponseEntity<ResponseBooleanList> validateStructuresUpdate(List<StructureElementCommandUpdate> structureElementCommands) {
boolean response = true; // convert
String reason = ""; // validate
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElement structureElement : structureElements) {
try {
structuresService.validateStructuresDelete(structureElement);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) {
response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()));
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) {
response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED));
}
}
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK);
}
@Override List<StructureElementCommand> commands = StructureElementUtil.convertCommandUpdate2Command(structureElementCommands);
public ResponseEntity<ResponseBooleanList> validateStructuresApprove(List<StructureElement> structureElements) {
boolean response = true; boolean response = true;
String reason = ""; String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList(); List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElement structureElement : structureElements) { for (StructureElementCommand command : commands) {
try { try {
structuresService.validateStructuresApprove(structureElement); structuresService.validateStructuresUpdate(command);
responses.add(new ResponseBoolean(Boolean.TRUE)); responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) { } catch (ServiceException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
} }
} }
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
} }
@Override @Override
public ResponseEntity<ResponseBooleanList> validateStructuresCancel(List<StructureElement> structureElements) { public ResponseEntity<ResponseBooleanList> validateStructuresDelete(List<StructureElementCommandConfirm> structureElementCommands) {
boolean response = true; // convert
String reason = ""; // validate
List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElement structureElement : structureElements) {
try {
structuresService.validateStructuresCancel(structureElement);
responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) {
response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()));
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) {
response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
}
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED));
}
}
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK);
}
@Override List<StructureElementCommand> commands = StructureElementUtil.convertCommandConfirm2Command(structureElementCommands);
public ResponseEntity<ResponseBooleanList> validateStructuresReject(List<StructureElement> structureElements) {
boolean response = true; boolean response = true;
String reason = ""; String reason = "";
List<ResponseBoolean> responses = Lists.newArrayList(); List<ResponseBoolean> responses = Lists.newArrayList();
for (StructureElement structureElement : structureElements) { for (StructureElementCommand command : commands) {
try { try {
structuresService.validateStructuresReject(structureElement); structuresService.validateStructuresDelete(command);
responses.add(new ResponseBoolean(Boolean.TRUE)); responses.add(new ResponseBoolean(Boolean.TRUE));
} catch (ServiceHttpStatusException e) { } catch (ServiceException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails(), e.getField()));
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
if (response) { if (response) {
response = false; response = false;
reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; reason = TextUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT;
} }
responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); responses.add(new ResponseBoolean(Boolean.FALSE, TextUtil.OPERATION_COULD_NOT_BE_PERFORMED));
} }
} }
return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.getHeaderJson(), HttpStatus.OK);
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public List<StructureElement> updateStructures(List<StructureElement> structureElements) { public List<StructureElement> updateStructures(UserDetails user,
try { List<StructureElementCommandUpdate> structureElementCommands) {
structuresService.validateStructuresUpdate(structureElements); // validate authority - user & admin
return structuresService.updateStructures(structureElements); // convert
} catch (ServiceHttpStatusException e) { // validate
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); // update structures
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
}
}
// ----------------------------------------------------------------------------------------------------
@Override
public List<StructureElement> deleteStructures(List<StructureElement> structureElements) {
try { try {
structuresService.validateStructuresDelete(structureElements); List<StructureElementCommand> commands = StructureElementUtil.convertCommandUpdate2Command(structureElementCommands);
return structuresService.deleteStructures(structureElements); structuresService.validateStructuresUpdate(commands);
} catch (ServiceHttpStatusException e) { return structuresService.updateStructures(commands, SecurityUtil.getUsername(user));
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
...@@ -454,49 +373,23 @@ public class StructuresController implements IStructures { ...@@ -454,49 +373,23 @@ public class StructuresController implements IStructures {
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Override @Override
public List<StructureElement> approveStructures(List<StructureElement> structureElements) { public ResponseEntity<Response> deleteStructures(UserDetails user,
try { List<StructureElementCommandConfirm> structureElementCommands) {
structuresService.validateStructuresApprove(structureElements); // validate authority - user & admin
return structuresService.approveStructures(structureElements); // convert
} catch (ServiceHttpStatusException e) { // validate
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); // delete structures
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
}
}
@Override
public List<StructureElement> cancelStructures(List<StructureElement> structureElements) {
try {
structuresService.validateStructuresCancel(structureElements);
return structuresService.cancelStructures(structureElements);
} catch (ServiceHttpStatusException e) {
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage());
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e;
}
}
@Override
public List<StructureElement> rejectStructures(List<StructureElement> structureElements) {
try { try {
structuresService.validateStructuresReject(structureElements); List<StructureElementCommand> commands = StructureElementUtil.convertCommandConfirm2Command(structureElementCommands);
return structuresService.rejectStructures(structureElements); structuresService.validateStructuresDelete(commands);
} catch (ServiceHttpStatusException e) { structuresService.deleteStructures(commands, SecurityUtil.getUsername(user));
LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); return new ResponseEntity<>(HttpStatus.NO_CONTENT);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); } catch (ServiceException e) {
logService.logServiceException(LOGGER, Level.WARNING, e);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage()); logService.logException(LOGGER, Level.WARNING, e);
LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
throw e; throw e;
} }
} }
......
...@@ -18,24 +18,31 @@ ...@@ -18,24 +18,31 @@
package org.openepics.names.rest.controller; package org.openepics.names.rest.controller;
import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Optional;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openepics.names.old.model.DeviceRevision; import org.openepics.names.old.model.DeviceRevision;
import org.openepics.names.old.model.NamePartRevision; import org.openepics.names.old.model.NamePartRevision;
import org.openepics.names.old.model.NamePartRevisionStatus; import org.openepics.names.old.model.NamePartRevisionStatus;
import org.openepics.names.old.nameviews.NameViewProvider; 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.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository; import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository; import org.openepics.names.repository.IDisciplineRepository;
...@@ -43,16 +50,37 @@ import org.openepics.names.repository.INameRepository; ...@@ -43,16 +50,37 @@ import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository; import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository; import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository; import org.openepics.names.repository.ISystemRepository;
import org.openepics.names.repository.model.DeviceGroup; import org.openepics.names.repository.AuditNameRepository;
import org.openepics.names.repository.model.DeviceType; import org.openepics.names.repository.AuditStructureRepository;
import org.openepics.names.repository.model.Discipline; import org.openepics.names.repository.DeviceGroupRepository;
import org.openepics.names.repository.model.Name; import org.openepics.names.repository.DeviceTypeRepository;
import org.openepics.names.repository.model.Subsystem; import org.openepics.names.repository.DisciplineRepository;
import org.openepics.names.repository.model.System; import org.openepics.names.repository.NameRepository;
import org.openepics.names.repository.model.SystemGroup; 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.IDeviceRevisionRepository;
import org.openepics.names.repository.old.INamePartRevisionRepository; 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.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.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -64,15 +92,66 @@ import io.swagger.v3.oas.annotations.Hidden; ...@@ -64,15 +92,66 @@ import io.swagger.v3.oas.annotations.Hidden;
/** /**
* This part of REST API provides verification of data migration for Naming application. * 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> * <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> * </ul>
* *
* <p> * <p>
* Ideally, some knowledge of database tables and object structures acquired to dig into this class. * 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 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 * @author Lars Johansson
*/ */
...@@ -82,304 +161,192 @@ import io.swagger.v3.oas.annotations.Hidden; ...@@ -82,304 +161,192 @@ import io.swagger.v3.oas.annotations.Hidden;
@EnableAutoConfiguration @EnableAutoConfiguration
public class VerificationController { public class VerificationController {
// note // methods
// global exception handler available // read GET /verification/migration_namepartrevision - readMigrationStructures
// read GET /verification/migration_devicerevision - readMigrationNames
/* // read GET /verification/data_reachable - readDataReachable
Methods // read GET /verification/restapi_oldvsnew - readRestApiOldVsNew
read GET /verification/migration_devicerevision - readMigrationDeviceRevision()
read GET /verification/migration_namepartrevision - readMigrationNamePartRevision
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 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 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 private final HolderIWipRepositories holderIWipRepositories;
IDeviceRevisionRepository deviceRevisionRepository; private final HolderIRepositories holderIRepositories;
@Autowired private final HolderRepositories holderRepositories;
INamePartRevisionRepository namePartRevisionRepository;
@Autowired @Autowired
public VerificationController( public VerificationController(
INameRepository nameRepository, IDeviceRevisionRepository deviceRevisionRepository,
ISystemGroupRepository systemGroupRepository, INamePartRevisionRepository namePartRevisionRepository,
ISystemRepository systemRepository, IWipNameRepository iWipNameRepository,
ISubsystemRepository subsystemRepository, IWipSystemGroupRepository iWipSystemGroupRepository,
IDisciplineRepository disciplineRepository, IWipSystemRepository iWipSystemRepository,
IDeviceGroupRepository deviceGroupRepository, IWipSubsystemRepository iWipSubsystemRepository,
IDeviceTypeRepository deviceTypeRepository) { IWipDisciplineRepository iWipDisciplineRepository,
IWipDeviceGroupRepository iWipDeviceGroupRepository,
holderIRepositories = new HolderIRepositories( 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, nameRepository,
systemGroupRepository, systemGroupRepository,
systemRepository, systemRepository,
subsystemRepository, subsystemRepository,
disciplineRepository, disciplineRepository,
deviceGroupRepository, 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. * Ok if all entries ok and no entry nok.
* *
* @return report of data migration * @return report of data migration
*/ */
@GetMapping("/migration_devicerevision") @GetMapping(
public String readMigrationDeviceRevision() { path = {"/migration_structures"},
// verification of produces = {"text/plain"})
// name vs. devicerevision, device public String verifyMigrationStructures() {
// with help of namepartrevision, namepart // about
// verification of structures (after) vs. name parts (before)
// note
// check entry by entry // how
// ---------- // find data for verification
// to check 1st, 2nd, 3rd parent to determine if systemgroup, system or subsystem // structures - systemgroup, system, subsystem, discipline, devicegroup, devicetype
// otherwise not clear how to make sure if it is supposed to be systemgroup and not system, subsystem and vice versa // name parts - namepartrevision, namepart
// ---------- // utility
// date may be in different format for different objects, to be formatted before being compared // interpret data into hashmaps for faster retrieval in checks
// ---------- // check
// name.id = devicerevision.id // for each entry in each structure
// name.version = devicerevision.version // check entry by entry
// name.uuid = devicerevision.device_id (device.id --> device.uuid) // each attribute as expected
// name.namepartrevision_systemgroup_uuid = devicerevision.section_id (namepart.id --> namepart.uuid // ok if
// name.namepartrevision_system_uuid = devicerevision.section_id (namepart.id --> namepart.uuid // all entries ok
// name.namepartrevision_subsystem_uuid = devicerevision.section_id (namepart.id --> namepart.uuid // no entry nok
// name.namepartrevision_devicetype_uuid = devicerevision.devicetype_id (namepart.id --> namepart.uuid
// name.instance_index = devicerevision.instanceindex // e.g. if there has been usage of new database tables (new entries) before verification, there are more rows in those tables
// name.convention_name = devicerevision.conventionname // which means new and more ids than in old database tables
// name.convention_name_equivalence = devicerevision.conventionnameeqclass // which means those new ids don't exist in old database tables
// name.description = devicerevision.additionalinfo // --> retrieval of device revisions for those ids will give null
// name.status = null
// name.latest = true if id = get max id for uuid (not consider status) StringBuilder report = new StringBuilder();
// name.deleted = devicerevision.deleted
// name.requested = devicerevision.requestdate prepareLogReport(report, "About verification for data migration of structures");
// name.requested_by = devicerevision.requestedby_id (useraccount.id --> useraccount.username) prepareLogReport(report, DIVIDER_128);
// name.requested_comment = null prepareLogReport(report, DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
// name.processed = null prepareLogReport(report, DIVIDER_128);
// name.processed_by = null prepareLogReport(report, " Compare structures data before and after migration");
// name.processed_comment = devicerevision.processorcomment prepareLogReport(report, " Check that each entry is migrated and that content after migration is same as content before migration");
prepareLogReport(report, " ");
StringBuilder reportHtml = new StringBuilder(); 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 // 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) {
check = true;
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.size() == 0;
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(); List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findAll();
prepareLogReport("readMigrationNamePartRevision, find data, systemGroups.size: " + systemGroups.size(), reportHtml); List<WipSystem> systems = holderIWipRepositories.systemRepository().findAll();
prepareLogReport("readMigrationNamePartRevision, find data, systems.size: " + systems.size(), reportHtml); List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findAll();
prepareLogReport("readMigrationNamePartRevision, find data, subsystems.size: " + subsystems.size(), reportHtml); List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findAll();
prepareLogReport("readMigrationNamePartRevision, find data, disciplines.size: " + disciplines.size(), reportHtml); List<WipDeviceGroup> deviceGroups = holderIWipRepositories.deviceGroupRepository().findAll();
prepareLogReport("readMigrationNamePartRevision, find data, deviceGroups.size: " + deviceGroups.size(), reportHtml); List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findAll();
prepareLogReport("readMigrationNamePartRevision, find data, deviceTypes.size: " + deviceTypes.size(), reportHtml);
prepareLogReport("readMigrationNamePartRevision, find data, namePartRevisions.size: " + namePartRevisions.size(), reportHtml); 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 // utility
// interpret lists into hashmaps for faster retrieval in for loop below // interpret lists into hashmaps for faster retrieval in for loop below
...@@ -398,7 +365,7 @@ public class VerificationController { ...@@ -398,7 +365,7 @@ public class VerificationController {
mapIdNamePartRevision.put(namePartRevision.getId(), namePartRevision); mapIdNamePartRevision.put(namePartRevision.getId(), namePartRevision);
} }
HashMap<UUID, Long> mapUuidMaxIdSystemGroup = new HashMap<>(); HashMap<UUID, Long> mapUuidMaxIdSystemGroup = new HashMap<>();
for (SystemGroup systemGroup : systemGroups) { for (WipSystemGroup systemGroup : systemGroups) {
if ( (mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()) == null if ( (mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()) == null
|| systemGroup.getId() > mapUuidMaxIdSystemGroup.get(systemGroup.getUuid())) || systemGroup.getId() > mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(systemGroup.getStatus().name())) { && NamePartRevisionStatus.APPROVED.name().equals(systemGroup.getStatus().name())) {
...@@ -406,7 +373,7 @@ public class VerificationController { ...@@ -406,7 +373,7 @@ public class VerificationController {
} }
} }
HashMap<UUID, Long> mapUuidMaxIdSystem = new HashMap<>(); HashMap<UUID, Long> mapUuidMaxIdSystem = new HashMap<>();
for (System system : systems) { for (WipSystem system : systems) {
if (( mapUuidMaxIdSystem.get(system.getUuid()) == null if (( mapUuidMaxIdSystem.get(system.getUuid()) == null
|| system.getId() > mapUuidMaxIdSystem.get(system.getUuid())) || system.getId() > mapUuidMaxIdSystem.get(system.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(system.getStatus().name())) { && NamePartRevisionStatus.APPROVED.name().equals(system.getStatus().name())) {
...@@ -414,7 +381,7 @@ public class VerificationController { ...@@ -414,7 +381,7 @@ public class VerificationController {
} }
} }
HashMap<UUID, Long> mapUuidMaxIdSubsystem = new HashMap<>(); HashMap<UUID, Long> mapUuidMaxIdSubsystem = new HashMap<>();
for (Subsystem subsystem : subsystems) { for (WipSubsystem subsystem : subsystems) {
if ( (mapUuidMaxIdSubsystem.get(subsystem.getUuid()) == null if ( (mapUuidMaxIdSubsystem.get(subsystem.getUuid()) == null
|| subsystem.getId() > mapUuidMaxIdSubsystem.get(subsystem.getUuid())) || subsystem.getId() > mapUuidMaxIdSubsystem.get(subsystem.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(subsystem.getStatus().name())) { && NamePartRevisionStatus.APPROVED.name().equals(subsystem.getStatus().name())) {
...@@ -422,7 +389,7 @@ public class VerificationController { ...@@ -422,7 +389,7 @@ public class VerificationController {
} }
} }
HashMap<UUID, Long> mapUuidMaxIdDiscipline = new HashMap<>(); HashMap<UUID, Long> mapUuidMaxIdDiscipline = new HashMap<>();
for (Discipline discipline : disciplines) { for (WipDiscipline discipline : disciplines) {
if ((mapUuidMaxIdDiscipline.get(discipline.getUuid()) == null if ((mapUuidMaxIdDiscipline.get(discipline.getUuid()) == null
|| discipline.getId() > mapUuidMaxIdDiscipline.get(discipline.getUuid())) || discipline.getId() > mapUuidMaxIdDiscipline.get(discipline.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(discipline.getStatus().name())) { && NamePartRevisionStatus.APPROVED.name().equals(discipline.getStatus().name())) {
...@@ -430,7 +397,7 @@ public class VerificationController { ...@@ -430,7 +397,7 @@ public class VerificationController {
} }
} }
HashMap<UUID, Long> mapUuidMaxIdDeviceGroup = new HashMap<>(); HashMap<UUID, Long> mapUuidMaxIdDeviceGroup = new HashMap<>();
for (DeviceGroup deviceGroup : deviceGroups) { for (WipDeviceGroup deviceGroup : deviceGroups) {
if ((mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()) == null if ((mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()) == null
|| deviceGroup.getId() > mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid())) || deviceGroup.getId() > mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(deviceGroup.getStatus().name())) { && NamePartRevisionStatus.APPROVED.name().equals(deviceGroup.getStatus().name())) {
...@@ -438,7 +405,7 @@ public class VerificationController { ...@@ -438,7 +405,7 @@ public class VerificationController {
} }
} }
HashMap<UUID, Long> mapUuidMaxIdDeviceType = new HashMap<>(); HashMap<UUID, Long> mapUuidMaxIdDeviceType = new HashMap<>();
for (DeviceType deviceType : deviceTypes) { for (WipDeviceType deviceType : deviceTypes) {
if ((mapUuidMaxIdDeviceType.get(deviceType.getUuid()) == null if ((mapUuidMaxIdDeviceType.get(deviceType.getUuid()) == null
|| deviceType.getId() > mapUuidMaxIdDeviceType.get(deviceType.getUuid())) || deviceType.getId() > mapUuidMaxIdDeviceType.get(deviceType.getUuid()))
&& NamePartRevisionStatus.APPROVED.name().equals(deviceType.getStatus().name())) { && NamePartRevisionStatus.APPROVED.name().equals(deviceType.getStatus().name())) {
...@@ -446,340 +413,317 @@ public class VerificationController { ...@@ -446,340 +413,317 @@ public class VerificationController {
} }
} }
prepareLogReport("readMigrationNamePartRevision, utility, mapIdNamePartRevision.size: " + mapIdNamePartRevision.size(), reportHtml); prepareLogReport(report, "Utility");
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdSystemGroup.size: " + mapUuidMaxIdSystemGroup.size(), reportHtml); prepareLogReport(report, DIVIDER_96);
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdSystem.size: " + mapUuidMaxIdSystem.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("# map id namepartrevision:", SPACE_UNTIL_SIZE_48) + mapIdNamePartRevision.size());
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdSubsystem.size: " + mapUuidMaxIdSubsystem.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved systemgroup:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdSystemGroup.size());
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdDiscipline.size: " + mapUuidMaxIdDiscipline.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved system:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdSystem.size());
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdDeviceGroup.size: " + mapUuidMaxIdDeviceGroup.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("# map uuid maxid approved subsystem:", SPACE_UNTIL_SIZE_48) + mapUuidMaxIdSubsystem.size());
prepareLogReport("readMigrationNamePartRevision, utility, mapUuidMaxIdDeviceType.size: " + mapUuidMaxIdDeviceType.size(), reportHtml); 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 // keep track of id
// ok // ok
// nok // nok
SortedSet<Long> id_ok_namePartRevision = new TreeSet<>(); SortedSet<Long> idOkNamePartRevision = new TreeSet<>();
SortedSet<Long> id_nok_namePartRevision = new TreeSet<>(); SortedSet<Long> idNokNamePartRevision = new TreeSet<>();
prepareLogReport("readMigrationNamePartRevision, check, before, id_ok_namePartRevision.size: " + id_ok_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("readMigrationNamePartRevision, check, before, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml); 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 // system group
// check entry by entry // check entry by entry
// each attribute as expected // each attribute as expected
boolean check = false; boolean check = false;
NamePartRevision namePartRevision = null; NamePartRevision namePartRevision = null;
for (SystemGroup systemGroup : systemGroups) { for (WipSystemGroup systemGroup : systemGroups) {
check = true;
namePartRevision = mapIdNamePartRevision.get(systemGroup.getId()); namePartRevision = mapIdNamePartRevision.get(systemGroup.getId());
check = namePartRevision != null; // no check for parent uuid
check = namePartRevision != null
check = check && systemGroup.getId().equals(namePartRevision.getId()); && equals(systemGroup, namePartRevision, mapUuidMaxIdSystemGroup);
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());
// add to count // add to count
if (check) { if (check) {
id_ok_namePartRevision.add(systemGroup.getId()); idOkNamePartRevision.add(systemGroup.getId());
} else { } 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(report, addSpaceUntilSize("after systemgroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readMigrationNamePartRevision, check, after systemgroup, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
// system // system
// check entry by entry // check entry by entry
// each attribute as expected // each attribute as expected
for (System system : systems) { for (WipSystem system : systems) {
check = true;
namePartRevision = mapIdNamePartRevision.get(system.getId()); namePartRevision = mapIdNamePartRevision.get(system.getId());
check = namePartRevision != null; check = namePartRevision != null
&& system.getParentUuid().equals(namePartRevision.getParent().getUuid())
check = check && system.getId().equals(namePartRevision.getId()); && equals(system, namePartRevision, mapUuidMaxIdSystem);
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());
// add to count // add to count
if (check) { if (check) {
id_ok_namePartRevision.add(system.getId()); idOkNamePartRevision.add(system.getId());
} else { } 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(report, addSpaceUntilSize("after system", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readMigrationNamePartRevision, check, after system, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
// subsystem // subsystem
// check entry by entry // check entry by entry
// each attribute as expected // each attribute as expected
for (Subsystem subsystem : subsystems) { for (WipSubsystem subsystem : subsystems) {
check = true;
namePartRevision = mapIdNamePartRevision.get(subsystem.getId()); namePartRevision = mapIdNamePartRevision.get(subsystem.getId());
check = namePartRevision != null; check = namePartRevision != null
&& subsystem.getParentUuid().equals(namePartRevision.getParent().getUuid())
check = check && subsystem.getId().equals(namePartRevision.getId()); && equals(subsystem, namePartRevision, mapUuidMaxIdSubsystem);
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());
// add to count // add to count
if (check) { if (check) {
id_ok_namePartRevision.add(subsystem.getId()); idOkNamePartRevision.add(subsystem.getId());
} else { } 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(report, addSpaceUntilSize("after subsystem", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readMigrationNamePartRevision, check, after subsystem, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
// discipline // discipline
// check entry by entry // check entry by entry
// each attribute as expected // each attribute as expected
for (Discipline discipline : disciplines) { for (WipDiscipline discipline : disciplines) {
check = true;
namePartRevision = mapIdNamePartRevision.get(discipline.getId()); namePartRevision = mapIdNamePartRevision.get(discipline.getId());
check = namePartRevision != null; // no check for parent uuid
check = namePartRevision != null
check = check && discipline.getId().equals(namePartRevision.getId()); && equals(discipline, namePartRevision, mapUuidMaxIdDiscipline);
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());
// add to count // add to count
if (check) { if (check) {
id_ok_namePartRevision.add(discipline.getId()); idOkNamePartRevision.add(discipline.getId());
} else { } 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(report, addSpaceUntilSize("after discipline", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readMigrationNamePartRevision, check, after discipline, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
// device group // device group
// check entry by entry // check entry by entry
// each attribute as expected // each attribute as expected
for (DeviceGroup deviceGroup : deviceGroups) { for (WipDeviceGroup deviceGroup : deviceGroups) {
check = true;
namePartRevision = mapIdNamePartRevision.get(deviceGroup.getId()); namePartRevision = mapIdNamePartRevision.get(deviceGroup.getId());
check = namePartRevision != null; check = namePartRevision != null
&& deviceGroup.getParentUuid().equals(namePartRevision.getParent().getUuid())
check = check && deviceGroup.getId().equals(namePartRevision.getId()); && equals(deviceGroup, namePartRevision, mapUuidMaxIdDeviceGroup);
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());
// add to count // add to count
if (check) { if (check) {
id_ok_namePartRevision.add(deviceGroup.getId()); idOkNamePartRevision.add(deviceGroup.getId());
} else { } 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(report, addSpaceUntilSize("after devicegroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readMigrationNamePartRevision, check, after devicegroup, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
// device type // device type
// check entry by entry // check entry by entry
// each attribute as expected // each attribute as expected
for (DeviceType deviceType : deviceTypes) { for (WipDeviceType deviceType : deviceTypes) {
check = true;
namePartRevision = mapIdNamePartRevision.get(deviceType.getId()); namePartRevision = mapIdNamePartRevision.get(deviceType.getId());
check = namePartRevision != null; check = namePartRevision != null
&& deviceType.getParentUuid().equals(namePartRevision.getParent().getUuid())
check = check && deviceType.getId().equals(namePartRevision.getId()); && equals(deviceType, namePartRevision, mapUuidMaxIdDeviceType);
check = check && deviceType.getVersion().equals(namePartRevision.getVersion());
check = check && deviceType.getUuid().equals(namePartRevision.getNamePart().getUuid()); // add to count
if (check) {
// parent uuid idOkNamePartRevision.add(deviceType.getId());
check = check && deviceType.getParentUuid().equals(namePartRevision.getParent().getUuid()); } else {
check = check && StringUtils.equals(deviceType.getName(), namePartRevision.getName()); idNokNamePartRevision.add(deviceType.getId());
check = check && StringUtils.equals(deviceType.getMnemonic(), namePartRevision.getMnemonic()); }
check = check && StringUtils.equals(deviceType.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass()); }
check = check && StringUtils.equals(deviceType.getDescription(), namePartRevision.getDescription()); prepareLogReport(report, addSpaceUntilSize("after devicetype", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(idOkNamePartRevision.size(), SPACE_UNTIL_SIZE_32) + addSpaceUntilSize(idNokNamePartRevision.size(), SPACE_UNTIL_SIZE_32));
check = check && ((deviceType.getStatus() == null && namePartRevision.getStatus() == null) prepareLogReport(report, DIVIDER_96);
|| (deviceType.getStatus().name().equals(namePartRevision.getStatus().name())));
// ok if
// latest // all entries ok
// true if id = get max id for uuid // no entry nok
// special rules for pending, not consider pending boolean ok = sumStructures == namePartRevisions.size()
check = check && deviceType.isLatest() == deviceType.getId().equals(mapUuidMaxIdDeviceType.get(deviceType.getUuid())); && idOkNamePartRevision.size() == namePartRevisions.size()
check = check && deviceType.isDeleted() == namePartRevision.isDeleted(); && idNokNamePartRevision.isEmpty();
// date may be in different format for different objects, to be formatted before being compared prepareLogReport(report, "Result");
check = check && ((deviceType.getRequested() == null && namePartRevision.getRequestDate() == null) prepareLogReport(report, DIVIDER_96);
|| StringUtils.equals(SDF.format(deviceType.getRequested()), SDF.format(namePartRevision.getRequestDate()))); prepareLogReport(report, "ok: " + ok);
check = check && (deviceType.getRequestedBy() == null && namePartRevision.getRequestedBy() == null prepareLogReport(report, DIVIDER_128);
|| StringUtils.equals(deviceType.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
check = check && StringUtils.equals(deviceType.getRequestedComment(), namePartRevision.getRequesterComment()); return report.toString();
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())); * Perform verification of data migration with focus on names, i.e. device revisions.
check = check && StringUtils.equals(deviceType.getProcessedComment(), namePartRevision.getProcessorComment()); * 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 // add to count
if (check) { if (check) {
id_ok_namePartRevision.add(deviceType.getId()); idOkDeviceRevision.add(name.getId());
} else { } 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); } catch (Exception e) {
prepareLogReport("readMigrationNamePartRevision, check, after devicetype, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml); 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 // ok if
// all entries ok // all entries ok
// no entry nok // no entry nok
boolean ok = id_ok_namePartRevision.size() == namePartRevisions.size() boolean ok = names.size() == deviceRevisions.size()
&& id_nok_namePartRevision.size() == 0; && idOkDeviceRevision.size() == deviceRevisions.size()
&& idNokDeviceRevision.isEmpty();
prepareLogReport("readMigrationNamePartRevision, check, after, id_ok_namePartRevision.size: " + id_ok_namePartRevision.size(), reportHtml); prepareLogReport(report, "Result");
prepareLogReport("readMigrationNamePartRevision, check, after, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml); prepareLogReport(report, DIVIDER_96);
prepareLogReport("readMigrationNamePartRevision, ok: " + ok, reportHtml); 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) * 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, * 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. * 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.
...@@ -788,43 +732,68 @@ public class VerificationController { ...@@ -788,43 +732,68 @@ public class VerificationController {
* *
* @return report of reachability of data * @return report of reachability of data
*/ */
@GetMapping("/data_reachable") @GetMapping(
public String readDataReachable() { path = {"/data_reachable"},
StringBuilder reportHtml = new StringBuilder(); produces = {"text/plain"})
public String verifyDataReachable() {
List<Name> names = holderIRepositories.getNameRepository().findAll(); StringBuilder report = new StringBuilder();
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findAll();
List<System> systems = holderIRepositories.getSystemRepository().findAll(); prepareLogReport(report, "About verification for reachability of data");
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findAll(); prepareLogReport(report, DIVIDER_128);
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findAll(); prepareLogReport(report, DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
List<DeviceGroup> deviceGroups = holderIRepositories.getDeviceGroupRepository().findAll(); prepareLogReport(report, DIVIDER_128);
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findAll(); prepareLogReport(report, " Check that each entry in tables for migrated data (structures, names) also can be reached through find by id");
prepareLogReport(report, " ");
prepareLogReport("readDataReachable, find data, names.size: " + names.size(), reportHtml); prepareLogReport(report, " 1) Find data for structures after migration (all entries in tables)");
prepareLogReport("readDataReachable, find data, systemGroups.size: " + systemGroups.size(), reportHtml); prepareLogReport(report, " Find data for names after migration (all entries in tables)");
prepareLogReport("readDataReachable, find data, systems.size: " + systems.size(), reportHtml); prepareLogReport(report, " 2) Process each name entry (data after migration)");
prepareLogReport("readDataReachable, find data, subsystems.size: " + subsystems.size(), reportHtml); prepareLogReport(report, " For each entry, find corresponding data by id");
prepareLogReport("readDataReachable, find data, disciplines.size: " + disciplines.size(), reportHtml); prepareLogReport(report, " Count entries found by id");
prepareLogReport("readDataReachable, find data, deviceGroups.size: " + deviceGroups.size(), reportHtml); prepareLogReport(report, " 3) Process each kind of structure entry and each entry therein (data after migration)");
prepareLogReport("readDataReachable, find data, deviceTypes.size: " + deviceTypes.size(), reportHtml); prepareLogReport(report, " For each entry, find corresponding data by id");
prepareLogReport(report, " Count entries found by id");
HashSet<Long> setIdName = new HashSet<>(); prepareLogReport(report, " 4) Result is ok if");
HashSet<Long> setIdSystemGroup = new HashSet<>(); prepareLogReport(report, " number of entries (name) is same as number of entries found by id");
HashSet<Long> setIdSystem = new HashSet<>(); prepareLogReport(report, " number of entries (structure) is same as number of entries found by id");
HashSet<Long> setIdSubsystem = new HashSet<>(); prepareLogReport(report, DIVIDER_128);
HashSet<Long> setIdDiscipline = new HashSet<>();
HashSet<Long> setIdDeviceGroup = new HashSet<>(); List<WipName> names = holderIWipRepositories.nameRepository().findAll();
HashSet<Long> setIdDeviceType = new HashSet<>(); List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findAll();
List<WipSystem> systems = holderIWipRepositories.systemRepository().findAll();
List<Name> namesByUuid = null; List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findAll();
List<SystemGroup> systemGroupsByUuid = null; List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findAll();
List<System> systemsByUuid = null; List<WipDeviceGroup> deviceGroups = holderIWipRepositories.deviceGroupRepository().findAll();
List<Subsystem> subsystemsByUuid = null; List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findAll();
List<Discipline> disciplinesByUuid = null;
List<DeviceGroup> deviceGroupsByUuid = null; prepareLogReport(report, "Find data");
List<DeviceType> deviceTypesByUuid = null; prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, addSpaceUntilSize("# name:", SPACE_UNTIL_SIZE_48) + names.size());
prepareLogReport("readDataReachable, check, before", reportHtml); 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 // get started
// go through list(s) // go through list(s)
...@@ -833,117 +802,142 @@ public class VerificationController { ...@@ -833,117 +802,142 @@ public class VerificationController {
// ok if set(s) size same as list(s) size // ok if set(s) size same as list(s) size
// any entry not in set or once in set // 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 // to mimic - Find history for name by uuid
namesByUuid = holderIRepositories.getNameRepository().findByUuid(name.getUuid().toString()); namesByUuid = holderIWipRepositories.nameRepository().findByUuid(name.getUuid().toString());
for (Name nameByUuid : namesByUuid) { for (WipName nameByUuid : namesByUuid) {
setIdName.add(nameByUuid.getId()); 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 (WipSystemGroup systemGroup : systemGroups) {
for (SystemGroup systemGroup : systemGroups) {
// to mimic - Find history for system group by uuid // to mimic - Find history for system group by uuid
systemGroupsByUuid = holderIRepositories.getSystemGroupRepository().findByUuid(systemGroup.getUuid().toString()); systemGroupsByUuid = holderIWipRepositories.systemGroupRepository().findByUuid(systemGroup.getUuid().toString());
for (SystemGroup systemGroupByUuid : systemGroupsByUuid) { for (WipSystemGroup systemGroupByUuid : systemGroupsByUuid) {
setIdSystemGroup.add(systemGroupByUuid.getId()); 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 (WipSystem system : systems) {
for (System system : systems) {
// to mimic - Find history for system by uuid // to mimic - Find history for system by uuid
systemsByUuid = holderIRepositories.getSystemRepository().findByUuid(system.getUuid().toString()); systemsByUuid = holderIWipRepositories.systemRepository().findByUuid(system.getUuid().toString());
for (System systemByUuid : systemsByUuid) { for (WipSystem systemByUuid : systemsByUuid) {
setIdSystem.add(systemByUuid.getId()); 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 (WipSubsystem subsystem : subsystems) {
for (Subsystem subsystem : subsystems) {
// to mimic - Find history for subsystem by uuid // to mimic - Find history for subsystem by uuid
subsystemsByUuid = holderIRepositories.getSubsystemRepository().findByUuid(subsystem.getUuid().toString()); subsystemsByUuid = holderIWipRepositories.subsystemRepository().findByUuid(subsystem.getUuid().toString());
for (Subsystem subsystemByUuid : subsystemsByUuid) { for (WipSubsystem subsystemByUuid : subsystemsByUuid) {
setIdSubsystem.add(subsystemByUuid.getId()); 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 (WipDiscipline discipline : disciplines) {
for (Discipline discipline : disciplines) {
// to mimic - Find history for discipline by uuid // to mimic - Find history for discipline by uuid
disciplinesByUuid = holderIRepositories.getDisciplineRepository().findByUuid(discipline.getUuid().toString()); disciplinesByUuid = holderIWipRepositories.disciplineRepository().findByUuid(discipline.getUuid().toString());
for (Discipline disciplineByUuid : disciplinesByUuid) { for (WipDiscipline disciplineByUuid : disciplinesByUuid) {
setIdDiscipline.add(disciplineByUuid.getId()); 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 (WipDeviceGroup deviceGroup : deviceGroups) {
for (DeviceGroup deviceGroup : deviceGroups) {
// to mimic - Find history for device group by uuid // to mimic - Find history for device group by uuid
deviceGroupsByUuid = holderIRepositories.getDeviceGroupRepository().findByUuid(deviceGroup.getUuid().toString()); deviceGroupsByUuid = holderIWipRepositories.deviceGroupRepository().findByUuid(deviceGroup.getUuid().toString());
for (DeviceGroup deviceGroupByUuid : deviceGroupsByUuid) { for (WipDeviceGroup deviceGroupByUuid : deviceGroupsByUuid) {
setIdDeviceGroup.add(deviceGroupByUuid.getId()); 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 (WipDeviceType deviceType : deviceTypes) {
for (DeviceType deviceType : deviceTypes) {
// to mimic - Find history for device type by uuid // to mimic - Find history for device type by uuid
deviceTypesByUuid = holderIRepositories.getDeviceTypeRepository().findByUuid(deviceType.getUuid().toString()); deviceTypesByUuid = holderIWipRepositories.deviceTypeRepository().findByUuid(deviceType.getUuid().toString());
for (DeviceType deviceTypeByUuid : deviceTypesByUuid) { for (WipDeviceType deviceTypeByUuid : deviceTypesByUuid) {
setIdDeviceType.add(deviceTypeByUuid.getId()); foundbyIdDeviceType.add(deviceTypeByUuid.getId());
} }
} }
prepareLogReport(report, addSpaceUntilSize("after devicetype", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdDeviceType.size(), SPACE_UNTIL_SIZE_32));
prepareLogReport("readDataReachable, check, after devicetype, setIdDeviceType.size: " + setIdDeviceType.size(), reportHtml); prepareLogReport(report, DIVIDER_96);
boolean ok = names.size() == setIdName.size() boolean ok = names.size() == foundbyIdName.size()
&& systemGroups.size() == setIdSystemGroup.size() && systemGroups.size() == foundbyIdSystemGroup.size()
&& systems.size() == setIdSystem.size() && systems.size() == foundbyIdSystem.size()
&& subsystems.size() == setIdSubsystem.size() && subsystems.size() == foundbyIdSubsystem.size()
&& disciplines.size() == setIdDiscipline.size() && disciplines.size() == foundbyIdDiscipline.size()
&& deviceGroups.size() == setIdDeviceGroup.size() && deviceGroups.size() == foundbyIdDeviceGroup.size()
&& deviceTypes.size() == setIdDeviceType.size(); && deviceTypes.size() == foundbyIdDeviceType.size();
prepareLogReport("readDataReachable, check, after", reportHtml); prepareLogReport(report, "Result");
prepareLogReport("readDataReachable, ok: " + ok, reportHtml); prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, "ok: " + ok);
return reportHtml.toString(); 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. * 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 * @return
*/ */
@GetMapping("/restapi_oldvsnew") @GetMapping(
public String readRestApiOldVsNew() { path = {"/restapi_oldvsnew"},
StringBuilder reportHtml = new StringBuilder(); 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 // prepare old REST API
List<DeviceRevision> deviceRevisions = deviceRevisionRepository.findAll(); List<DeviceRevision> deviceRevisions = deviceRevisionRepository.findAll();
// old REST API cache
NameViewProvider nameViewProvider = new NameViewProvider(); NameViewProvider nameViewProvider = new NameViewProvider();
nameViewProvider.update(deviceRevisions); nameViewProvider.update(deviceRevisions);
// prepare new REST API // prepare new REST API
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted(); List<WipName> namesLatest = holderIWipRepositories.nameRepository().findLatest();
List<Name> namesLatest = holderIRepositories.getNameRepository().findLatest();
prepareLogReport("readRestApiOldVsNew, find data, deviceRevisions.size: " + deviceRevisions.size(), reportHtml); prepareLogReport(report, "Find data");
prepareLogReport("readRestApiOldVsNew, find data, nameViewProvider.getNameRevisions.entrySet.size: " + nameViewProvider.getNameRevisions().entrySet().size(), reportHtml); prepareLogReport(report, DIVIDER_96);
prepareLogReport("readRestApiOldVsNew, find data, names.size: " + names.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("# devicerevision:", SPACE_UNTIL_SIZE_48) + deviceRevisions.size());
prepareLogReport("readRestApiOldVsNew, find data, namesLatest.size: " + namesLatest.size(), reportHtml); 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 // prepare comparison
...@@ -956,93 +950,377 @@ public class VerificationController { ...@@ -956,93 +950,377 @@ public class VerificationController {
mapIdUuidDeviceRevision.put(entry.getValue().getId(), entry.getValue().getDevice().getUuid()); mapIdUuidDeviceRevision.put(entry.getValue().getId(), entry.getValue().getDevice().getUuid());
} }
HashMap<Long, Name> mapIdName = new HashMap<>((int)(names.size()/0.75 + 2)); HashMap<UUID, WipName> mapUuidNameLatest = new HashMap<>((int)(namesLatest.size()/0.75 + 2));
for (Name name : names) { for (WipName name : namesLatest) {
mapIdName.put(name.getId(), name);
}
HashMap<UUID, Name> mapUuidNameLatest = new HashMap<>((int)(namesLatest.size()/0.75 + 2));
for (Name name : namesLatest) {
mapUuidNameLatest.put(name.getUuid(), name); mapUuidNameLatest.put(name.getUuid(), name);
} }
prepareLogReport("readRestApiOldVsNew, utility, mapIdDeviceRevision.size: " + mapIdDeviceRevision.size(), reportHtml); prepareLogReport(report, "Utility");
prepareLogReport("readRestApiOldVsNew, utility, mapIdDeviceRevisionDifference.size: " + mapIdDeviceRevisionDifference.size(), reportHtml); prepareLogReport(report, DIVIDER_96);
prepareLogReport("readRestApiOldVsNew, utility, mapIdUuidDeviceRevision.size: " + mapIdUuidDeviceRevision.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("# map id devicerevision:", SPACE_UNTIL_SIZE_48) + mapIdDeviceRevision.size());
prepareLogReport("readRestApiOldVsNew, utility, mapIdName.size: " + mapIdName.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("# map id devicerevision difference:", SPACE_UNTIL_SIZE_48) + mapIdDeviceRevisionDifference.size());
prepareLogReport("readRestApiOldVsNew, utility, mapUuidNameLatest.size: " + mapUuidNameLatest.size(), reportHtml); 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 // 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; boolean idInOld = true;
int countIdInOld = 0; int countIdInOld = 0;
int countNotIdInOld = 0; int countIdNotInOld = 0;
for (Name name : names) { int countIdNotInOldButDeleted = 0;
for (WipName name : namesLatest) {
idInOld = mapIdDeviceRevisionDifference.containsKey(name.getId()); idInOld = mapIdDeviceRevisionDifference.containsKey(name.getId());
if (idInOld) { if (idInOld) {
countIdInOld++; countIdInOld++;
} else if (!idInOld) { } else if (!idInOld) {
countNotIdInOld++; // either bug in old REST API or bug in implementation of cache for old REST API - NEED TO INVESTIGATE
// break; // after investigation, appears bug in old REST API
countIdNotInOld++;
if (name.isDeleted()) {
countIdNotInOldButDeleted++;
}
} }
mapIdDeviceRevisionDifference.remove(name.getId()); mapIdDeviceRevisionDifference.remove(name.getId());
} }
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdDeviceRevision.size: " + mapIdDeviceRevision.size(), reportHtml); prepareLogReport(report, "Check");
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdDeviceRevisionDifference.size: " + mapIdDeviceRevisionDifference.size(), reportHtml); prepareLogReport(report, DIVIDER_96);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdUuidDeviceRevision.size: " + mapIdUuidDeviceRevision.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# map id devicerevision difference:", SPACE_UNTIL_SIZE_40) + mapIdDeviceRevisionDifference.size());
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdName.size: " + mapIdName.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# count id in old:", SPACE_UNTIL_SIZE_40) + countIdInOld);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapUuidNameLatest.size: " + mapUuidNameLatest.size(), reportHtml); prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# count id not in old:", SPACE_UNTIL_SIZE_40) + countIdNotInOld);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, countIdInOld: " + countIdInOld, reportHtml); prepareLogReport(report, addSpaceUntilSize("after difference overview", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# count id not in old but deleted:", SPACE_UNTIL_SIZE_40) + countIdNotInOldButDeleted);
prepareLogReport("readRestApiOldVsNew, check, after difference 1, countNotIdInOld: " + countNotIdInOld, reportHtml); prepareLogReport(report, DIVIDER_96);
// 2. difference is old/obsolete data // 2. check difference - is old/obsolete data
// id corresponding to uuid should not be last in line // can not know reason for certain
// <--> last in line should be deleted // 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<>(); 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 (Entry<Long, DeviceRevision> entry : mapIdDeviceRevisionDifference.entrySet()) {
// for each difference
// find out uuid, name -
// note use of mapUuidNameLatest - latest (!)
UUID uuid = mapIdUuidDeviceRevision.get(entry.getKey()); 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 // something may be wrong
// if latest for devicerevision is in names then ok // no name
// else if latest for devicerevision is deleted then ok // name is in remaining difference
// else something is wrong
// if (!latestInLine && !name.isDeleted()) { if (name == null) {
// <-->
// name != null && (name.isLatest() || name.isDeleted()) --> ok, else wrong
if (!(name != null && (name.isLatest() || name.isDeleted()))) {
// something is wrong // something is wrong
listDeviceRevisionWrong.add(entry.getValue()); 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(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(report, "Result");
prepareLogReport(report, DIVIDER_96);
prepareLogReport(report, "ok: " + ok);
prepareLogReport(report, DIVIDER_128);
return report.toString();
}
prepareLogReport("readRestApiOldVsNew, check, after difference 2, listDeviceRevisionWrong.size: " + listDeviceRevisionWrong.size(), reportHtml); /**
* Utility method for preparing reports for logging purposes.
*
* @param report
* @param message
*/
private void prepareLogReport(StringBuilder report, String message) {
if (!StringUtils.isEmpty(message)) {
report.append(message + NEWLINE);
LOGGER.log(Level.FINE, message);
}
}
boolean ok = (mapIdDeviceRevisionDifference.size() == (nameViewProvider.getNameRevisions().entrySet().size() - names.size())) /**
&& (listDeviceRevisionWrong.size() == 0); * 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;
}
prepareLogReport("readRestApiOldVsNew, check, after", reportHtml); boolean check = structure.getId().equals(namePartRevision.getId());
prepareLogReport("readRestApiOldVsNew, ok: " + ok, reportHtml); 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();
}
return reportHtml.toString(); // 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 for preparing reports for logging purposes. * Utility method to compare Name with DeviceRevision.
* *
* @param message * @param name name
* @param reportHtml * @param deviceRevision device revision
* @param reportLog * @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 void prepareLogReport(String message, StringBuilder reportHtml) { private boolean equals(WipName name, DeviceRevision deviceRevision, HashMap<UUID, Long> mapUuidMaxIdName, HashMap<UUID, NamePartRevision> mapUuidNamePartRevision) {
if (!StringUtils.isEmpty(message)) { // check
LOGGER.log(Level.INFO, message); // check entry by entry
reportHtml.append(message + NEW_LINE_BR); // 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; ...@@ -29,19 +29,20 @@ import java.util.regex.PatternSyntaxException;
import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Hidden;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IDeviceGroupRepository; import org.openepics.names.repository.model.wip.WipName;
import org.openepics.names.repository.IDeviceTypeRepository; import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
import org.openepics.names.repository.IDisciplineRepository; import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
import org.openepics.names.repository.INameRepository; import org.openepics.names.repository.wip.IWipDisciplineRepository;
import org.openepics.names.repository.ISubsystemRepository; import org.openepics.names.repository.wip.IWipNameRepository;
import org.openepics.names.repository.ISystemGroupRepository; import org.openepics.names.repository.wip.IWipSubsystemRepository;
import org.openepics.names.repository.ISystemRepository; import org.openepics.names.repository.wip.IWipSystemGroupRepository;
import org.openepics.names.repository.model.Name; import org.openepics.names.repository.wip.IWipSystemRepository;
import org.openepics.names.rest.beans.old.DeviceNameElement; import org.openepics.names.rest.beans.old.DeviceNameElement;
import org.openepics.names.util.HolderIRepositories; import org.openepics.names.service.LogService;
import org.openepics.names.util.HolderSystemDeviceStructure;
import org.openepics.names.util.NamingConventionUtil; import org.openepics.names.util.NamingConventionUtil;
import org.openepics.names.util.old.DeviceNameElementUtil; 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.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -82,26 +83,29 @@ public class DeviceNamesControllerV0 { ...@@ -82,26 +83,29 @@ public class DeviceNamesControllerV0 {
private static final Logger LOGGER = Logger.getLogger(DeviceNamesControllerV0.class.getName()); private static final Logger LOGGER = Logger.getLogger(DeviceNamesControllerV0.class.getName());
private HolderIRepositories holderIRepositories; private final LogService logService;
private final HolderIWipRepositories holderIWipRepositories;
@Autowired @Autowired
public DeviceNamesControllerV0( public DeviceNamesControllerV0(
INameRepository iNameRepository, LogService logService,
ISystemGroupRepository iSystemGroupRepository, IWipNameRepository iWipNameRepository,
ISystemRepository iSystemRepository, IWipSystemGroupRepository iWipSystemGroupRepository,
ISubsystemRepository iSubsystemRepository, IWipSystemRepository iWipSystemRepository,
IDisciplineRepository iDisciplineRepository, IWipSubsystemRepository iWipSubsystemRepository,
IDeviceGroupRepository iDeviceGroupRepository, IWipDisciplineRepository iWipDisciplineRepository,
IDeviceTypeRepository iDeviceTypeRepository) { IWipDeviceGroupRepository iWipDeviceGroupRepository,
IWipDeviceTypeRepository iWipDeviceTypeRepository) {
holderIRepositories = new HolderIRepositories(
iNameRepository, this.logService = logService;
iSystemGroupRepository, this.holderIWipRepositories = new HolderIWipRepositories(
iSystemRepository, iWipNameRepository,
iSubsystemRepository, iWipSystemGroupRepository,
iDisciplineRepository, iWipSystemRepository,
iDeviceGroupRepository, iWipSubsystemRepository,
iDeviceTypeRepository); iWipDisciplineRepository,
iWipDeviceGroupRepository,
iWipDeviceTypeRepository);
} }
/** /**
...@@ -111,19 +115,19 @@ public class DeviceNamesControllerV0 { ...@@ -111,19 +115,19 @@ public class DeviceNamesControllerV0 {
*/ */
@GetMapping @GetMapping
public List<DeviceNameElement> findNames() { public List<DeviceNameElement> findNames() {
List<Name> names = holderIRepositories.getNameRepository().findLatestNotDeleted(); List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
// create collection with known initial capacity // create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size()); final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
// initiate holder of containers for system and device structure content, for performance reasons // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
LOGGER.log(Level.INFO, "findNames, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNames, deviceNameElement s.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -152,23 +156,23 @@ public class DeviceNamesControllerV0 { ...@@ -152,23 +156,23 @@ public class DeviceNamesControllerV0 {
try { try {
pattern = Pattern.compile(name); pattern = Pattern.compile(name);
} catch (PatternSyntaxException e) { } catch (PatternSyntaxException e) {
LOGGER.log(Level.FINE, e.getMessage(), e); logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements; 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 // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name namee : names) { for (WipName namee : names) {
if (pattern.matcher(namee.getConventionName()).find()) { if (pattern.matcher(namee.getConventionName()).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(namee, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(namee, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesSearch, name: " + name); LOGGER.log(Level.FINE, "findNamesSearch, name: {0}", name);
LOGGER.log(Level.INFO, "findNamesSearch, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesSearch, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -186,25 +190,25 @@ public class DeviceNamesControllerV0 { ...@@ -186,25 +190,25 @@ public class DeviceNamesControllerV0 {
// exact match // exact match
// case sensitive // case sensitive
// initiate holder of containers for system and device structure content, for performance reasons // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
final List<DeviceNameElement> deviceNameElements = Lists.newArrayList(); final List<DeviceNameElement> deviceNameElements = Lists.newArrayList();
List<Name> namesSystemGroup = holderIRepositories.getNameRepository().findLatestBySystemGroupMnemonic(system); List<WipName> namesSystemGroup = holderIWipRepositories.nameRepository().findLatestBySystemGroupMnemonic(system);
for (Name name : namesSystemGroup) { for (WipName name : namesSystemGroup) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
List<Name> namesSystem = holderIRepositories.getNameRepository().findLatestBySystemMnemonic(system); List<WipName> namesSystem = holderIWipRepositories.nameRepository().findLatestBySystemMnemonic(system);
List<Name> namesSystemThroughSubsystem = holderIRepositories.getNameRepository().findLatestBySystemMnemonicThroughSubsystem(system); List<WipName> namesSystemThroughSubsystem = holderIWipRepositories.nameRepository().findLatestBySystemMnemonicThroughSubsystem(system);
for (Name name : namesSystem) { for (WipName name : namesSystem) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
for (Name name : namesSystemThroughSubsystem) { for (WipName name : namesSystemThroughSubsystem) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
LOGGER.log(Level.INFO, "findNamesBySystem, system: " + system); LOGGER.log(Level.FINE, "findNamesBySystem, system: {0}", system);
LOGGER.log(Level.INFO, "findNamesBySystem, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesBySystem, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -228,24 +232,24 @@ public class DeviceNamesControllerV0 { ...@@ -228,24 +232,24 @@ public class DeviceNamesControllerV0 {
try { try {
pattern = Pattern.compile(system); pattern = Pattern.compile(system);
} catch (PatternSyntaxException e) { } catch (PatternSyntaxException e) {
LOGGER.log(Level.FINE, e.getMessage(), e); logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements; 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 // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
String sub = NamingConventionUtil.extractSystem(name.getConventionName()); String sub = NamingConventionUtil.extractSystem(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesSearch, system: " + system); LOGGER.log(Level.FINE, "findNamesSearch, system: {0}", system);
LOGGER.log(Level.INFO, "findNamesSearch, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesSearch, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -263,22 +267,22 @@ public class DeviceNamesControllerV0 { ...@@ -263,22 +267,22 @@ public class DeviceNamesControllerV0 {
// exact match // exact match
// case sensitive // case sensitive
List<Name> names = holderIRepositories.getNameRepository().findLatestBySubsystemMnemonic(subsystem); List<WipName> names = holderIWipRepositories.nameRepository().findLatestBySubsystemMnemonic(subsystem);
// create collection with known initial capacity // create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size()); final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
if (!names.isEmpty()) { if (!names.isEmpty()) {
// initiate holder of containers for system and device structure content, for performance reasons // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesBySubsystem, subsystem: " + subsystem); LOGGER.log(Level.FINE, "findNamesBySubsystem, subsystem: {0}", subsystem);
LOGGER.log(Level.INFO, "findNamesBySubsystem, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesBySubsystem, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -302,24 +306,24 @@ public class DeviceNamesControllerV0 { ...@@ -302,24 +306,24 @@ public class DeviceNamesControllerV0 {
try { try {
pattern = Pattern.compile(subsystem); pattern = Pattern.compile(subsystem);
} catch (PatternSyntaxException e) { } catch (PatternSyntaxException e) {
LOGGER.log(Level.FINE, e.getMessage(), e); logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements; 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 // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
String sub = NamingConventionUtil.extractSubsystem(name.getConventionName()); String sub = NamingConventionUtil.extractSubsystem(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesBySubsystemSearch, subsystem: " + subsystem); LOGGER.log(Level.FINE, "findNamesBySubsystemSearch, subsystem: {0}", subsystem);
LOGGER.log(Level.INFO, "findNamesBySubsystemSearch, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesBySubsystemSearch, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -337,22 +341,22 @@ public class DeviceNamesControllerV0 { ...@@ -337,22 +341,22 @@ public class DeviceNamesControllerV0 {
// exact match // exact match
// case sensitive // case sensitive
List<Name> names = holderIRepositories.getNameRepository().findLatestByDisciplineMnemonic(discipline); List<WipName> names = holderIWipRepositories.nameRepository().findLatestByDisciplineMnemonicThroughDeviceType(discipline);
// create collection with known initial capacity // create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size()); final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
if (!names.isEmpty()) { if (!names.isEmpty()) {
// initiate holder of containers for system and device structure content, for performance reasons // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesByDiscipline, discipline: " + discipline); LOGGER.log(Level.FINE, "findNamesByDiscipline, discipline: {0}", discipline);
LOGGER.log(Level.INFO, "findNamesByDiscipline, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesByDiscipline, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -376,24 +380,24 @@ public class DeviceNamesControllerV0 { ...@@ -376,24 +380,24 @@ public class DeviceNamesControllerV0 {
try { try {
pattern = Pattern.compile(discipline); pattern = Pattern.compile(discipline);
} catch (PatternSyntaxException e) { } catch (PatternSyntaxException e) {
LOGGER.log(Level.FINE, e.getMessage(), e); logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements; 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 // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
String sub = NamingConventionUtil.extractDiscipline(name.getConventionName()); String sub = NamingConventionUtil.extractDiscipline(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesByDisciplineSearch, discipline: " + discipline); LOGGER.log(Level.FINE, "findNamesByDisciplineSearch, discipline: {0}", discipline);
LOGGER.log(Level.INFO, "findNamesByDisciplineSearch, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesByDisciplineSearch, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -411,22 +415,22 @@ public class DeviceNamesControllerV0 { ...@@ -411,22 +415,22 @@ public class DeviceNamesControllerV0 {
// exact match // exact match
// case sensitive // case sensitive
List<Name> names = holderIRepositories.getNameRepository().findLatestByDeviceTypeMnemonic(deviceType); List<WipName> names = holderIWipRepositories.nameRepository().findLatestByDeviceTypeMnemonic(deviceType);
// create collection with known initial capacity // create collection with known initial capacity
final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size()); final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
if (!names.isEmpty()) { if (!names.isEmpty()) {
// initiate holder of containers for system and device structure content, for performance reasons // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesByDeviceType, deviceType: " + deviceType); LOGGER.log(Level.FINE, "findNamesByDeviceType, deviceType: {0}", deviceType);
LOGGER.log(Level.INFO, "findNamesByDeviceType, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesByDeviceType, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -450,24 +454,24 @@ public class DeviceNamesControllerV0 { ...@@ -450,24 +454,24 @@ public class DeviceNamesControllerV0 {
try { try {
pattern = Pattern.compile(deviceType); pattern = Pattern.compile(deviceType);
} catch (PatternSyntaxException e) { } catch (PatternSyntaxException e) {
LOGGER.log(Level.FINE, e.getMessage(), e); logService.logException(LOGGER, Level.WARNING, e);
return deviceNameElements; 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 // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
for (Name name : names) { for (WipName name : names) {
String sub = NamingConventionUtil.extractDeviceType(name.getConventionName()); String sub = NamingConventionUtil.extractDeviceType(name.getConventionName());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holder)); deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
} }
} }
LOGGER.log(Level.INFO, "findNamesByDeviceTypeSearch, deviceType: " + deviceType); LOGGER.log(Level.FINE, "findNamesByDeviceTypeSearch, deviceType: {0}", deviceType);
LOGGER.log(Level.INFO, "findNamesByDeviceTypeSearch, deviceNameElements.size: " + deviceNameElements.size()); LOGGER.log(Level.FINE, "findNamesByDeviceTypeSearch, deviceNameElements.size: {0}", deviceNameElements.size());
return deviceNameElements; return deviceNameElements;
} }
...@@ -484,17 +488,17 @@ public class DeviceNamesControllerV0 { ...@@ -484,17 +488,17 @@ public class DeviceNamesControllerV0 {
// exact match // exact match
// case sensitive // case sensitive
Name name = null; WipName name = null;
try { try {
UUID.fromString(uuid); UUID.fromString(uuid);
name = holderIRepositories.getNameRepository().findLatestByUuid(uuid); name = holderIWipRepositories.nameRepository().findLatestByUuid(uuid);
} catch (IllegalArgumentException e) { } 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.INFO, "findName, uuid: " + uuid); LOGGER.log(Level.FINE, "findName, uuid: {0}", uuid);
LOGGER.log(Level.INFO, "findName, deviceNameElement: " + deviceNameElement); LOGGER.log(Level.FINE, "findName, deviceNameElement: {0}", deviceNameElement);
return deviceNameElement; return deviceNameElement;
} }
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
package org.openepics.names.rest.controller.old; package org.openepics.names.rest.controller.old;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
...@@ -59,7 +58,7 @@ public class HealthcheckControllerV0 { ...@@ -59,7 +58,7 @@ public class HealthcheckControllerV0 {
// return healthcheck as server timestamp // return healthcheck as server timestamp
// datetime - dateStyle, timeStyle - full // datetime - dateStyle, timeStyle - full
return SimpleDateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()); return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date());
} }
} }
...@@ -23,23 +23,23 @@ import java.util.logging.Level; ...@@ -23,23 +23,23 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IDeviceGroupRepository; import org.openepics.names.repository.model.wip.WipDeviceGroup;
import org.openepics.names.repository.IDeviceTypeRepository; import org.openepics.names.repository.model.wip.WipDeviceType;
import org.openepics.names.repository.IDisciplineRepository; import org.openepics.names.repository.model.wip.WipDiscipline;
import org.openepics.names.repository.INameRepository; import org.openepics.names.repository.model.wip.WipName;
import org.openepics.names.repository.ISubsystemRepository; import org.openepics.names.repository.model.wip.WipSubsystem;
import org.openepics.names.repository.ISystemGroupRepository; import org.openepics.names.repository.model.wip.WipSystem;
import org.openepics.names.repository.ISystemRepository; import org.openepics.names.repository.model.wip.WipSystemGroup;
import org.openepics.names.repository.model.DeviceGroup; import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
import org.openepics.names.repository.model.DeviceType; import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
import org.openepics.names.repository.model.Discipline; import org.openepics.names.repository.wip.IWipDisciplineRepository;
import org.openepics.names.repository.model.Name; import org.openepics.names.repository.wip.IWipNameRepository;
import org.openepics.names.repository.model.Subsystem; import org.openepics.names.repository.wip.IWipSubsystemRepository;
import org.openepics.names.repository.model.System; import org.openepics.names.repository.wip.IWipSystemGroupRepository;
import org.openepics.names.repository.model.SystemGroup; import org.openepics.names.repository.wip.IWipSystemRepository;
import org.openepics.names.rest.beans.old.HistoryElement; 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.old.HistoryElementUtil;
import org.openepics.names.util.wip.HolderIWipRepositories;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -75,26 +75,26 @@ public class HistoryControllerV0 { ...@@ -75,26 +75,26 @@ public class HistoryControllerV0 {
private static final long THOUSAND_MILLISECONDS = 1000; private static final long THOUSAND_MILLISECONDS = 1000;
private HolderIRepositories holderIRepositories; private final HolderIWipRepositories holderIWipRepositories;
@Autowired @Autowired
public HistoryControllerV0( public HistoryControllerV0(
INameRepository iNameRepository, IWipNameRepository iWipNameRepository,
ISystemGroupRepository iSystemGroupRepository, IWipSystemGroupRepository iWipSystemGroupRepository,
ISystemRepository iSystemRepository, IWipSystemRepository iWipSystemRepository,
ISubsystemRepository iSubsystemRepository, IWipSubsystemRepository iWipSubsystemRepository,
IDisciplineRepository iDisciplineRepository, IWipDisciplineRepository iWipDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository, IWipDeviceGroupRepository iWipDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository) { IWipDeviceTypeRepository iWipDeviceTypeRepository) {
holderIRepositories = new HolderIRepositories( this.holderIWipRepositories = new HolderIWipRepositories(
iNameRepository, iWipNameRepository,
iSystemGroupRepository, iWipSystemGroupRepository,
iSystemRepository, iWipSystemRepository,
iSubsystemRepository, iWipSubsystemRepository,
iDisciplineRepository, iWipDisciplineRepository,
iDeviceGroupRepository, iWipDeviceGroupRepository,
iDeviceTypeRepository); iWipDeviceTypeRepository);
} }
/** /**
...@@ -118,16 +118,16 @@ public class HistoryControllerV0 { ...@@ -118,16 +118,16 @@ public class HistoryControllerV0 {
return historyElements; return historyElements;
} }
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findByUuid(uuid); List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findByUuid(uuid);
List<System> systems = holderIRepositories.getSystemRepository().findByUuid(uuid); List<WipSystem> systems = holderIWipRepositories.systemRepository().findByUuid(uuid);
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findByUuid(uuid); List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findByUuid(uuid);
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findByUuid(uuid); List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findByUuid(uuid);
List<DeviceGroup> deviceGroups = holderIRepositories.getDeviceGroupRepository().findByUuid(uuid); List<WipDeviceGroup> deviceGroups = holderIWipRepositories.deviceGroupRepository().findByUuid(uuid);
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findByUuid(uuid); List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findByUuid(uuid);
if (!systemGroups.isEmpty()) { if (!systemGroups.isEmpty()) {
for (SystemGroup systemGroup : systemGroups) { for (WipSystemGroup systemGroup : systemGroups) {
// one or two return elements // one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
...@@ -143,7 +143,7 @@ public class HistoryControllerV0 { ...@@ -143,7 +143,7 @@ public class HistoryControllerV0 {
} }
} }
} else if (!systems.isEmpty()) { } else if (!systems.isEmpty()) {
for (System system : systems) { for (WipSystem system : systems) {
// one or two return elements // one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
...@@ -159,7 +159,7 @@ public class HistoryControllerV0 { ...@@ -159,7 +159,7 @@ public class HistoryControllerV0 {
} }
} }
} else if (!subsystems.isEmpty()) { } else if (!subsystems.isEmpty()) {
for (Subsystem subsystem : subsystems) { for (WipSubsystem subsystem : subsystems) {
// one or two return elements // one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
...@@ -175,7 +175,7 @@ public class HistoryControllerV0 { ...@@ -175,7 +175,7 @@ public class HistoryControllerV0 {
} }
} }
} else if (!disciplines.isEmpty()) { } else if (!disciplines.isEmpty()) {
for (Discipline discipline : disciplines) { for (WipDiscipline discipline : disciplines) {
// one or two return elements // one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
...@@ -191,7 +191,7 @@ public class HistoryControllerV0 { ...@@ -191,7 +191,7 @@ public class HistoryControllerV0 {
} }
} }
} else if (!deviceGroups.isEmpty()) { } else if (!deviceGroups.isEmpty()) {
for (DeviceGroup deviceGroup : deviceGroups) { for (WipDeviceGroup deviceGroup : deviceGroups) {
// one or two return elements // one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
...@@ -207,7 +207,7 @@ public class HistoryControllerV0 { ...@@ -207,7 +207,7 @@ public class HistoryControllerV0 {
} }
} }
} else if (!deviceTypes.isEmpty()) { } else if (!deviceTypes.isEmpty()) {
for (DeviceType deviceType : deviceTypes) { for (WipDeviceType deviceType : deviceTypes) {
// one or two return elements // one or two return elements
// processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested)
// processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial)
...@@ -224,8 +224,8 @@ public class HistoryControllerV0 { ...@@ -224,8 +224,8 @@ public class HistoryControllerV0 {
} }
} }
LOGGER.log(Level.INFO, "findNamePartHistoryForUuid, uuid: " + uuid); LOGGER.log(Level.FINE, "findNamePartHistoryForUuid, uuid: {0}", uuid);
LOGGER.log(Level.INFO, "findNamePartHistoryForUuid, historyElements.size: " + historyElements.size()); LOGGER.log(Level.FINE, "findNamePartHistoryForUuid, historyElements.size: {0}", historyElements.size());
return historyElements; return historyElements;
} }
...@@ -251,13 +251,13 @@ public class HistoryControllerV0 { ...@@ -251,13 +251,13 @@ public class HistoryControllerV0 {
return historyElements; return historyElements;
} }
List<Name> names = holderIRepositories.getNameRepository().findByUuid(uuid); List<WipName> names = holderIWipRepositories.nameRepository().findByUuid(uuid);
for (Name name : names) { for (WipName name : names) {
historyElements.add(HistoryElementUtil.getHistoryElement(name)); historyElements.add(HistoryElementUtil.getHistoryElement(name));
} }
LOGGER.log(Level.INFO, "findNameHistoryForUuid, uuid: " + uuid); LOGGER.log(Level.FINE, "findNameHistoryForUuid, uuid: {0}", uuid);
LOGGER.log(Level.INFO, "findNameHistoryForUuid, historyElements.size: " + historyElements.size()); LOGGER.log(Level.FINE, "findNameHistoryForUuid, historyElements.size: {0}", historyElements.size());
return historyElements; return historyElements;
} }
......
...@@ -25,23 +25,24 @@ import java.util.regex.Pattern; ...@@ -25,23 +25,24 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openepics.names.repository.IDeviceGroupRepository; import org.openepics.names.repository.model.wip.WipDeviceGroup;
import org.openepics.names.repository.IDeviceTypeRepository; import org.openepics.names.repository.model.wip.WipDeviceType;
import org.openepics.names.repository.IDisciplineRepository; import org.openepics.names.repository.model.wip.WipDiscipline;
import org.openepics.names.repository.INameRepository; import org.openepics.names.repository.model.wip.WipSubsystem;
import org.openepics.names.repository.ISubsystemRepository; import org.openepics.names.repository.model.wip.WipSystem;
import org.openepics.names.repository.ISystemGroupRepository; import org.openepics.names.repository.model.wip.WipSystemGroup;
import org.openepics.names.repository.ISystemRepository; import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
import org.openepics.names.repository.model.DeviceGroup; import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
import org.openepics.names.repository.model.DeviceType; import org.openepics.names.repository.wip.IWipDisciplineRepository;
import org.openepics.names.repository.model.Discipline; import org.openepics.names.repository.wip.IWipNameRepository;
import org.openepics.names.repository.model.Subsystem; import org.openepics.names.repository.wip.IWipSubsystemRepository;
import org.openepics.names.repository.model.System; import org.openepics.names.repository.wip.IWipSystemGroupRepository;
import org.openepics.names.repository.model.SystemGroup; import org.openepics.names.repository.wip.IWipSystemRepository;
import org.openepics.names.rest.beans.old.PartElement; 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.NamingConventionUtil;
import org.openepics.names.util.old.PartElementUtil; import org.openepics.names.util.old.PartElementUtil;
import org.openepics.names.util.wip.HolderIWipRepositories;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -76,26 +77,29 @@ public class PartControllerV0 { ...@@ -76,26 +77,29 @@ public class PartControllerV0 {
private static final Logger LOGGER = Logger.getLogger(PartControllerV0.class.getName()); private static final Logger LOGGER = Logger.getLogger(PartControllerV0.class.getName());
private HolderIRepositories holderIRepositories; private final LogService logService;
private final HolderIWipRepositories holderIWipRepositories;
@Autowired @Autowired
public PartControllerV0( public PartControllerV0(
INameRepository iNameRepository, LogService logService,
ISystemGroupRepository iSystemGroupRepository, IWipNameRepository iWipNameRepository,
ISystemRepository iSystemRepository, IWipSystemGroupRepository iWipSystemGroupRepository,
ISubsystemRepository iSubsystemRepository, IWipSystemRepository iWipSystemRepository,
IDisciplineRepository iDisciplineRepository, IWipSubsystemRepository iWipSubsystemRepository,
IDeviceGroupRepository iDeviceGroupRepository, IWipDisciplineRepository iWipDisciplineRepository,
IDeviceTypeRepository iDeviceTypeRepository) { IWipDeviceGroupRepository iWipDeviceGroupRepository,
IWipDeviceTypeRepository iWipDeviceTypeRepository) {
holderIRepositories = new HolderIRepositories(
iNameRepository, this.logService = logService;
iSystemGroupRepository, this.holderIWipRepositories = new HolderIWipRepositories(
iSystemRepository, iWipNameRepository,
iSubsystemRepository, iWipSystemGroupRepository,
iDisciplineRepository, iWipSystemRepository,
iDeviceGroupRepository, iWipSubsystemRepository,
iDeviceTypeRepository); iWipDisciplineRepository,
iWipDeviceGroupRepository,
iWipDeviceTypeRepository);
} }
/** /**
...@@ -115,34 +119,34 @@ public class PartControllerV0 { ...@@ -115,34 +119,34 @@ public class PartControllerV0 {
// find in system structure // find in system structure
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findLatestByMnemonic(mnemonic); List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatestByMnemonic(mnemonic);
List<System> systems = holderIRepositories.getSystemRepository().findLatestByMnemonic(mnemonic); List<WipSystem> systems = holderIWipRepositories.systemRepository().findLatestByMnemonic(mnemonic);
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findLatestByMnemonic(mnemonic); List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findLatestByMnemonic(mnemonic);
for (SystemGroup systemGroup : systemGroups) { for (WipSystemGroup systemGroup : systemGroups) {
partElements.add(PartElementUtil.getPartElement(systemGroup)); partElements.add(PartElementUtil.getPartElement(systemGroup));
} }
for (System system : systems) { for (WipSystem system : systems) {
partElements.add(PartElementUtil.getPartElement(system, holderIRepositories)); partElements.add(PartElementUtil.getPartElement(system, holderIWipRepositories));
} }
for (Subsystem subsystem : subsystems) { for (WipSubsystem subsystem : subsystems) {
partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories)); partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
} }
// find in system structure // find in system structure
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findLatestByMnemonic(mnemonic); List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatestByMnemonic(mnemonic);
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findLatestByMnemonic(mnemonic); List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatestByMnemonic(mnemonic);
for (Discipline discipline : disciplines) { for (WipDiscipline discipline : disciplines) {
partElements.add(PartElementUtil.getPartElement(discipline)); partElements.add(PartElementUtil.getPartElement(discipline));
} }
for (DeviceType deviceType : deviceTypes) { for (WipDeviceType deviceType : deviceTypes) {
partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories)); partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
} }
LOGGER.log(Level.INFO, "findPartsByMnemonic, mnemonic: " + mnemonic); LOGGER.log(Level.FINE, "findPartsByMnemonic, mnemonic: {0}", mnemonic);
LOGGER.log(Level.INFO, "findPartsByMnemonic, partElements.size: " + partElements.size()); LOGGER.log(Level.FINE, "findPartsByMnemonic, partElements.size: {0}", partElements.size());
return partElements; return partElements;
} }
...@@ -167,54 +171,54 @@ public class PartControllerV0 { ...@@ -167,54 +171,54 @@ public class PartControllerV0 {
try { try {
pattern = Pattern.compile(mnemonic); pattern = Pattern.compile(mnemonic);
} catch (PatternSyntaxException e) { } catch (PatternSyntaxException e) {
LOGGER.log(Level.FINE, e.getMessage(), e); logService.logException(LOGGER, Level.WARNING, e);
} }
// find in system structure // find in system structure
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findLatest(); List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatest();
List<System> systems = holderIRepositories.getSystemRepository().findLatest(); List<WipSystem> systems = holderIWipRepositories.systemRepository().findLatest();
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findLatest(); List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findLatest();
for (SystemGroup systemGroup : systemGroups) { for (WipSystemGroup systemGroup : systemGroups) {
String sub = systemGroup.getMnemonic(); String sub = systemGroup.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(systemGroup)); partElements.add(PartElementUtil.getPartElement(systemGroup));
} }
} }
for (System system : systems) { for (WipSystem system : systems) {
String sub = system.getMnemonic(); String sub = system.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { 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(); String sub = subsystem.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories)); partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
} }
} }
// find in device structure // find in device structure
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findLatest(); List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatest();
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findLatest(); List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatest();
for (Discipline discipline : disciplines) { for (WipDiscipline discipline : disciplines) {
String sub = discipline.getMnemonic(); String sub = discipline.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(discipline)); partElements.add(PartElementUtil.getPartElement(discipline));
} }
} }
for (DeviceType deviceType : deviceTypes) { for (WipDeviceType deviceType : deviceTypes) {
String sub = deviceType.getMnemonic(); String sub = deviceType.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories)); partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
} }
} }
LOGGER.log(Level.INFO, "getAllPartsByMnemonicSearch, mnemonic: " + mnemonic); LOGGER.log(Level.FINE, "getAllPartsByMnemonicSearch, mnemonic: {0}", mnemonic);
LOGGER.log(Level.INFO, "getAllPartsByMnemonicSearch, partElements.size: " + partElements.size()); LOGGER.log(Level.FINE, "getAllPartsByMnemonicSearch, partElements.size: {0}", partElements.size());
return partElements; return partElements;
} }
...@@ -239,62 +243,62 @@ public class PartControllerV0 { ...@@ -239,62 +243,62 @@ public class PartControllerV0 {
try { try {
pattern = Pattern.compile(mnemonicPath); pattern = Pattern.compile(mnemonicPath);
} catch (PatternSyntaxException e) { } catch (PatternSyntaxException e) {
LOGGER.log(Level.FINE, e.getMessage(), e); logService.logException(LOGGER, Level.WARNING, e);
} }
// find in system structure // find in system structure
List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findLatest(); List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatest();
List<System> systems = holderIRepositories.getSystemRepository().findLatest(); List<WipSystem> systems = holderIWipRepositories.systemRepository().findLatest();
List<Subsystem> subsystems = holderIRepositories.getSubsystemRepository().findLatest(); List<WipSubsystem> subsystems = holderIWipRepositories.subsystemRepository().findLatest();
for (SystemGroup systemGroup : systemGroups) { for (WipSystemGroup systemGroup : systemGroups) {
String sub = systemGroup.getMnemonic(); String sub = systemGroup.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(systemGroup)); partElements.add(PartElementUtil.getPartElement(systemGroup));
} }
} }
for (System system : systems) { for (WipSystem system : systems) {
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(system.getParentUuid().toString()); 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()) { 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) {
System system = holderIRepositories.getSystemRepository().findLatestByUuid(subsystem.getParentUuid().toString()); WipSystem system = holderIWipRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(system.getParentUuid().toString()); WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
String sub = NamingConventionUtil.mnemonicPath2String(systemGroup.getMnemonic(), system.getMnemonic(), subsystem.getMnemonic()); String sub = NamingConventionUtil.mnemonicPath2String(systemGroup.getMnemonic(), system.getMnemonic(), subsystem.getMnemonic());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories)); partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
} }
} }
// find in device structure // find in device structure
List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findLatest(); List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatest();
List<DeviceType> deviceTypes = holderIRepositories.getDeviceTypeRepository().findLatest(); List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatest();
for (Discipline discipline : disciplines) { for (WipDiscipline discipline : disciplines) {
String sub = discipline.getMnemonic(); String sub = discipline.getMnemonic();
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(discipline)); partElements.add(PartElementUtil.getPartElement(discipline));
} }
} }
for (DeviceType deviceType : deviceTypes) { for (WipDeviceType deviceType : deviceTypes) {
DeviceGroup deviceGroup = holderIRepositories.getDeviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString()); WipDeviceGroup deviceGroup = holderIWipRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString()); WipDiscipline discipline = holderIWipRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
String sub = NamingConventionUtil.mnemonicPath2String(discipline.getMnemonic(), deviceType.getMnemonic()); String sub = NamingConventionUtil.mnemonicPath2String(discipline.getMnemonic(), deviceType.getMnemonic());
if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) { if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories)); partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
} }
} }
LOGGER.log(Level.INFO, "findPartsByMnemonicPathSearch, mnemonicPath: " + mnemonicPath); LOGGER.log(Level.FINE, "findPartsByMnemonicPathSearch, mnemonicPath: {0}", mnemonicPath);
LOGGER.log(Level.INFO, "findPartsByMnemonicPathSearch, partElements.size: " + partElements.size()); LOGGER.log(Level.FINE, "findPartsByMnemonicPathSearch, partElements.size: {0}", partElements.size());
return partElements; return partElements;
} }
......
/*
* 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 { ...@@ -156,8 +156,12 @@ public class RestLogFilter implements Filter {
} }
} }
private final ObjectMapper mapper;
@Autowired @Autowired
private ObjectMapper mapper; public RestLogFilter(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override @Override
public void init(FilterConfig filterConfig) {} public void init(FilterConfig filterConfig) {}
...@@ -166,8 +170,8 @@ public class RestLogFilter implements Filter { ...@@ -166,8 +170,8 @@ public class RestLogFilter implements Filter {
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain) public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
throws IOException, ServletException { throws IOException, ServletException {
HttpServletRequest req = null; HttpServletRequest req = null;
if (request instanceof HttpServletRequest) { if (request instanceof HttpServletRequest object) {
req = (HttpServletRequest)request; req = object;
} }
LogEntry logLine = new LogEntry(); LogEntry logLine = new LogEntry();
...@@ -190,15 +194,15 @@ public class RestLogFilter implements Filter { ...@@ -190,15 +194,15 @@ public class RestLogFilter implements Filter {
logLine.setTime(endTime - startTime); logLine.setTime(endTime - startTime);
HttpServletResponse resp = null; HttpServletResponse resp = null;
if (response instanceof HttpServletResponse) { if (response instanceof HttpServletResponse object) {
resp = (HttpServletResponse) response; resp = object;
} }
if (resp != null) { if (resp != null) {
logLine.setStatusCode(resp.getStatus()); logLine.setStatusCode(resp.getStatus());
} }
} finally { } finally {
if (restRequest) { if (restRequest && LOGGER.isLoggable(Level.INFO)) {
LOGGER.log(Level.INFO, mapper.writeValueAsString(logLine)); 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));
}
}
...@@ -16,94 +16,121 @@ ...@@ -16,94 +16,121 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
package org.openepics.names.util; package org.openepics.names.service;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils; 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. * Utility class to assist in handling of logs.
* *
* @author Lars Johansson * @author Lars Johansson
*/ */
public class LogUtil { @Service
public class LogService {
private static final String ORG_OPENEPICS_NAMES = "org.openepics.names"; private static final String DELIMITER = " ### ";
private static final String ORG_OPENEPICS_NAMES_UTIL_EXCEPTION_UTIL = "org.openepics.names.util.ExceptionUtil";
/** /**
* This class is not to be instantiated. * 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.
*/ */
private LogUtil() { @Value("${naming.logging.filter.includes}")
throw new IllegalStateException("Utility class"); List<String> loggingFilterIncludes;
} /**
* 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.excludes}")
List<String> loggingFilterExcludes;
/**
* 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.stacktrace.length}")
int loggingStackTraceLength;
/** /**
* Log service http status exception. * Log service exception.
*
* @param logger logger
* @param level log level
* @param e service exception
*/
public void logServiceException(Logger logger, Level level, ServiceException e) {
logServiceException(logger, level, e, null);
}
/**
* Log service exception.
* *
* @param logger logger * @param logger logger
* @param level log level * @param level log level
* @param e service https status exception * @param e service exception
* @param msg message (additional and optional)
*/ */
public static void logServiceHttpStatusException(Logger logger, Level level, ServiceHttpStatusException e) { public void logServiceException(Logger logger, Level level, ServiceException e, String msg) {
if (logger == null || level == null || e == null) { if (ValidateUtil.isAnyNull(logger, level, e)) {
return; return;
} }
String msg = !StringUtils.isEmpty(e.getMessage()) String msgException = !StringUtils.isEmpty(msg)
? e.getMessage() ? DELIMITER + msg
: "";
String message = !StringUtils.isEmpty(e.getMessage())
? DELIMITER + e.getMessage()
: ""; : "";
String details = !StringUtils.isEmpty(e.getDetails()) String details = !StringUtils.isEmpty(e.getDetails())
? " ### " + e.getDetails() ? DELIMITER + e.getDetails()
: ""; : "";
String httpStatus = e.getHttpStatus() != null String field = !StringUtils.isEmpty(e.getField())
? " ### " + e.getHttpStatus().toString() ? DELIMITER + e.getField()
: ""; : "";
msg = msg + details + httpStatus; msgException = msgException + message + details + field;
logger.log(level, msg); logger.log(level, msgException);
logStackTraceElements(logger, level, e);
} }
/** /**
* Log stack trace elements. * Log exception.
*
* @param logger logger
* @param level log level
* @param e service https status exception
*/
public static void logStackTraceElements(Logger logger, Level level, ServiceHttpStatusException e) {
logStackTraceElements(logger, Level.SEVERE, e, 10, ORG_OPENEPICS_NAMES, ORG_OPENEPICS_NAMES_UTIL_EXCEPTION_UTIL);
}
/**
* Log stack trace elements.
* *
* @param logger logger * @param logger logger
* @param level log level * @param level log level
* @param e exception * @param e exception
*/ */
public static void logStackTraceElements(Logger logger, Level level, Exception e) { public void logException(Logger logger, Level level, Exception e) {
logStackTraceElements(logger, Level.SEVERE, e, 10, ORG_OPENEPICS_NAMES, ORG_OPENEPICS_NAMES_UTIL_EXCEPTION_UTIL); logException(logger, level, e, null);
} }
/** /**
* Log stack trace elements. * Log exception.
* *
* @param logger logger * @param logger logger
* @param level log level * @param level log level
* @param e service https status exception * @param e exception
* @param maxNumberOfLogs max number of logs * @param msg message (additional and optional)
* @param filterInclude filter include
* @param filterExclude filter exclude
*/ */
public static void logStackTraceElements(Logger logger, Level level, ServiceHttpStatusException e, int maxNumberOfLogs, String filterInclude, String filterExclude) { public void logException(Logger logger, Level level, Exception e, String msg) {
if (logger == null || level == null || e == null || maxNumberOfLogs <= 0) { if (ValidateUtil.isAnyNull(logger, level, e)) {
return; return;
} }
logStackTraceElements(logger, level, e.getStackTrace(), maxNumberOfLogs, filterInclude, filterExclude); if (!StringUtils.isEmpty(msg) ) {
logger.log(level, msg);
}
logStackTraceElements(logger, level, e);
} }
/** /**
...@@ -112,16 +139,20 @@ public class LogUtil { ...@@ -112,16 +139,20 @@ public class LogUtil {
* @param logger logger * @param logger logger
* @param level log level * @param level log level
* @param e exception * @param e exception
* @param maxNumberOfLogs max number of logs
* @param filterInclude filter include
* @param filterExclude filter exclude
*/ */
public static void logStackTraceElements(Logger logger, Level level, Exception e, int maxNumberOfLogs, String filterInclude, String filterExclude) { private void logStackTraceElements(Logger logger, Level level, Exception e) {
if (logger == null || level == null || e == null || maxNumberOfLogs <= 0) { if (ValidateUtil.isAnyNull(logger, level, e)) {
return; 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());
}
} }
/** /**
...@@ -130,29 +161,49 @@ public class LogUtil { ...@@ -130,29 +161,49 @@ public class LogUtil {
* @param logger logger * @param logger logger
* @param level log level * @param level log level
* @param stackTraceElements stack trace elements * @param stackTraceElements stack trace elements
* @param maxNumberOfLogs max number of logs
* @param filterInclude filter include
* @param filterExclude filter exclude
*/ */
private static void logStackTraceElements(Logger logger, Level level, StackTraceElement[] stackTraceElements, int maxNumberOfLogs, String filterInclude, String filterExclude) { private void logStackTraceElements(Logger logger, Level level, StackTraceElement[] stackTraceElements) {
if (logger == null || level == null || stackTraceElements == null || maxNumberOfLogs <= 0) { if (ValidateUtil.isAnyNull(logger, level, stackTraceElements)) {
return; return;
} }
String str; String str = null;
int count = 0; 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) { for (StackTraceElement stackTraceElement : stackTraceElements) {
str = stackTraceElement.toString(); str = stackTraceElement.toString();
if ((StringUtils.isEmpty(filterInclude) || str.contains(filterInclude)) if ((emptyFilterInclude || ValidateUtil.isAnyMatch(patternsFilterInclude, str))
&& !(!StringUtils.isEmpty(filterExclude) && str.contains(filterExclude))) { && !(!emptyFilterExclude && ValidateUtil.isAnyMatch(patternsFilterExclude, str))) {
count++; count++;
logger.log(level, str); logger.log(level, str);
if (count == maxNumberOfLogs) { if (count == loggingStackTraceLength) {
break; 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,14 +18,16 @@ ...@@ -18,14 +18,16 @@
package org.openepics.names.service; package org.openepics.names.service;
import java.util.Collections; import java.text.MessageFormat;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
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.IDeviceGroupRepository;
import org.openepics.names.repository.IDeviceTypeRepository; import org.openepics.names.repository.IDeviceTypeRepository;
import org.openepics.names.repository.IDisciplineRepository; import org.openepics.names.repository.IDisciplineRepository;
...@@ -33,24 +35,39 @@ import org.openepics.names.repository.INameRepository; ...@@ -33,24 +35,39 @@ import org.openepics.names.repository.INameRepository;
import org.openepics.names.repository.ISubsystemRepository; import org.openepics.names.repository.ISubsystemRepository;
import org.openepics.names.repository.ISystemGroupRepository; import org.openepics.names.repository.ISystemGroupRepository;
import org.openepics.names.repository.ISystemRepository; 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.NameRepository;
import org.openepics.names.repository.model.DeviceGroup; import org.openepics.names.repository.SubsystemRepository;
import org.openepics.names.repository.SystemGroupRepository;
import org.openepics.names.repository.SystemRepository;
import org.openepics.names.repository.model.AuditName;
import org.openepics.names.repository.model.DeviceType; import org.openepics.names.repository.model.DeviceType;
import org.openepics.names.repository.model.Discipline; import org.openepics.names.repository.model.Discipline;
import org.openepics.names.repository.model.Name; 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.Subsystem;
import org.openepics.names.repository.model.System;
import org.openepics.names.repository.model.SystemGroup; import org.openepics.names.repository.model.SystemGroup;
import org.openepics.names.rest.beans.FieldName; import org.openepics.names.rest.beans.FieldName;
import org.openepics.names.rest.beans.NameElement;
import org.openepics.names.rest.beans.Status; import org.openepics.names.rest.beans.Status;
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.EssNamingConvention;
import org.openepics.names.util.HolderIRepositories; import org.openepics.names.util.HolderIRepositories;
import org.openepics.names.util.HolderSystemDeviceStructure; import org.openepics.names.util.HolderRepositories;
import org.openepics.names.util.HolderStructures;
import org.openepics.names.util.NameElementUtil; import org.openepics.names.util.NameElementUtil;
import org.openepics.names.util.ValidateUtil; import org.openepics.names.util.NameUtil;
import org.openepics.names.util.TextUtil;
import org.openepics.names.util.ValidateNameElementUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
...@@ -63,18 +80,21 @@ import com.google.common.collect.Lists; ...@@ -63,18 +80,21 @@ import com.google.common.collect.Lists;
@Service @Service
public class NamesService { public class NamesService {
// HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return // note
// default
// for each method // active means valid not deleted
// document what values come from NameElement and what values come from persistence layer // obsolete values are not shown unless history is requested
// somehow provide this information to user // handling of system structure, device 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 static final Logger LOGGER = Logger.getLogger(NamesService.class.getName());
private EssNamingConvention namingConvention; private final EssNamingConvention namingConvention;
private final HolderIRepositories holderIRepositories;
private HolderIRepositories holderIRepositories; private final HolderRepositories holderRepositories;
private NameRepository nameRepository;
@Autowired @Autowired
public NamesService( public NamesService(
...@@ -85,7 +105,17 @@ public class NamesService { ...@@ -85,7 +105,17 @@ public class NamesService {
IDisciplineRepository iDisciplineRepository, IDisciplineRepository iDisciplineRepository,
IDeviceGroupRepository iDeviceGroupRepository, IDeviceGroupRepository iDeviceGroupRepository,
IDeviceTypeRepository iDeviceTypeRepository, IDeviceTypeRepository iDeviceTypeRepository,
NameRepository nameRepository) { IAuditNameRepository iAuditNameRepository,
IAuditStructureRepository iAuditStructureRepository,
NameRepository nameRepository,
SystemGroupRepository systemGroupRepository,
SystemRepository systemRepository,
SubsystemRepository subsystemRepository,
DisciplineRepository disciplineRepository,
DeviceGroupRepository deviceGroupRepository,
DeviceTypeRepository deviceTypeRepository,
AuditNameRepository auditNameRepository,
AuditStructureRepository auditStructureRepository) {
this.namingConvention = new EssNamingConvention(); this.namingConvention = new EssNamingConvention();
this.holderIRepositories = new HolderIRepositories( this.holderIRepositories = new HolderIRepositories(
...@@ -95,598 +125,662 @@ public class NamesService { ...@@ -95,598 +125,662 @@ public class NamesService {
iSubsystemRepository, iSubsystemRepository,
iDisciplineRepository, iDisciplineRepository,
iDeviceGroupRepository, iDeviceGroupRepository,
iDeviceTypeRepository); iDeviceTypeRepository,
this.nameRepository = nameRepository; iAuditNameRepository,
iAuditStructureRepository);
this.holderRepositories = new HolderRepositories(
nameRepository,
systemGroupRepository,
systemRepository,
subsystemRepository,
disciplineRepository,
deviceGroupRepository,
deviceTypeRepository,
auditNameRepository,
auditStructureRepository);
} }
@Transactional @Transactional
public List<NameElement> createNames(List<NameElement> nameElements) { public List<NameElement> createNames(List<NameElementCommand> nameElementCommands, String username) {
// validate // validation outside method
// outside of @Transactional
// transaction // transaction
// do // for each name element
// for each name element // create name
// create name, latest, with data // handle name element for created name
// add name element for created // no notify
// return // return name elements for created names
// name elements for created names
LOGGER.log(Level.INFO, "createNames, nameElements.size: " + String.valueOf(nameElements != null ? nameElements.size() : "null")); // holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// do Date when = new Date();
String requestedBy = "test who";
final List<NameElement> createdNameElements = Lists.newArrayList(); final List<NameElement> createdNameElements = Lists.newArrayList();
for (NameElement nameElement : nameElements) { for (NameElementCommand nameElementCommand : nameElementCommands) {
// create NameElement createdNameElement = createName(nameElementCommand, when, username, holderStructures);
Name name = new Name(); createdNameElements.add(createdNameElement);
setAttributes(name,
UUID.randomUUID(), if (LOGGER.isLoggable(Level.FINER)) {
nameElement.getSystemgroup(), nameElement.getSystem(), nameElement.getSubsystem(), nameElement.getDevicetype(), LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_NAME, TextUtil.ELEMENT_IN, nameElementCommand));
nameElement.getIndex(), nameElement.getName(), namingConvention.equivalenceClassRepresentative(nameElement.getName()), LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_NAME, TextUtil.ELEMENT_OUT, createdNameElement));
nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE, }
new Date(), requestedBy, nameElement.getComment());
nameRepository.createName(name);
// possibly validate that created
// approved, latest, not deleted, uuid
// add
createdNameElements.add(NameElementUtil.getNameElement(name));
} }
LOGGER.log(Level.INFO, "createNames, createdNameElements.size: " + createdNameElements.size()); LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Create names",
nameElementCommands.size(),
createdNameElements.size()));
return createdNameElements; return createdNameElements;
} }
// ---------------------------------------------------------------------------------------------------- @Transactional(propagation = Propagation.MANDATORY)
public NameElement createName(NameElementCommand nameElementCommand, Date when, String username, HolderStructures holderStructures) {
public List<NameElement> readNames( return createName(nameElementCommand, when, username, holderStructures, null);
Boolean deleted, FieldName[] queryFields, String[] queryValues,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
return readNames(deleted, queryFields, queryValues, Boolean.FALSE, orderBy, isAsc, offset, limit);
} }
@Transactional(propagation = Propagation.MANDATORY)
public List<NameElement> readNames( public NameElement createName(NameElementCommand nameElementCommand, Date when, String username, HolderStructures holderStructures, Structure structure) {
Boolean deleted, FieldName[] queryFields, String[] queryValues, Boolean includeHistory, // validation outside method
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { // transaction
// support a current transaction, throw an exception if none exists
LOGGER.log(Level.INFO, "readNames, deleted: " + deleted); // find & prepare
LOGGER.log(Level.INFO, "readNames, queryFields.length: " + String.valueOf(queryFields != null ? queryFields.length : "null")); // create name
LOGGER.log(Level.INFO, "readNames, queryValues.length: " + String.valueOf(queryValues != null ? queryValues.length : "null")); // create audit
LOGGER.log(Level.INFO, "readNames, includeHistory: " + includeHistory); // return name element for created name
LOGGER.log(Level.INFO, "readNames, orderBy: " + orderBy);
LOGGER.log(Level.INFO, "readNames, isAsc: " + isAsc); UUID uuid = UUID.randomUUID();
LOGGER.log(Level.INFO, "readNames, offset: " + offset); UUID parentSystemStructure = nameElementCommand.getParentSystemStructure();
LOGGER.log(Level.INFO, "readNames, limit: " + limit); UUID parentDeviceStructure = nameElementCommand.getParentDeviceStructure();
if (queryFields != null && queryFields.length > 0) { String index = nameElementCommand.getIndex();
for (FieldName queryField : queryFields) { String description = nameElementCommand.getDescription();
LOGGER.log(Level.INFO, "readNames, queryField: " + queryField); String comment = null;
}
} // find & prepare
if (queryValues != null && queryValues.length > 0) { // system structure - system group, system, subsystem - one of the three expected to be non-null, other two expected to be null
for (String queryValue : queryValues) { // device structure - device type - may be null
LOGGER.log(Level.INFO, "readNames, queryValue: " + queryValue); 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());
} }
// validate input String derivedName = null;
// queryFields and queryValues if (systemGroup != null) {
// uuid derivedName = NameUtil.getName(systemGroup, deviceType, index, holderStructures);
// do } else if (system != null) {
// read names derivedName = NameUtil.getName(system, deviceType, index, holderStructures);
// return } else if (subsystem != null) {
// name elements for names derivedName = NameUtil.getName(subsystem, deviceType, index, holderStructures);
// validate input
ValidateUtil.validateNamesInputRead(
deleted, queryFields, queryValues,
includeHistory,
orderBy, isAsc,
offset, limit);
// do
List<Name> names = nameRepository.readNames(deleted, queryFields, queryValues, includeHistory, orderBy, isAsc, offset, limit);
final List<NameElement> nameElements = Lists.newArrayList();
for (Name name : names) {
nameElements.add(NameElementUtil.getNameElement(name));
} }
LOGGER.log(Level.INFO, "readNames, nameElements.size: " + nameElements.size()); // create name
return nameElements; // 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 List<NameElement> readNames( // ----------------------------------------------------------------------------------------------------
String name,
public ResponsePageNameElements readNames(Boolean deleted,
String uuid, String name, String systemStructure, String deviceStructure, String index, String description, String who,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
return readNames(deleted,
uuid, name, systemStructure, deviceStructure, index, description, who,
Boolean.FALSE, orderBy, isAsc, offset, limit);
}
LOGGER.log(Level.INFO, "readNames, name: " + name); public ResponsePageNameElements readNames(Boolean deleted,
String uuid, String name, String systemStructure, String deviceStructure, String index, String description, String who,
// validate input Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
// name or uuid // validation outside method
// to work with both uuid and name // read names
// do // return name elements for names
// name or uuid
// return if (LOGGER.isLoggable(Level.FINE)) {
// name elements 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));
// validate input LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "name", name));
ValidateUtil.validateInputName(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));
// do LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "index", index));
final List<NameElement> nameElements = Lists.newArrayList(); LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "description", description));
try { LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "who", who));
UUID.fromString(name); LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "includeHistory", includeHistory));
Name latestByUuid = holderIRepositories.getNameRepository().findLatestByUuid(name); LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "orderBy", orderBy));
if (latestByUuid != null) { LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "isAsc", isAsc));
nameElements.add(NameElementUtil.getNameElement(latestByUuid)); 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));
} catch (IllegalArgumentException e) {
nameElements.addAll(readNames(false, new FieldName[] {FieldName.NAME}, new String[] {name}, orderBy, isAsc, offset, limit));
} }
LOGGER.log(Level.INFO, "readNames, nameElements.size: " + nameElements.size()); // holder of valid content for system and device structures
return nameElements; HolderStructures holderStructures = new HolderStructures(holderIRepositories);
}
public List<NameElement> readNamesSystemStructure(
String mnemonicpath,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
LOGGER.log(Level.INFO, "readNamesSystemStructure, mnemonicpath: " + mnemonicpath); // 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);
// validate input nameElements = NameElementUtil.getNameElementsForAuditNames(auditNames, holderStructures);
// mnemonic path } else {
// do List<Name> names = holderRepositories.nameRepository().readNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who, orderBy, isAsc, offset, limit);
// mnemonic path totalCount = holderRepositories.nameRepository().countNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who);
// return
// name elements
// validate input nameElements = NameElementUtil.getNameElements(names, holderStructures);
ValidateUtil.validateInputMnemonicpath(mnemonicpath); }
// do ResponsePageNameElements response = new ResponsePageNameElements(nameElements, totalCount, nameElements.size(), offset, limit);
return readNames(false, new FieldName[] {FieldName.SYSTEMSTRUCTURE}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit); LOGGER.log(Level.FINE,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_RESPONSE,
TextUtil.READ_NAMES,
response.toString()));
return response;
} }
public List<NameElement> readNamesDeviceStructure( public ResponsePageNameElements readNamesStructure(String uuid, Boolean deleted,
String mnemonicpath,
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { 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.INFO, "readNamesDeviceStructure, mnemonicpath: " + mnemonicpath); // there are different kinds of references to structure ids for names, directly and indirectly, both are included
// directly
// validate input // system group
// mnemonic path // system
// do // subsystem
// mnemonic path // device type
// return // indirectly
// name elements // 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);
LOGGER.log(Level.FINE,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_RESPONSE,
TextUtil.READ_NAMES_STRUCTURE,
response.toString()));
return response;
}
// validate input private List<NameElement> paginate(List<NameElement> list, Integer offset, Integer limit) {
ValidateUtil.validateInputMnemonicpath(mnemonicpath); // 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;
}
// do List<NameElement> listPagination = Lists.newArrayList();
return readNames(false, new FieldName[] {FieldName.DEVICESTRUCTURE}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit); 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 List<NameElement> readNamesHistory( public ResponsePageNameElements readNamesHistory(String uuid, Integer offset, Integer limit) {
String uuid, // validation outside method
FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { // read history for name
LOGGER.log(Level.INFO, "readNamesHistory, uuid: " + uuid); // return name elements for names
// 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
List<NameElement> nameElements = readNames(null, new FieldName[] {FieldName.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit);
Collections.sort(nameElements, new Comparator<NameElement>() {
@Override
public int compare(NameElement e1, NameElement e2) {
return e1.getWhen().compareTo(e2.getWhen());
}
});
LOGGER.log(Level.INFO, "readNamesHistory, nameElements.size: " + nameElements.size()); LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "uuid", uuid));
return nameElements; return readNames(null,
uuid, null, null, null, null, null, null,
Boolean.TRUE, FieldName.WHEN, Boolean.TRUE, offset, limit);
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
public String equivalenceName(String name) {
LOGGER.log(Level.INFO, "equivalenceName, name: " + name);
// validate input
// do
// exists
// validate input
ValidateUtil.validateInputName(name);
// do
return namingConvention.equivalenceClassRepresentative(name);
}
public Boolean existsName(String name) { public Boolean existsName(String name) {
LOGGER.log(Level.INFO, "existsName, name: " + name); // validation outside method
// read exists
// validate input
// do
// exists
// validate input LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.EXISTS_NAME, "name", name));
ValidateUtil.validateInputName(name);
// do List<Name> names = holderRepositories.nameRepository().readNames(false,
List<Name> names = nameRepository.readNames(false, FieldName.NAME, name); null, name, null, null, null, null, null, null);
return !names.isEmpty(); return !names.isEmpty();
} }
public Boolean isLegacyName(String name) {
LOGGER.log(Level.INFO, "isLegacyName, name: " + name);
// validate input
// do
// exists
// validate input
ValidateUtil.validateInputName(name);
// do
List<Name> names = nameRepository.readNames(false, FieldName.NAME, name);
ValidateUtil.validateCondition(names != null && names.size() == 1, HttpStatus.BAD_REQUEST, "name not available", name);
Name toBeChecked = names.get(0);
// system structure
if (toBeChecked.getSystemgroupUuid() != null) {
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemgroupUuid().toString());
ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, "system group not available", name);
if (systemGroup.isDeleted()) {
return Boolean.TRUE;
}
} else if (toBeChecked.getSystemUuid() != null) {
org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemUuid().toString());
ValidateUtil.validateCondition(system != null, HttpStatus.BAD_REQUEST, "system not available", name);
if (system.isDeleted()) {
return Boolean.TRUE;
}
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString());
ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, "system group not available", name);
if (systemGroup.isDeleted()) {
return Boolean.TRUE;
}
} else if (toBeChecked.getSubsystemUuid() != null) {
Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSubsystemUuid().toString());
ValidateUtil.validateCondition(subsystem != null, HttpStatus.BAD_REQUEST, "subsystem not available", name);
if (subsystem.isDeleted()) {
return Boolean.TRUE;
}
org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(subsystem.getParentUuid().toString());
ValidateUtil.validateCondition(system != null, HttpStatus.BAD_REQUEST, "system not available", name);
if (system.isDeleted()) {
return Boolean.TRUE;
}
SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString());
ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, "system group not available", name);
if (systemGroup.isDeleted()) {
return Boolean.TRUE;
}
}
// device structure
if (toBeChecked.getDevicetypeUuid() != null) {
DeviceType deviceType = holderIRepositories.getDeviceTypeRepository().findLatestNotDeletedByUuid(toBeChecked.getDevicetypeUuid().toString());
ValidateUtil.validateCondition(deviceType != null, HttpStatus.BAD_REQUEST, "device type not available", name);
if (deviceType.isDeleted()) {
return Boolean.TRUE;
}
DeviceGroup deviceGroup = holderIRepositories.getDeviceGroupRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString());
ValidateUtil.validateCondition(deviceGroup != null, HttpStatus.BAD_REQUEST, "device group not available", name);
if (deviceGroup.isDeleted()) {
return Boolean.TRUE;
}
Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString());
ValidateUtil.validateCondition(discipline != null, HttpStatus.BAD_REQUEST, "device group not available", name);
if (discipline.isDeleted()) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
public Boolean isValidToCreateName(String name) { public Boolean isValidToCreateName(String name) {
LOGGER.log(Level.INFO, "isValidToCreateName, name: " + name); // validation outside method
// validate data - not exists
// validate input
// validate data
// not exists
// validate input LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_VALID_TO_CREATE_NAME, "name", name));
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 // 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, holderStructures);
ValidateUtil.validateNameDataCreate(name, namingConvention, holderIRepositories, nameRepository, holder);
return Boolean.TRUE; return Boolean.TRUE;
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
public void validateNamesCreate(NameElement nameElement) { public void validateNamesCreate(NameElementCommand nameElement) {
validateNamesCreate(nameElement, new HolderSystemDeviceStructure(holderIRepositories)); validateNamesCreate(nameElement, new HolderStructures(holderIRepositories));
} }
public void validateNamesCreate(NameElement nameElement, HolderSystemDeviceStructure holder) { public void validateNamesCreate(NameElementCommand nameElement, HolderStructures holderStructures) {
// validate authority // validate name element
// elsewhere // input vs given task
// naming user & admin // data vs given task
// validate input
// name element ValidateNameElementUtil.validateNameElementInputCreate(nameElement);
// validate input itself ValidateNameElementUtil.validateNameElementDataCreate(nameElement, namingConvention,
// validate data holderIRepositories, holderRepositories, holderStructures);
// name element
// validate towards repository
// validate input
ValidateUtil.validateNameElementInputCreate(nameElement);
// validate data
ValidateUtil.validateNameElementDataCreate(nameElement, namingConvention, holderIRepositories, nameRepository, holder);
} }
public void validateNamesCreate(List<NameElement> nameElements) { public void validateNamesCreate(List<NameElementCommand> nameElements) {
// initiate holder of containers for system and device structure content, for performance reasons // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (NameElement nameElement : nameElements) { for (NameElementCommand nameElement : nameElements) {
validateNamesCreate(nameElement, holder); validateNamesCreate(nameElement, holderStructures);
} }
} }
public void validateNamesUpdate(NameElement nameElement) { public void validateNamesUpdate(NameElementCommand nameElement) {
validateNamesUpdate(nameElement, new HolderSystemDeviceStructure(holderIRepositories)); validateNamesUpdate(nameElement, new HolderStructures(holderIRepositories));
} }
public void validateNamesUpdate(NameElement nameElement, HolderSystemDeviceStructure holder) { public void validateNamesUpdate(NameElementCommand nameElement, HolderStructures holderStructures) {
// validate authority // validate name element
// elsewhere // input vs given task
// naming user & admin // data vs given task
// validate input
// name element ValidateNameElementUtil.validateNameElementInputUpdate(nameElement);
// validate input itself ValidateNameElementUtil.validateNameElementDataUpdate(nameElement, namingConvention,
// validate data holderIRepositories, holderRepositories, holderStructures);
// name element
// validate towards repository
// validate input
ValidateUtil.validateNameElementInputUpdate(nameElement);
// validate data
ValidateUtil.validateNameElementDataUpdate(nameElement, namingConvention, holderIRepositories, nameRepository, holder);
} }
public void validateNamesUpdate(List<NameElement> nameElements) { public void validateNamesUpdate(List<NameElementCommand> nameElements) {
// initiate holder of containers for system and device structure content, for performance reasons // holder of valid content for system and device structures
HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); HolderStructures holderStructures = new HolderStructures(holderIRepositories);
for (NameElement nameElement : nameElements) { for (NameElementCommand nameElement : nameElements) {
validateNamesUpdate(nameElement, holder); validateNamesUpdate(nameElement, holderStructures);
} }
} }
public void validateNamesDelete(NameElement nameElement) { public void validateNamesDelete(NameElementCommand nameElement) {
validateNamesDelete(nameElement, new HolderSystemDeviceStructure(holderIRepositories)); validateNamesDelete(nameElement, new HolderStructures(holderIRepositories));
} }
public void validateNamesDelete(NameElement nameElement, HolderSystemDeviceStructure holder) { public void validateNamesDelete(NameElementCommand nameElement, HolderStructures holderStructures) {
// validate authority // validate name element
// elsewhere // input vs given task
// naming user & admin // data vs given task
// validate input
// uuid ValidateNameElementUtil.validateNameElementInputDelete(nameElement);
// validate data ValidateNameElementUtil.validateNameElementDataDelete(nameElement, namingConvention,
// retrieve name (uuid, latest, not deleted) holderIRepositories, holderRepositories, holderStructures);
// validate input
ValidateUtil.validateNameElementInputDelete(nameElement);
// validate data
ValidateUtil.validateNameElementDataDelete(nameElement, namingConvention, holderIRepositories, nameRepository, holder);
} }
public void validateNamesDelete(List<NameElement> nameElements) { public void validateNamesDelete(List<NameElementCommand> nameElements) {
// validate authority // holder of valid content for system and device structures
// elsewhere HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// naming user & admin
// validate input for (NameElementCommand nameElement : nameElements) {
// name element validateNamesDelete(nameElement, holderStructures);
// 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);
for (NameElement nameElement : nameElements) {
validateNamesDelete(nameElement, holder);
} }
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Transactional @Transactional
public List<NameElement> updateNames(List<NameElement> nameElements) { public List<NameElement> updateNames(List<NameElementCommand> nameElementCommands, String username) {
// validate // validation outside method
// outside of @Transactional
// transaction // transaction
// do // for each name element
// for each name element // find & prepare
// update name to not latest // update name
// insert name to latest, not deleted, with data // create audit
// read // handle name element for updated name
// return // no notify
// name elements for updated names // return name elements for updated names
LOGGER.log(Level.INFO, "updateNames, nameElements.size: " + String.valueOf(nameElements != null ? nameElements.size() : "null")); // holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// do
String requestedBy = "test who"; Date when = new Date();
final List<NameElement> updatedNameElements = Lists.newArrayList(); final List<NameElement> updatedNameElements = Lists.newArrayList();
for (NameElement nameElement : nameElements) { for (NameElementCommand nameElementCommand : nameElementCommands) {
// update not latest, not deleted UUID uuid = nameElementCommand.getUuid();
// create latest, not deleted 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) { if (name == null) {
continue; continue;
} }
// skip if name element has same content as name // skip if name element has same content as name
// proceed without fail // proceed without fail
if (NameElementUtil.hasSameContent(nameElement, name)) { if (NameElementUtil.hasSameContent(nameElementCommand, name, holderIRepositories, holderStructures)) {
continue; continue;
} }
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));
}
}
// update LOGGER.log(Level.INFO,
name.setLatest(Boolean.FALSE); () -> MessageFormat.format(
nameRepository.updateName(name); TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Update names",
// create nameElementCommands.size(),
name = new Name(); updatedNameElements.size()));
setAttributes(name, return updatedNameElements;
nameElement.getUuid(), }
nameElement.getSystemgroup(), nameElement.getSystem(), nameElement.getSubsystem(), nameElement.getDevicetype(),
nameElement.getIndex(), nameElement.getName(), namingConvention.equivalenceClassRepresentative(nameElement.getName()),
nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
new Date(), requestedBy, nameElement.getComment());
nameRepository.createName(name);
// 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 // update names
updatedNameElements.add(NameElementUtil.getNameElement(name)); updatedNameElements = updateNames(nameElements, username);
} }
LOGGER.log(Level.INFO, "updateNames, updatedNameElements.size: " + updatedNameElements.size());
return updatedNameElements; return updatedNameElements;
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
@Transactional @Transactional
public List<NameElement> deleteNames(List<NameElement> nameElements) { public List<NameElement> deleteNames(List<NameElementCommand> nameElementCommands, String username) {
// validate // validation outside method
// outside of @Transactional
// transaction // transaction
// do // for each name element
// update name to not latest // delete name (update)
// insert name to latest, deleted // create audit
// read // handle name element for deleted name (updated)
// return // no notify
// name element for deleted name // return name elements for deleted names
LOGGER.log(Level.INFO, "deleteNames, nameElements.size: " + String.valueOf(nameElements != null ? nameElements.size() : "null")); // holder of valid content for system and device structures
HolderStructures holderStructures = new HolderStructures(holderIRepositories);
// do Date when = new Date();
String requestedBy = "test who";
final List<NameElement> deletedNameElements = Lists.newArrayList(); final List<NameElement> deletedNameElements = Lists.newArrayList();
for (NameElement nameElement : nameElements) { for (NameElementCommand nameElementCommand : nameElementCommands) {
Name name = holderIRepositories.getNameRepository().findLatestByUuid(nameElement.getUuid().toString()); UUID uuid = nameElementCommand.getUuid();
String comment = null;
// update
// create audit
Name name = holderIRepositories.nameRepository().findByUuid(uuid.toString());
if (name == null) { if (name == null) {
continue; 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); NameElement deletedNameElement = NameElementUtil.getNameElement(name, holderStructures);
nameRepository.updateName(name); deletedNameElements.add(deletedNameElement);
name = new Name();
setAttributes(name,
nameElement.getUuid(),
nameElement.getSystemgroup(), nameElement.getSystem(), nameElement.getSubsystem(), nameElement.getDevicetype(),
nameElement.getIndex(), nameElement.getName(), namingConvention.equivalenceClassRepresentative(nameElement.getName()),
nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
new Date(), requestedBy, nameElement.getComment());
nameRepository.createName(name);
// possibly validate that deleted if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_NAME, TextUtil.ELEMENT_IN, nameElementCommand));
// add LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_NAME, TextUtil.ELEMENT_OUT, deletedNameElement));
deletedNameElements.add(NameElementUtil.getNameElement(name)); }
} }
LOGGER.log(Level.INFO, "deleteNames, deletedNameElements.size: " + deletedNameElements.size()); LOGGER.log(Level.INFO,
() -> MessageFormat.format(
TextUtil.DESCRIPTION_NUMBER_ELEMENTS_IN_OUT,
"Delete names",
nameElementCommands.size(),
deletedNameElements.size()));
return deletedNameElements; return deletedNameElements;
} }
// ---------------------------------------------------------------------------------------------------- @Transactional(propagation = Propagation.MANDATORY)
public List<NameElement> deleteNames(Structure structure, String username, HolderStructures holderStructures) {
/** // validation outside method
* Utility method to help set attributes for Name class. // transaction
* // support a current transaction, throw an exception if none exists
* @param name name // find out names referenced by structure
* @param uuid uuid // prepare name element commands
* @param systemgroupUuid system group uuid // delete names (update)
* @param systemUuid system uuid // no notify
* @param subsystemUuid subsystem uuid // return name elements for deleted names (updated)
* @param devicetypeUuid device type uuid
* @param index index List<NameElement> deletedNameElements = Lists.newArrayList();
* @param conventionName convention name if (structure != null) {
* @param conventionNameEquivalence convention name equivalence List<Name> names = null;
* @param description description List<NameElementCommand> nameElements = Lists.newArrayList();
* @param status status UUID parentSystemStructureUuid = null;
* @param latest latest UUID parentDeviceStructureUuid = null;
* @param deleted deleted
* @param requested requested if (structure instanceof SystemGroup) {
* @param requestedBy requested by names = holderIRepositories.nameRepository().findNotDeletedBySystemGroupUuid(structure.getUuid().toString());
* @param requestedComment requested comment for (Name name : names) {
*/ parentSystemStructureUuid = NameElementUtil.getSystemGroupUuid(name, holderStructures);
private void setAttributes(Name name, parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
UUID uuid, UUID systemgroupUuid, UUID systemUuid, UUID subsystemUuid, UUID devicetypeUuid, nameElements.add(
String index, String conventionName, String conventionNameEquivalence, new NameElementCommand(
String description, Status status, Boolean latest, Boolean deleted, name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
Date requested, String requestedBy, String requestedComment) { name.getInstanceIndex(), name.getDescription()));
name.setUuid(uuid); }
name.setSystemgroupUuid(systemgroupUuid); } else if (structure instanceof System) {
name.setSystemUuid(systemUuid); names = holderIRepositories.nameRepository().findNotDeletedBySystemUuid(structure.getUuid().toString());
name.setSubsystemUuid(subsystemUuid); for (Name name : names) {
name.setDevicetypeUuid(devicetypeUuid); parentSystemStructureUuid = NameElementUtil.getSystemUuid(name, holderStructures);
name.setInstanceIndex(index); parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
name.setConventionName(conventionName); nameElements.add(
name.setConventionNameEquivalence(conventionNameEquivalence); new NameElementCommand(
name.setDescription(description); name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
name.setStatus(Status.APPROVED); name.getInstanceIndex(), name.getDescription()));
name.setLatest(latest); }
name.setDeleted(deleted); } else if (structure instanceof Subsystem) {
name.setRequested(requested); names = holderIRepositories.nameRepository().findNotDeletedBySubsystemUuid(structure.getUuid().toString());
name.setRequestedBy(requestedBy); for (Name name : names) {
name.setRequestedComment(requestedComment); 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()));
}
}
// delete names
deletedNameElements = deleteNames(nameElements, username);
}
return deletedNameElements;
} }
} }