From f29b22859061996349ad5725c66dd7b3f19a7da9 Mon Sep 17 00:00:00 2001
From: Lars Johansson <lars.johansson@ess.eu>
Date: Fri, 2 Dec 2022 17:46:58 +0100
Subject: [PATCH] Fix bugs for names and structures

Fix bug for create name after approve create for system structure-
Name to be created after create approve, not after update approve, delete approve.

Fix bug for is legacy name.
Updates in checks if structure entries are available.

Update unit test for legacy name.
---
 .../openepics/names/service/NamesService.java | 62 ++++++--------
 .../names/service/StructuresService.java      | 22 ++++-
 .../names/util/ValidateNameElementUtil.java   |  2 +
 .../org/openepics/names/docker/NamesIT.java   | 83 +++++++++++++++++--
 4 files changed, 123 insertions(+), 46 deletions(-)

diff --git a/src/main/java/org/openepics/names/service/NamesService.java b/src/main/java/org/openepics/names/service/NamesService.java
index c1e1d29b..97cb80a9 100644
--- a/src/main/java/org/openepics/names/service/NamesService.java
+++ b/src/main/java/org/openepics/names/service/NamesService.java
@@ -404,7 +404,7 @@ public class NamesService {
 
         // validate input
         // do
-        //     exists
+        //     name exists but either parent does not exist (latest, not deleted, by uuid)
 
         // validate input
         ValidateUtil.validateInputName(name);
@@ -417,77 +417,63 @@ public class NamesService {
 
         // system structure
         if (toBeChecked.getSystemgroupUuid() != null) {
-            SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemgroupUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(systemGroup != null,
-                    TextUtil.SYSTEMGROUP_IS_NOT_AVAILABLE, name, null);
+            // system group
 
-            if (systemGroup.isDeleted()) {
+            SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemgroupUuid().toString());
+            if (systemGroup == null) {
                 return Boolean.TRUE;
             }
         } else if (toBeChecked.getSystemUuid() != null) {
-            org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(system != null,
-                    TextUtil.SYSTEM_IS_NOT_AVAILABLE, name, null);
+            // system
+            // system group
 
-            if (system.isDeleted()) {
+            org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemUuid().toString());
+            if (system == null) {
                 return Boolean.TRUE;
             }
 
             SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(systemGroup != null,
-                    TextUtil.SYSTEMGROUP_IS_NOT_AVAILABLE, name, null);
-
-            if (systemGroup.isDeleted()) {
+            if (systemGroup == null) {
                 return Boolean.TRUE;
             }
         } else if (toBeChecked.getSubsystemUuid() != null) {
-            Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSubsystemUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(subsystem != null,
-                    TextUtil.SUBSYSTEM_IS_NOT_AVAILABLE, name, null);
+            // subsystem
+            // system
+            // system group
 
-            if (subsystem.isDeleted()) {
+            Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSubsystemUuid().toString());
+            if (subsystem == null) {
                 return Boolean.TRUE;
             }
 
             org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(subsystem.getParentUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(system != null,
-                    TextUtil.SYSTEM_IS_NOT_AVAILABLE, name, null);
-
-            if (system.isDeleted()) {
+            if (system == null) {
                 return Boolean.TRUE;
             }
 
             SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(systemGroup != null,
-                    TextUtil.SYSTEMGROUP_IS_NOT_AVAILABLE, name, null);
-
-            if (systemGroup.isDeleted()) {
+            if (systemGroup == null) {
                 return Boolean.TRUE;
             }
         }
         // device structure
         if (toBeChecked.getDevicetypeUuid() != null) {
-            DeviceType deviceType = holderIRepositories.getDeviceTypeRepository().findLatestNotDeletedByUuid(toBeChecked.getDevicetypeUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(deviceType != null,
-                    TextUtil.DEVICETYPE_IS_NOT_AVAILABLE, name, null);
+            // devie type
+            // device group
+            // discipline
 
-            if (deviceType.isDeleted()) {
+            DeviceType deviceType = holderIRepositories.getDeviceTypeRepository().findLatestNotDeletedByUuid(toBeChecked.getDevicetypeUuid().toString());
+            if (deviceType == null) {
                 return Boolean.TRUE;
             }
 
             DeviceGroup deviceGroup = holderIRepositories.getDeviceGroupRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(deviceGroup != null,
-                    TextUtil.DEVICEGROUP_IS_NOT_AVAILABLE, name, null);
-
-            if (deviceGroup.isDeleted()) {
+            if (deviceGroup == null) {
                 return Boolean.TRUE;
             }
 
-            Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString());
-            ExceptionUtil.validateConditionDataNotAvailableException(discipline != null,
-                    TextUtil.DEVICEGROUP_IS_NOT_AVAILABLE, name, null);
-
-            if (discipline.isDeleted()) {
+            Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestNotDeletedByUuid(deviceGroup.getParentUuid().toString());
+            if (discipline == null) {
                 return Boolean.TRUE;
             }
         }
diff --git a/src/main/java/org/openepics/names/service/StructuresService.java b/src/main/java/org/openepics/names/service/StructuresService.java
index 065a9232..f80d0df8 100644
--- a/src/main/java/org/openepics/names/service/StructuresService.java
+++ b/src/main/java/org/openepics/names/service/StructuresService.java
@@ -62,6 +62,7 @@ import org.openepics.names.util.TextUtil;
 import org.openepics.names.util.Utilities;
 import org.openepics.names.util.ValidateStructureElementUtil;
 import org.openepics.names.util.StructureElementUtil.StructureChoice;
+import org.openepics.names.util.StructureUtil;
 import org.openepics.names.util.ValidateUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -1147,8 +1148,13 @@ public class StructuresService {
                 holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup);
 
                 // automatically create name when system structure is approved (after create)
+                //     condition on name and structure entry
+                //         system structure should exist (uuid), one entry that is not deleted
+                //         name should not exist (system structure mnemonic)
                 // create name within current transaction
-                if (!StringUtils.isEmpty(systemGroup.getMnemonic())) {
+                systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(null, Boolean.FALSE, queryValue, null, null, null, null, null);
+                boolean existsName = !StringUtils.isEmpty(systemGroup.getMnemonic()) && namesService.existsName(StructureUtil.getMnemonicPath(systemGroup, holder));
+                if (ValidateUtil.isSize(systemGroups, 1) && !existsName) {
                     NameElementCommand nameElement = new NameElementCommand(null, systemGroup.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
                     NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
                     LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:  {0}", createdNameElement.getName());
@@ -1181,8 +1187,13 @@ public class StructuresService {
                 holderRepositories.getSystemRepository().updateSystem(system);
 
                 // automatically create name when system structure is approved (after create)
+                //     condition on name and structure entry
+                //         system structure should exist (uuid), one entry that is not deleted
+                //         name should not exist (system structure mnemonic)
                 // create name within current transaction
-                if (!StringUtils.isEmpty(system.getMnemonic())) {
+                systems = holderRepositories.getSystemRepository().readSystems(null, Boolean.FALSE, queryValue, null, null, null, null, null, null);
+                boolean existsName = !StringUtils.isEmpty(system.getMnemonic()) && namesService.existsName(StructureUtil.getMnemonicPath(system, holder));
+                if (ValidateUtil.isSize(systems, 1) && !existsName) {
                     NameElementCommand nameElement = new NameElementCommand(null, system.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
                     NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
                     LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:  {0}", createdNameElement.getName());
@@ -1215,8 +1226,13 @@ public class StructuresService {
                 holderRepositories.getSubsystemRepository().updateSubsystem(subsystem);
 
                 // automatically create name when system structure is approved (after create)
+                //     condition on name and structure entry
+                //         system structure should exist (uuid), one entry that is not deleted
+                //         name should not exist (system structure mnemonic)
                 // create name within current transaction
-                if (!StringUtils.isEmpty(subsystem.getMnemonic())) {
+                subsystems = holderRepositories.getSubsystemRepository().readSubsystems(null, Boolean.FALSE, queryValue, null, null, null, null, null, null);
+                boolean existsName = !StringUtils.isEmpty(subsystem.getMnemonic()) && namesService.existsName(StructureUtil.getMnemonicPath(subsystem, holder));
+                if (ValidateUtil.isSize(subsystems, 1) && !existsName) {
                     NameElementCommand nameElement = new NameElementCommand(null, subsystem.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
                     NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
                     LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:  {0}", createdNameElement.getName());
diff --git a/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java b/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
index 97d1cfea..b5a262e2 100644
--- a/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
+++ b/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
@@ -280,6 +280,8 @@ public class ValidateNameElementUtil {
             // name
             //     name not exists
             //     name equivalence not exists
+            //     name is not legacy         - done by checking system structure and device structure
+            //                                  corresponds to legacy check, need not call is legacy
 
             // find out system group, system, subsystem
             //     one of the three expected to be non-null, other two expected to be null
diff --git a/src/test/java/org/openepics/names/docker/NamesIT.java b/src/test/java/org/openepics/names/docker/NamesIT.java
index da8e305e..42dd8c4b 100644
--- a/src/test/java/org/openepics/names/docker/NamesIT.java
+++ b/src/test/java/org/openepics/names/docker/NamesIT.java
@@ -18,6 +18,8 @@
 
 package org.openepics.names.docker;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.File;
@@ -181,10 +183,81 @@ class NamesIT {
         // purpose
         //     test if name is legacy name
         //
-        // what
+        // what - combination of
+        //     read        exists name
         //     read        is legacy name
+        //     read        is valid to create name
+        //     create      create names
+        //     delete      delete structures
+        //     patch       approve structures
 
         ITUtilNameElement.assertIsLegacy("RFQ-010PRL:EMR-RFA-071", Boolean.FALSE);
+        ITUtilNameElement.assertIsLegacy("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+
+        try {
+            NameElementCommand nameElement = null;
+            NameElement createdNameElement = null;
+            StructureElementCommand structureElement = null;
+
+            nameElement = new NameElementCommand(
+                    null, subsystemN1U1, deviceTypeRFA, "071",
+                    "description", "comment");
+
+            Long totalCount = ITUtilNameElement.assertRead("").getTotalCount();
+            assertNotNull(totalCount);
+
+            ITUtilNameElement.assertExists("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+            ITUtilNameElement.assertIsLegacy("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+            ITUtilNameElement.assertIsValidToCreate("RFQ-N1U1:EMR-RFA-071", Boolean.TRUE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.CREATE, Boolean.TRUE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.UPDATE, Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.DELETE, Boolean.FALSE);
+
+            // create
+            createdNameElement = ITUtilNameElement.assertCreate(nameElement);
+            nameElement.setUuid(createdNameElement.getUuid());
+
+            Long totalCount2 = ITUtilNameElement.assertRead("").getTotalCount();
+            assertNotNull(totalCount2);
+            assertEquals(totalCount + 1, totalCount2);
+
+            ITUtilNameElement.assertExists("RFQ-N1U1:EMR-RFA-071", Boolean.TRUE);
+            ITUtilNameElement.assertIsLegacy("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+            ITUtilNameElement.assertIsValidToCreate("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.CREATE, Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.UPDATE, Boolean.TRUE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.DELETE, Boolean.TRUE);
+
+            // delete, approve
+            structureElement = new StructureElementCommand(
+                    subsystemN1U1, Type.SUBSYSTEM, systemRFQ,
+                    "name", "N1U1",
+                    "description", "comment");
+
+            ITUtilStructureElement.assertDelete(structureElement);
+
+            ITUtilNameElement.assertExists("RFQ-N1U1:EMR-RFA-071", Boolean.TRUE);
+            ITUtilNameElement.assertIsLegacy("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+            ITUtilNameElement.assertIsValidToCreate("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.CREATE, Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.UPDATE, Boolean.TRUE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.DELETE, Boolean.TRUE);
+
+            ITUtilStructureElement.assertApprove(structureElement);
+
+            totalCount = ITUtilNameElement.assertRead("").getTotalCount();
+            assertNotNull(totalCount);
+            assertEquals(totalCount2, totalCount);
+
+            ITUtilNameElement.assertExists("RFQ-N1U1:EMR-RFA-071", Boolean.TRUE);
+            ITUtilNameElement.assertIsLegacy("RFQ-N1U1:EMR-RFA-071", Boolean.TRUE);
+            ITUtilNameElement.assertIsValidToCreate("RFQ-N1U1:EMR-RFA-071", Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.CREATE, Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.UPDATE, Boolean.FALSE);
+            ITUtilNameElement.assertValidate(nameElement,  NameChoice.DELETE, Boolean.TRUE);
+        } catch (Exception e) {
+            fail();
+        }
     }
 
     @Test
@@ -491,8 +564,8 @@ class NamesIT {
             nameElement.setParentsystemstructure(null);
             ITUtilNameElement.assertValidate(nameElement, NameChoice.UPDATE, Boolean.FALSE);
 
-            nameElement.setParentsystemstructure(subsystemN1U1);
-            ITUtilNameElement.assertValidate(nameElement, NameChoice.UPDATE, Boolean.TRUE);
+            // subsystemN1U1 used in isLegacyName but not here
+            // order of tests not guaranteed
 
             nameElement.setParentsystemstructure(subsystem010PRL);
             ITUtilNameElement.assertValidate(nameElement, NameChoice.UPDATE, Boolean.TRUE);
@@ -810,7 +883,7 @@ class NamesIT {
             ITUtilNameElement.assertRead("?systemstructure=RFQ-010",  6, -1);
             ITUtilNameElement.assertRead("?systemstructure=RFQ-0",    0);
             ITUtilNameElement.assertRead("?systemstructure=RFQ-0__",  6, -1);
-            ITUtilNameElement.assertRead("?systemstructure=RFQ-N1U1", 1);
+            ITUtilNameElement.assertRead("?systemstructure=RFQ-N1U1", 0, -1);
 
             ITUtilNameElement.assertRead("?devicestructure=EMR-FS",   6, -1);
             ITUtilNameElement.assertRead("?devicestructure=EMR-F",    0);
@@ -846,7 +919,7 @@ class NamesIT {
             ITUtilNameElement.assertRead("/systemstructure/RFQ-010",      6, -1);
             ITUtilNameElement.assertRead("/systemstructure/RFQ-0",        0);
             ITUtilNameElement.assertRead("/systemstructure/RFQ-0__",      6, -1);
-            ITUtilNameElement.assertRead("/systemstructure/RFQ-N1U1",     1);
+            ITUtilNameElement.assertRead("/systemstructure/RFQ-N1U1",     0, -1);
 
             // device structure mnemonic path
             //     /devicestructure/{mnemonicpath}
-- 
GitLab