Add REST CRUD ops for service data 03/109503/7
authorDan Timoney <dtimoney@att.com>
Wed, 24 Jun 2020 12:14:17 +0000 (08:14 -0400)
committerDan Timoney <dtimoney@att.com>
Thu, 2 Jul 2020 17:46:57 +0000 (13:46 -0400)
Add REST Create/Read/Update/Delete for service data

Change-Id: Ie22e8a82afa6b50c4a9fbe80ec792996e377abed
Issue-ID: SDNC-1213
Signed-off-by: Dan Timoney <dtimoney@att.com>
31 files changed:
.gitignore
ms/generic-resource-api/.swagger-codegen-ignore
ms/generic-resource-api/pom.xml
ms/generic-resource-api/src/main/dc/docker-compose.yaml
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/controllers/ConfigApiController.java
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/controllers/OperationalApiController.java [new file with mode: 0644]
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/core/GenericResourceMsApp.java
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/core/WebConfig.java
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/data/ConfigPreloadData.java
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/data/ConfigServices.java
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/data/OperationalPreloadData.java
ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/data/OperationalServices.java
ms/generic-resource-api/src/main/resources/startGra.sh
ms/generic-resource-api/src/main/templates/api.mustache [new file with mode: 0644]
ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/ConfigApiPreloadControllerTest.java [new file with mode: 0644]
ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/ConfigApiServicesControllerTest.java [new file with mode: 0644]
ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/GenericResourceMsAppTest.java [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/application.properties [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/preload.data [deleted file]
ms/generic-resource-api/src/test/resources/preload1-net-list-item.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/preload1-net-model-info.json [moved from ms/generic-resource-api/src/test/resources/preload1.json with 98% similarity]
ms/generic-resource-api/src/test/resources/preload1-net-preload-data.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/preload1-rpc-network.json [moved from ms/generic-resource-api/src/test/resources/preload-net.json with 98% similarity]
ms/generic-resource-api/src/test/resources/preload1-rpc-vfmodule.json [moved from ms/generic-resource-api/src/test/resources/preload-vfmodule.json with 99% similarity]
ms/generic-resource-api/src/test/resources/preload2-net-list-item.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/preload2-net-model-info.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/service1-servicedata.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/service1-serviceitem.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/service1-servicestatus.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/service1.json [new file with mode: 0644]
ms/generic-resource-api/src/test/resources/svclogic.properties [new file with mode: 0644]

index 6b2cbd6..478a06e 100644 (file)
@@ -1,4 +1,5 @@
 *.classpath
+*.factorypath
 *.project
 *.checkstyle
 .idea
@@ -7,3 +8,4 @@ target/
 output.log
 debug-logs/
 logs/
+**/derby.log
index f0c00f4..d8f3f67 100644 (file)
@@ -1,3 +1,4 @@
 **/OperationsApiController.java
+**/OperationalApiController.java
 **/ConfigApiController.java
 **/Swagger2SpringBoot.java
index bca0ec8..dbbfad0 100644 (file)
@@ -13,7 +13,7 @@
     <version>2.0.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
-    <name>sdnc-northbound :: ms :: ${project.artifactId}</name>
+    <name>sdnc-apps :: ms :: ${project.artifactId}</name>
     <description>POM to be used for yang2swagger generation of client in SDNC project</description>
     <url>http://wiki.onap.org</url>
 
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.derby</groupId>
+            <artifactId>derby</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
                             <generateApiTests>true</generateApiTests>
                             <ignoreFileOverride>${project.basedir}/.swagger-codegen-ignore</ignoreFileOverride>
                             <withXml>true</withXml>
+                            <templateDirectory>${project.basedir}/src/main/templates</templateDirectory>
                             <configOptions>
                                 <java8>true</java8>
                                 <springBootVersion>2.2.4-RELEASE</springBootVersion>
index da3d98d..9d85c39 100755 (executable)
@@ -9,6 +9,9 @@ services:
     environment:
       - MYSQL_ROOT_PASSWORD=openECOMP1.0
       - MYSQL_ROOT_HOST=%
+      - MYSQL_USER=sdnc
+      - MYSQL_PASSWORD=abc123
+      - MYSQL_DATABASE=sdnctl
     logging:       
       driver:   "json-file"
       options:  
index 59d082b..e3d084e 100644 (file)
@@ -23,6 +23,10 @@ package org.onap.sdnc.apps.ms.gra.controllers;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.ccsdk.apps.services.RestApplicationException;
+import org.onap.ccsdk.apps.services.RestException;
+import org.onap.ccsdk.apps.services.RestProtocolError;
+import org.onap.ccsdk.apps.services.RestProtocolException;
 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadData;
 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadDataRepository;
 import org.onap.sdnc.apps.ms.gra.data.ConfigServices;
@@ -41,8 +45,10 @@ import org.springframework.stereotype.Controller;
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 @Controller
 @ComponentScan(basePackages = {"org.onap.sdnc.apps.ms.gra.*"})
@@ -81,14 +87,18 @@ public class ConfigApiController implements ConfigApi {
     @Override
     public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationDelete() {
         configPreloadDataRepository.deleteAll();
-        return (new ResponseEntity<>(HttpStatus.OK));
+        return (new ResponseEntity<>(HttpStatus.NO_CONTENT));
     }
 
     @Override
-    public ResponseEntity<GenericResourceApiPreloadModelInformation> configGENERICRESOURCEAPIpreloadInformationGet() {
+    public ResponseEntity<GenericResourceApiPreloadModelInformation> configGENERICRESOURCEAPIpreloadInformationGet() throws RestApplicationException {
         GenericResourceApiPreloadModelInformation genericResourceApiPreloadModelInformation = new GenericResourceApiPreloadModelInformation();
 
-        configPreloadDataRepository.findAll().forEach(configPreloadData -> {
+        if (configPreloadDataRepository.count() == 0) {
+            throw new RestApplicationException("data-missing", "Request could not be completed because the relevant data model content does not exist", HttpStatus.NOT_FOUND.value());
+        }
+
+        for (ConfigPreloadData configPreloadData : configPreloadDataRepository.findAll()) {
             GenericResourceApiPreloadmodelinformationPreloadList preloadListItem = new GenericResourceApiPreloadmodelinformationPreloadList();
 
             preloadListItem.setPreloadId(configPreloadData.getPreloadId());
@@ -97,60 +107,100 @@ public class ConfigApiController implements ConfigApi {
                 preloadListItem.setPreloadData(objectMapper.readValue(configPreloadData.getPreloadData(), GenericResourceApiPreloaddataPreloadData.class));
             } catch (JsonProcessingException e) {
                 log.error("Could not convert preload data", e);
+                throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
             }
             genericResourceApiPreloadModelInformation.addPreloadListItem(preloadListItem);
-        });
+        }
 
 
         return new ResponseEntity<>(genericResourceApiPreloadModelInformation, HttpStatus.OK);
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationPost(@Valid GenericResourceApiPreloadModelInformation graPreloadModelInfo) {
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationPost(@Valid GenericResourceApiPreloadModelInformation graPreloadModelInfo) throws RestApplicationException, RestProtocolException {
+
+        List<GenericResourceApiPreloadmodelinformationPreloadList> preloadList = graPreloadModelInfo.getPreloadList();
+        List<ConfigPreloadData> newPreloadData = new LinkedList<>();
+
+        if (preloadList != null) {
+            // Verification pass - if any items already exist, return an error
+            for (GenericResourceApiPreloadmodelinformationPreloadList curItem : preloadList) {
+
+                List<ConfigPreloadData> curPreloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(curItem.getPreloadId(), curItem.getPreloadType());
+                if ((curPreloadData != null) && (!curPreloadData.isEmpty())) {
+                    log.error("Preload data already exists for {}:{}", curItem.getPreloadId(), curItem.getPreloadType());
+                    throw new RestProtocolException("data-exists", "Data already exists for " + curItem.getPreloadId() + ":" + curItem.getPreloadType(), HttpStatus.CONFLICT.value());
+                } else {
+                    try {
+                        newPreloadData.add(new ConfigPreloadData(curItem.getPreloadId(), curItem.getPreloadType(), objectMapper.writeValueAsString(curItem.getPreloadData())));
+                    } catch (JsonProcessingException e) {
+                        log.error("Cannot convert preload data");
+                        throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+                    }
+                }
+            }
+
+            // Update pass
+            for (ConfigPreloadData newDataItem : newPreloadData) {
+                log.info("Adding preload data for {}:{}", newDataItem.getPreloadId(), newDataItem.getPreloadType());
+                configPreloadDataRepository.save(newDataItem);
+            }
+        } else {
+            throw new RestProtocolException("data-missing", "No preload-list entries found to add", HttpStatus.CONFLICT.value());
+        }
+
+        return new ResponseEntity<>(HttpStatus.CREATED);
+    }
+
+    @Override
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationPut(@Valid GenericResourceApiPreloadModelInformation graPreloadModelInfo) throws RestApplicationException {
 
+        boolean addedNew = false;
         List<GenericResourceApiPreloadmodelinformationPreloadList> preloadList = graPreloadModelInfo.getPreloadList();
 
         if (preloadList != null) {
             Iterator<GenericResourceApiPreloadmodelinformationPreloadList> iter = preloadList.iterator();
             while (iter.hasNext()) {
                 GenericResourceApiPreloadmodelinformationPreloadList curItem = iter.next();
-
-                // Remove any entries already existing for this preloadId/preloadType
-               configPreloadDataRepository.deleteByPreloadIdAndPreloadType(curItem.getPreloadId(), curItem.getPreloadType());
+                List<ConfigPreloadData> curPreloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(curItem.getPreloadId(), curItem.getPreloadType());
+                if ((curPreloadData == null) || curPreloadData.isEmpty()) {
+                    addedNew = true;
+                }
 
                 try {
                     configPreloadDataRepository.save(new ConfigPreloadData(curItem.getPreloadId(), curItem.getPreloadType(), objectMapper.writeValueAsString(curItem.getPreloadData())));
                 } catch (JsonProcessingException e) {
                     log.error("Cannot convert preload data", e);
+                    throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
                 }
             }
         }
 
-        return new ResponseEntity<>(HttpStatus.OK);
+        if (addedNew) {
+            return new ResponseEntity<>(HttpStatus.CREATED);
+        } else {
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        }
+
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPost(@Valid GenericResourceApiPreloadmodelinformationPreloadList preloadListItem) {
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPost(@Valid GenericResourceApiPreloadmodelinformationPreloadList preloadListItem) throws RestProtocolException {
 
-        // Remove any entries already existing for this preloadId/preloadType
-        configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadListItem.getPreloadId(), preloadListItem.getPreloadType());
-
-        try {
-            configPreloadDataRepository.save(new ConfigPreloadData(preloadListItem.getPreloadId(), preloadListItem.getPreloadType(), objectMapper.writeValueAsString(preloadListItem.getPreloadData())));
-        } catch (JsonProcessingException e) {
-            log.error("Cannot convert preload data", e);
-        }
-        return new ResponseEntity<>(HttpStatus.OK);
+        throw new RestProtocolException("data-missing", "Missing key for list \"preload-list\"", HttpStatus.NOT_FOUND.value());
     }
 
+
     @Override
     public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeDelete(String preloadId, String preloadType) {
         configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
-        return new ResponseEntity<>(HttpStatus.OK);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     @Override
-    public ResponseEntity<GenericResourceApiPreloadmodelinformationPreloadList> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGet(String preloadId, String preloadType) {
+    public ResponseEntity<GenericResourceApiPreloadmodelinformationPreloadList> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGet(String preloadId, String preloadType) throws RestApplicationException {
         List<ConfigPreloadData> preloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
         if (preloadData != null) {
             if (!preloadData.isEmpty()) {
@@ -162,6 +212,7 @@ public class ConfigApiController implements ConfigApi {
                     preloadDataList.setPreloadData(objectMapper.readValue(preloadDataItem.getPreloadData(), GenericResourceApiPreloaddataPreloadData.class));
                 } catch (JsonProcessingException e) {
                     log.error("Cannot convert preload data", e);
+                    throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
                 }
                 return new ResponseEntity<>(preloadDataList, HttpStatus.OK);
             }
@@ -170,71 +221,275 @@ public class ConfigApiController implements ConfigApi {
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypePost(String preloadId, String preloadType, @Valid GenericResourceApiPreloadmodelinformationPreloadList preloadListItem) {
-        configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypePost(String preloadId, String preloadType, @Valid GenericResourceApiPreloadmodelinformationPreloadList preloadListItem) throws RestApplicationException, RestProtocolException {
+        List<ConfigPreloadData> preloadDataItems = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+
+        if ((preloadDataItems != null) && !preloadDataItems.isEmpty()) {
+            log.error("Preload data already exists for {}:{}", preloadId, preloadType);
+            throw new RestProtocolException("data-exists", "Data already exists for " + preloadId + ":" + preloadType, HttpStatus.CONFLICT.value());
+        }
+
         try {
+            log.info("Adding preload data for {}:{}", preloadId, preloadType);
             configPreloadDataRepository.save(new ConfigPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadListItem.getPreloadData())));
         } catch (JsonProcessingException e) {
             log.error("Cannot convert preload data", e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
         }
-        return new ResponseEntity<>(HttpStatus.OK);
+        return new ResponseEntity<>(HttpStatus.CREATED);
     }
 
-
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataDelete(String preloadId, String preloadType) {
-        List<ConfigPreloadData> preloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypePut(String preloadId, String preloadType, @Valid GenericResourceApiPreloadmodelinformationPreloadList preloadListItem) throws RestApplicationException, RestProtocolException {
+        List<ConfigPreloadData> preloadDataItems = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+        boolean dataExists = false;
+        if ((preloadDataItems != null) && !preloadDataItems.isEmpty()) {
+            dataExists = true;
+        }
 
-        if (preloadData != null) {
-            Iterator<ConfigPreloadData> iter = preloadData.iterator();
+        if ((preloadListItem.getPreloadId() == null) ||
+                (preloadListItem.getPreloadType() == null) ||
+                (preloadListItem.getPreloadData() == null)) {
+            log.error("Invalid list item received: {}", preloadListItem);
+            throw new RestProtocolException("bad-attribute", "Invalid data received", HttpStatus.BAD_REQUEST.value());
+        }
 
-            while (iter.hasNext()) {
-                configPreloadDataRepository.delete(iter.next());
+        try {
+            if (dataExists) {
+                log.info("Updating preload data for {}:{} -> {}", preloadId, preloadType, objectMapper.writeValueAsString(preloadListItem));
+
+            } else {
+                log.info("Adding preload data for {}:{}", preloadId, preloadType);
             }
+
+            configPreloadDataRepository.save(new ConfigPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadListItem.getPreloadData())));
+        } catch (JsonProcessingException e) {
+            log.error("Cannot convert preload data", e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+        }
+
+        if (dataExists) {
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        } else {
+            return new ResponseEntity<>(HttpStatus.CREATED);
         }
-        return new ResponseEntity<>(HttpStatus.OK);
     }
 
+
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationPut(@Valid GenericResourceApiPreloadModelInformation genericResourceApiPreloadModelInformationBodyParam) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataDelete(String preloadId, String preloadType) throws RestProtocolException {
+        List<ConfigPreloadData> preloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+
+        if ((preloadData == null) || preloadData.isEmpty()) {
+            throw new RestProtocolException("data-missing", "No preload entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        ConfigPreloadData preloadDataItem = preloadData.get(0);
+
+        if (preloadDataItem.getPreloadData() == null) {
+            throw new RestProtocolException("data-missing", "No preload-data found", HttpStatus.NOT_FOUND.value());
+        }
+        preloadDataItem.setPreloadData(null);
+        configPreloadDataRepository.save(preloadDataItem);
+
+
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
+
     @Override
-    public ResponseEntity<GenericResourceApiPreloaddataPreloadData> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataGet(String preloadId, String preloadType) {
+    public ResponseEntity<GenericResourceApiPreloaddataPreloadData> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataGet(String preloadId, String preloadType) throws RestApplicationException, RestProtocolException {
         List<ConfigPreloadData> preloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
-        if (preloadData != null) {
-            if (!preloadData.isEmpty()) {
-                ConfigPreloadData preloadDataItem = preloadData.get(0);
-                try {
-                    return new ResponseEntity<>(objectMapper.readValue(preloadDataItem.getPreloadData(), GenericResourceApiPreloaddataPreloadData.class), HttpStatus.OK);
-                } catch (JsonProcessingException e) {
-                    log.error("Cannot convert preload data", e);
-                }
-            }
+
+        if ((preloadData == null) || preloadData.isEmpty()) {
+            throw new RestProtocolException("data-missing", "No preload entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        ConfigPreloadData preloadDataItem = preloadData.get(0);
+
+        if (preloadDataItem.getPreloadData() == null) {
+            throw new RestProtocolException("data-missing", "No preload-data found", HttpStatus.NOT_FOUND.value());
+        }
+        try {
+            return new ResponseEntity<>(objectMapper.readValue(preloadDataItem.getPreloadData(), GenericResourceApiPreloaddataPreloadData.class), HttpStatus.OK);
+        } catch (JsonProcessingException e) {
+            log.error("Cannot convert preload data", e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
         }
-        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPost(String preloadId, String preloadType, @Valid GenericResourceApiPreloaddataPreloadData preloadData) {
-        configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPost(String preloadId, String preloadType, @Valid GenericResourceApiPreloaddataPreloadData preloadData) throws RestApplicationException, RestProtocolException {
+        List<ConfigPreloadData> preloadDataEntries = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+
+        List<ConfigPreloadData> preloadDataItems = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+        if ((preloadDataItems == null) || (preloadDataItems.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No preload entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        if ((preloadData == null) ||
+                (preloadData.getPreloadNetworkTopologyInformation() == null)) {
+            throw new RestProtocolException("bad-attribute", "Invalid preloadData received", HttpStatus.BAD_REQUEST.value());
+        }
+
+        ConfigPreloadData preloadDataItem = preloadDataItems.get(0);
+
+        if (preloadDataItem.getPreloadData() != null) {
+            log.error("Preload data already exists for {}:{} ", preloadId, preloadType);
+            throw new RestProtocolException("data-exists", "Data already exists for " + preloadId + ":" + preloadType, HttpStatus.CONFLICT.value());
+        }
+
         try {
-            configPreloadDataRepository.save(new ConfigPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
+            preloadDataItem.setPreloadData(objectMapper.writeValueAsString(preloadData));
+            configPreloadDataRepository.save(preloadDataItem);
         } catch (JsonProcessingException e) {
             log.error("Cannot convert preload data", e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+        return new ResponseEntity<>(HttpStatus.CREATED);
+    }
+
+    @Override
+    public ResponseEntity<Void> configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPut(String preloadId, String preloadType, @Valid GenericResourceApiPreloaddataPreloadData preloadData) throws RestApplicationException, RestProtocolException {
+        boolean dataExists = false;
+        List<ConfigPreloadData> preloadDataItems = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+        if ((preloadDataItems == null) || (preloadDataItems.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No preload entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        if ((preloadData == null) ||
+                (preloadData.getPreloadNetworkTopologyInformation() == null)) {
+            throw new RestProtocolException("bad-attribute", "Invalid preloadData received", HttpStatus.BAD_REQUEST.value());
+        }
+
+        ConfigPreloadData preloadDataItem = preloadDataItems.get(0);
+
+        if (preloadDataItem.getPreloadData() != null) {
+            dataExists = true;
+        }
+
+        try {
+            preloadDataItem.setPreloadData(objectMapper.writeValueAsString(preloadData));
+            configPreloadDataRepository.save(preloadDataItem);
+        } catch (JsonProcessingException e) {
+            log.error("Cannot convert preload data", e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+        if (dataExists) {
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        } else {
+            return new ResponseEntity<>(HttpStatus.CREATED);
         }
-        return new ResponseEntity<>(HttpStatus.OK);
     }
 
     @Override
     public ResponseEntity<Void> configGENERICRESOURCEAPIservicesDelete() {
         configServicesRepository.deleteAll();
-        return new ResponseEntity<>(HttpStatus.OK);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIservicePost(@Valid GenericResourceApiServicemodelinfrastructureService servicesData) {
+    public ResponseEntity<GenericResourceApiServiceModelInfrastructure> configGENERICRESOURCEAPIservicesGet() throws RestApplicationException {
+        GenericResourceApiServiceModelInfrastructure modelInfrastructure = new GenericResourceApiServiceModelInfrastructure();
+
+        if (configServicesRepository.count() == 0)  {
+            throw new RestApplicationException("data-missing", "Request could not be completed because the relevant data model content does not exist", HttpStatus.NOT_FOUND.value());
+        }
+
+        for (ConfigServices service : configServicesRepository.findAll()) {
+            GenericResourceApiServicemodelinfrastructureService serviceItem = new GenericResourceApiServicemodelinfrastructureService();
+            serviceItem.setServiceInstanceId(service.getSvcInstanceId());
+            try {
+                serviceItem.setServiceData(objectMapper.readValue(service.getSvcData(), GenericResourceApiServicedataServiceData.class));
+            } catch (JsonProcessingException e) {
+                log.error("Could not deserialize service data for {}", service.getSvcInstanceId(), e);
+                throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+            }
+            serviceItem.setServiceStatus(service.getServiceStatus());
+            modelInfrastructure.addServiceItem(serviceItem);
+        }
+
+
+        return new ResponseEntity<>(modelInfrastructure, HttpStatus.OK);
+
+    }
+
+    @Override
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesPost(@Valid GenericResourceApiServiceModelInfrastructure modelInfrastructure) throws RestApplicationException, RestProtocolException {
+        List<ConfigServices> newServices = new LinkedList<>();
+
+        for (GenericResourceApiServicemodelinfrastructureService serviceItem : modelInfrastructure.getService()) {
+            String svcInstanceId = serviceItem.getServiceInstanceId();
+            List<ConfigServices> existingService = configServicesRepository.findBySvcInstanceId(svcInstanceId);
+            if ((existingService != null) && !existingService.isEmpty()) {
+                log.error("Service data already exists for {}", svcInstanceId);
+                throw new RestProtocolException("data-exists", "Data already exists for service-instance-id " + svcInstanceId, HttpStatus.CONFLICT.value());
+            }
+            ConfigServices service = new ConfigServices();
+            service.setSvcInstanceId(svcInstanceId);
+            try {
+                service.setSvcData(objectMapper.writeValueAsString(serviceItem.getServiceData()));
+            } catch (JsonProcessingException e) {
+                log.error("Could not serialize service data for {}", service.getSvcInstanceId(), e);
+                throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+            }
+            service.setServiceStatus(serviceItem.getServiceStatus());
+            newServices.add(service);
+        }
+
+        for (ConfigServices service : newServices) {
+            configServicesRepository.save(service);
+        }
+
+        return new ResponseEntity<>(HttpStatus.CREATED);
+
+    }
+
+    @Override
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesPut(@Valid GenericResourceApiServiceModelInfrastructure modelInfrastructure) throws RestApplicationException {
+
+        List<ConfigServices> newServices = new LinkedList<>();
+        boolean dataExists = false;
+
+        for (GenericResourceApiServicemodelinfrastructureService serviceItem : modelInfrastructure.getService()) {
+            String svcInstanceId = serviceItem.getServiceInstanceId();
+            List<ConfigServices> existingService = configServicesRepository.findBySvcInstanceId(svcInstanceId);
+            if ((existingService != null) && !existingService.isEmpty()) {
+                dataExists = true;
+            }
+            ConfigServices service = new ConfigServices();
+            service.setSvcInstanceId(svcInstanceId);
+            try {
+                service.setSvcData(objectMapper.writeValueAsString(serviceItem.getServiceData()));
+            } catch (JsonProcessingException e) {
+                log.error("Could not serialize service data for {}", service.getSvcInstanceId(), e);
+                throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+            }
+            service.setServiceStatus(serviceItem.getServiceStatus());
+            newServices.add(service);
+        }
+
+        for (ConfigServices service : newServices) {
+            configServicesRepository.save(service);
+        }
+
+        if (dataExists) {
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        } else {
+            return new ResponseEntity<>(HttpStatus.CREATED);
+        }
+
+    }
+
+    @Override
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIservicePost(@Valid GenericResourceApiServicemodelinfrastructureService servicesData) throws RestApplicationException {
         String svcInstanceId = servicesData.getServiceInstanceId();
         try {
             String svcData = objectMapper.writeValueAsString(servicesData.getServiceData());
@@ -242,7 +497,9 @@ public class ConfigApiController implements ConfigApi {
             configServicesRepository.deleteBySvcInstanceId(svcInstanceId);
             configServicesRepository.save(configService);
         } catch (JsonProcessingException e) {
-           log.error("Cannot convert service data", e);
+            log.error("Cannot convert service data", e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
         }
         return new ResponseEntity<>(HttpStatus.OK);
     }
@@ -250,76 +507,292 @@ public class ConfigApiController implements ConfigApi {
     @Override
     public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdDelete(String serviceInstanceId) {
         configServicesRepository.deleteBySvcInstanceId(serviceInstanceId);
-        return new ResponseEntity<>(HttpStatus.OK);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataDelete(String serviceInstanceId) {
-        return null;
-    }
+    public ResponseEntity<GenericResourceApiServicemodelinfrastructureService> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGet(String serviceInstanceId) throws RestApplicationException {
+        GenericResourceApiServicemodelinfrastructureService retval = null;
+
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+
+        if (services.isEmpty()) {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+        } else {
+            ConfigServices service = services.get(0);
+            retval = new GenericResourceApiServicemodelinfrastructureService();
+            retval.setServiceInstanceId(serviceInstanceId);
+            retval.setServiceStatus(service.getServiceStatus());
+            try {
+                retval.setServiceData(objectMapper.readValue(service.getSvcData(), GenericResourceApiServicedataServiceData.class));
+            } catch (JsonProcessingException e) {
+                log.error("Could not deserialize service data for service instance id {}", serviceInstanceId, e);
+                throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
 
-    @Override
-    public ResponseEntity<GenericResourceApiServicedataServiceData> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataGet(String serviceInstanceId) {
-        return null;
-    }
+            }
+        }
 
-    @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataPost(String serviceInstanceId, @Valid GenericResourceApiServicedataServiceData genericResourceApiServicedataServiceDataBodyParam) {
-        return null;
-    }
 
-    @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataPut(String serviceInstanceId, @Valid GenericResourceApiServicedataServiceData genericResourceApiServicedataServiceDataBodyParam) {
-        return null;
+        return new ResponseEntity<>(retval, HttpStatus.OK);
+
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusDelete(String serviceInstanceId) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdPost(String svcInstanceId, @Valid GenericResourceApiServicemodelinfrastructureService newService) throws RestApplicationException, RestProtocolException {
+
+        List<ConfigServices> existingService = configServicesRepository.findBySvcInstanceId(svcInstanceId);
+        if ((existingService != null) && !existingService.isEmpty()) {
+            log.error("Service data already exists for {}", svcInstanceId);
+            throw new RestProtocolException("data-exists", "Data already exists for service-instance-id " + svcInstanceId, HttpStatus.CONFLICT.value());
+        }
+        ConfigServices service = new ConfigServices();
+        service.setSvcInstanceId(svcInstanceId);
+        try {
+            service.setSvcData(objectMapper.writeValueAsString(newService.getServiceData()));
+        } catch (JsonProcessingException e) {
+            log.error("Could not serialize service data for {}", service.getSvcInstanceId(), e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+        }
+        service.setServiceStatus(newService.getServiceStatus());
+        configServicesRepository.save(service);
+
+        return new ResponseEntity<>(HttpStatus.CREATED);
     }
 
     @Override
-    public ResponseEntity<GenericResourceApiServicestatusServiceStatus> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusGet(String serviceInstanceId) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdPut(String serviceInstanceId, @Valid GenericResourceApiServicemodelinfrastructureService newService) throws RestApplicationException {
+
+        boolean dataExists = false;
+
+        String svcInstanceId = newService.getServiceInstanceId();
+
+        ConfigServices service = null;
+        List<ConfigServices> existingService = configServicesRepository.findBySvcInstanceId(svcInstanceId);
+        if ((existingService != null) && !existingService.isEmpty()) {
+            dataExists = true;
+            service = existingService.get(0);
+        } else {
+            service = new ConfigServices();
+            service.setSvcInstanceId(svcInstanceId);
+        }
+
+        try {
+            service.setSvcData(objectMapper.writeValueAsString(newService.getServiceData()));
+        } catch (JsonProcessingException e) {
+            log.error("Could not serialize service data for {}", service.getSvcInstanceId(), e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+        }
+        service.setServiceStatus(newService.getServiceStatus());
+        configServicesRepository.save(service);
+
+        if (dataExists) {
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        } else {
+            return new ResponseEntity<>(HttpStatus.CREATED);
+        }
     }
 
+
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusPost(String serviceInstanceId, @Valid GenericResourceApiServicestatusServiceStatus genericResourceApiServicestatusServiceStatusBodyParam) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataDelete(String serviceInstanceId) throws RestProtocolException {
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        ConfigServices service = services.get(0);
+        if (service.getSvcData() == null) {
+            throw new RestProtocolException("data-missing", "No service-data found", HttpStatus.NOT_FOUND.value());
+        }
+        service.setSvcData(null);
+        configServicesRepository.save(service);
+
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusPut(String serviceInstanceId, @Valid GenericResourceApiServicestatusServiceStatus genericResourceApiServicestatusServiceStatusBodyParam) {
-        return null;
+    public ResponseEntity<GenericResourceApiServicedataServiceData> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataGet(String serviceInstanceId) throws RestApplicationException, RestProtocolException {
+        GenericResourceApiServicedataServiceData serviceData = null;
+
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        try {
+            serviceData = objectMapper.readValue(services.get(0).getSvcData(), GenericResourceApiServicedataServiceData.class);
+            return new ResponseEntity<>(serviceData, HttpStatus.OK);
+        } catch (JsonProcessingException e) {
+            log.error("Could not parse service data", e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
     }
 
     @Override
-    public ResponseEntity<GenericResourceApiServicemodelinfrastructureService> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGet(String serviceInstanceId) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataPost(String serviceInstanceId, @Valid GenericResourceApiServicedataServiceData serviceData) throws RestApplicationException, RestProtocolException {
+        ConfigServices service;
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        if ((serviceData == null) ||
+                (serviceData.getServiceInformation() == null)) {
+            throw new RestProtocolException("bad-attribute", "Invalid service-data received", HttpStatus.BAD_REQUEST.value());
+
+        }
+        service = services.get(0);
+
+        if ((service.getSvcData() != null) && (service.getSvcData().length() > 0)){
+            log.error("service-data already exists for svcInstanceId {}", serviceInstanceId);
+            throw new RestProtocolException("data-exists", "Data already exists for " + serviceInstanceId, HttpStatus.CONFLICT.value());
+        }
+
+
+        try {
+            service.setSvcData(objectMapper.writeValueAsString(serviceData));
+            configServicesRepository.save(service);
+        } catch (JsonProcessingException e) {
+            log.error("Could not serialize service data for svc instance id {}", serviceInstanceId, e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+
+        return new ResponseEntity<>(HttpStatus.CREATED);
+
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdPost(String serviceInstanceId, @Valid GenericResourceApiServicemodelinfrastructureService genericResourceApiServicemodelinfrastructureServiceBodyParam) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataPut(String serviceInstanceId, @Valid GenericResourceApiServicedataServiceData serviceData) throws RestApplicationException, RestProtocolException {
+        ConfigServices service;
+        boolean dataExists = false;
+
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        if ((serviceData == null) ||
+                (serviceData.getServiceInformation() == null)) {
+            throw new RestProtocolException("bad-attribute", "Invalid service-data received", HttpStatus.BAD_REQUEST.value());
+
+        }
+        service = services.get(0);
+
+        if ((service.getSvcData() != null) && (service.getSvcData().length() > 0)) {
+            dataExists = true;
+        }
+
+        try {
+            service.setSvcData(objectMapper.writeValueAsString(serviceData));
+            configServicesRepository.save(service);
+        } catch (JsonProcessingException e) {
+            log.error("Could not serialize service data for svc instance id {}", serviceInstanceId, e);
+            throw new RestApplicationException("data-conversion", "Request could not be completed due to internal error", e, HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+        if (dataExists) {
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        } else {
+            return new ResponseEntity<>(HttpStatus.CREATED);
+        }
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdPut(String serviceInstanceId, @Valid GenericResourceApiServicemodelinfrastructureService genericResourceApiServicemodelinfrastructureServiceBodyParam) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusDelete(String serviceInstanceId) throws RestProtocolException {
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        ConfigServices service = services.get(0);
+        if (service.getServiceStatus() == null) {
+            throw new RestProtocolException("data-missing", "No service-status found", HttpStatus.NOT_FOUND.value());
+        }
+        service.setServiceStatus(null);
+        configServicesRepository.save(service);
+
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+
     }
 
     @Override
-    public ResponseEntity<GenericResourceApiServiceModelInfrastructure> configGENERICRESOURCEAPIservicesGet() {
-        return null;
+    public ResponseEntity<GenericResourceApiServicestatusServiceStatus> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusGet(String serviceInstanceId) throws RestApplicationException, RestProtocolException {
+        GenericResourceApiServicestatusServiceStatus serviceStatus = null;
+
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        serviceStatus = services.get(0).getServiceStatus();
+        return new ResponseEntity<>(serviceStatus, HttpStatus.OK);
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesPost(@Valid GenericResourceApiServiceModelInfrastructure genericResourceApiServiceModelInfrastructureBodyParam) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusPost(String serviceInstanceId, @Valid GenericResourceApiServicestatusServiceStatus serviceStatus) throws RestProtocolException {
+        ConfigServices service;
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        if ((serviceStatus == null) ||
+                (serviceStatus.getAction() == null)) {
+            throw new RestProtocolException("bad-attribute", "Invalid service-status received", HttpStatus.BAD_REQUEST.value());
+
+        }
+        service = services.get(0);
+
+        if (service.getServiceStatus() != null) {
+            log.error("service-status already exists for svcInstanceId {}", serviceInstanceId);
+            throw new RestProtocolException("data-exists", "Data already exists for " + serviceInstanceId, HttpStatus.CONFLICT.value());
+        }
+
+
+        service.setServiceStatus(serviceStatus);
+        configServicesRepository.save(service);
+
+
+        return new ResponseEntity<>(HttpStatus.CREATED);
+
     }
 
     @Override
-    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesPut(@Valid GenericResourceApiServiceModelInfrastructure genericResourceApiServiceModelInfrastructureBodyParam) {
-        return null;
+    public ResponseEntity<Void> configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusPut(String serviceInstanceId, @Valid GenericResourceApiServicestatusServiceStatus serviceStatus) throws RestProtocolException {
+        ConfigServices service;
+        boolean dataExists = false;
+
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId(serviceInstanceId);
+        if ((services == null) || (services.isEmpty())) {
+            throw new RestProtocolException("data-missing", "No service entry found", HttpStatus.NOT_FOUND.value());
+        }
+
+        if ((serviceStatus == null) ||
+                (serviceStatus.getAction() == null)) {
+            throw new RestProtocolException("bad-attribute", "Invalid service-status received", HttpStatus.BAD_REQUEST.value());
+
+        }
+        service = services.get(0);
+
+        if (service.getServiceStatus() != null) {
+            dataExists = true;
+        }
+
+
+        service.setServiceStatus(serviceStatus);
+        configServicesRepository.save(service);
+
+        if (dataExists) {
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        } else {
+            return new ResponseEntity<>(HttpStatus.CREATED);
+        }
     }
+
 }
diff --git a/ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/controllers/OperationalApiController.java b/ms/generic-resource-api/src/main/java/org/onap/sdnc/apps/ms/gra/controllers/OperationalApiController.java
new file mode 100644 (file)
index 0000000..14e285f
--- /dev/null
@@ -0,0 +1,213 @@
+package org.onap.sdnc.apps.ms.gra.controllers;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.sdnc.apps.ms.gra.data.*;
+import org.onap.sdnc.apps.ms.gra.swagger.OperationalApi;
+import org.onap.sdnc.apps.ms.gra.swagger.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@Controller
+@ComponentScan(basePackages = {"org.onap.sdnc.apps.ms.gra.*"})
+@EntityScan("org.onap.sdnc.apps.ms.gra.springboot.*")
+public class OperationalApiController implements OperationalApi {
+    private static final Logger log = LoggerFactory.getLogger(ConfigApiController.class);
+
+    private final ObjectMapper objectMapper;
+
+    private final HttpServletRequest request;
+
+    @Autowired
+    private OperationalPreloadDataRepository operationalPreloadDataRepository;
+
+    @Autowired
+    private OperationalServicesRepository operationalServicesRepository;
+
+    @Autowired
+    public OperationalApiController(ObjectMapper objectMapper, HttpServletRequest request) {
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        this.objectMapper = objectMapper;
+        this.request = request;
+    }
+
+    @Override
+    public Optional<ObjectMapper> getObjectMapper() {
+        return Optional.ofNullable(objectMapper);
+    }
+
+    @Override
+    public Optional<HttpServletRequest> getRequest() {
+        return Optional.ofNullable(request);
+    }
+
+
+    @Override
+    public ResponseEntity<GenericResourceApiPreloadModelInformation> operationalGENERICRESOURCEAPIpreloadInformationGet() {
+        GenericResourceApiPreloadModelInformation genericResourceApiPreloadModelInformation = new GenericResourceApiPreloadModelInformation();
+
+        operationalPreloadDataRepository.findAll().forEach(configPreloadData -> {
+            GenericResourceApiPreloadmodelinformationPreloadList preloadListItem = new GenericResourceApiPreloadmodelinformationPreloadList();
+
+            preloadListItem.setPreloadId(configPreloadData.getPreloadId());
+            preloadListItem.setPreloadType(configPreloadData.getPreloadType());
+            try {
+                preloadListItem.setPreloadData(objectMapper.readValue(configPreloadData.getPreloadData(), GenericResourceApiPreloaddataPreloadData.class));
+            } catch (JsonProcessingException e) {
+                log.error("Could not convert preload data", e);
+            }
+            genericResourceApiPreloadModelInformation.addPreloadListItem(preloadListItem);
+        });
+
+
+        return new ResponseEntity<>(genericResourceApiPreloadModelInformation, HttpStatus.OK);
+    }
+
+
+    @Override
+    public ResponseEntity<GenericResourceApiPreloadmodelinformationPreloadList> operationalGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGet(String preloadId, String preloadType) {
+        List<OperationalPreloadData> preloadData = operationalPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+        if (preloadData != null) {
+            if (!preloadData.isEmpty()) {
+                OperationalPreloadData preloadDataItem = preloadData.get(0);
+                GenericResourceApiPreloadmodelinformationPreloadList preloadDataList = new GenericResourceApiPreloadmodelinformationPreloadList();
+                preloadDataList.setPreloadId(preloadDataItem.getPreloadId());
+                preloadDataList.setPreloadType(preloadDataItem.getPreloadType());
+                try {
+                    preloadDataList.setPreloadData(objectMapper.readValue(preloadDataItem.getPreloadData(), GenericResourceApiPreloaddataPreloadData.class));
+                } catch (JsonProcessingException e) {
+                    log.error("Cannot convert preload data", e);
+                }
+                return new ResponseEntity<>(preloadDataList, HttpStatus.OK);
+            }
+        }
+        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+    }
+
+
+    @Override
+    public ResponseEntity<GenericResourceApiPreloaddataPreloadData> operationalGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataGet(String preloadId, String preloadType) {
+        List<OperationalPreloadData> preloadData = operationalPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
+        if (preloadData != null) {
+            if (!preloadData.isEmpty()) {
+                OperationalPreloadData preloadDataItem = preloadData.get(0);
+                try {
+                    return new ResponseEntity<>(objectMapper.readValue(preloadDataItem.getPreloadData(), GenericResourceApiPreloaddataPreloadData.class), HttpStatus.OK);
+                } catch (JsonProcessingException e) {
+                    log.error("Cannot convert preload data", e);
+                }
+            }
+        }
+        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+    }
+
+
+    @Override
+    public ResponseEntity<GenericResourceApiServiceModelInfrastructure> operationalGENERICRESOURCEAPIservicesGet() {
+        GenericResourceApiServiceModelInfrastructure modelInfrastructure = new GenericResourceApiServiceModelInfrastructure();
+
+        AtomicBoolean caughtError = new AtomicBoolean(false);
+        operationalServicesRepository.findAll().forEach(service ->
+        {
+            GenericResourceApiServicemodelinfrastructureService serviceItem = new GenericResourceApiServicemodelinfrastructureService();
+            serviceItem.setServiceInstanceId(service.getSvcInstanceId());
+            try {
+                serviceItem.setServiceData(objectMapper.readValue(service.getSvcData(), GenericResourceApiServicedataServiceData.class));
+            } catch (JsonProcessingException e) {
+                log.error("Could not deserialize service data for {}", service.getSvcInstanceId(), e);
+                caughtError.set(true);
+            }
+            serviceItem.setServiceStatus(service.getServiceStatus());
+            modelInfrastructure.addServiceItem(serviceItem);
+        });
+
+        if (caughtError.get()) {
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        } else {
+            return new ResponseEntity<>(modelInfrastructure, HttpStatus.OK);
+        }
+    }
+
+
+
+    @Override
+    public ResponseEntity<GenericResourceApiServicemodelinfrastructureService> operationalGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGet(String serviceInstanceId) {
+        GenericResourceApiServicemodelinfrastructureService retval = null;
+
+        List<OperationalServices> services = operationalServicesRepository.findBySvcInstanceId(serviceInstanceId);
+
+        if (services.isEmpty()) {
+            return new ResponseEntity<> (HttpStatus.NOT_FOUND);
+        } else {
+            OperationalServices service = services.get(0);
+            retval = new GenericResourceApiServicemodelinfrastructureService();
+            retval.setServiceInstanceId(serviceInstanceId);
+            retval.setServiceStatus(service.getServiceStatus());
+            try {
+                retval.setServiceData(objectMapper.readValue(service.getSvcData(), GenericResourceApiServicedataServiceData.class));
+            } catch (JsonProcessingException e) {
+                log.error("Could not deserialize service data for service instance id {}", serviceInstanceId, e);
+                retval = null;
+            }
+        }
+
+        if (retval == null) {
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        } else {
+            return new ResponseEntity<>(retval, HttpStatus.OK);
+        }
+    }
+
+
+    @Override
+    public ResponseEntity<GenericResourceApiServicedataServiceData> operationalGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataGet(String serviceInstanceId) {
+        GenericResourceApiServicedataServiceData serviceData = null;
+
+        List<OperationalServices> services = operationalServicesRepository.findBySvcInstanceId(serviceInstanceId);
+        if (services.isEmpty()) {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+        } else {
+            try {
+                serviceData = objectMapper.readValue(services.get(0).getSvcData(), GenericResourceApiServicedataServiceData.class);
+                return new ResponseEntity<>(serviceData, HttpStatus.OK);
+            } catch (JsonProcessingException e) {
+                log.error("Could not parse service data", e);
+                return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+            }
+        }
+    }
+
+    @Override
+    public ResponseEntity<GenericResourceApiServicestatusServiceStatus> operationalGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusGet(String serviceInstanceId) {
+        GenericResourceApiServicestatusServiceStatus serviceStatus = null;
+        List<OperationalServices> services = operationalServicesRepository.findBySvcInstanceId(serviceInstanceId);
+
+        if (!services.isEmpty()) {
+            OperationalServices service = services.get(0);
+            serviceStatus = service.getServiceStatus();
+        }
+
+        if (serviceStatus == null) {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+        } else {
+            return new ResponseEntity<>(serviceStatus, HttpStatus.OK);
+        }
+
+    }
+
+}
index a195c0c..e3a2bd7 100644 (file)
@@ -34,7 +34,7 @@ import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Import;
 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
-@SpringBootApplication(scanBasePackages= { "org.onap.sdnc.apps.ms.gra.*" })
+@SpringBootApplication(scanBasePackages= { "org.onap.sdnc.apps.ms.gra.*", "org.onap.ccsdk.apps.services"})
 @EnableSwagger2
 public class GenericResourceMsApp {
 
index c71ac98..5c1a923 100644 (file)
@@ -45,7 +45,7 @@ import javax.sql.DataSource;
 
 @Configuration
 @EnableJpaRepositories("org.onap.sdnc.apps.ms.gra.*")
-@ComponentScan(basePackages={"org.onap.sdnc.apps.ms.gra.*"})
+@ComponentScan(basePackages={"org.onap.sdnc.apps.ms.gra.*", "org.onap.ccsdk.apps.services"})
 @EntityScan("org.onap.sdnc.apps.ms.gra.*")
 @EnableTransactionManagement
 public class WebConfig implements WebMvcConfigurer {
index 4d0f9da..a23884d 100644 (file)
@@ -39,6 +39,7 @@ public class ConfigPreloadData {
     private String preloadType;
 
     @Lob
+    @Column(length=10000)
     private String preloadData;
 
     public ConfigPreloadData() {
index 187169a..ca22fff 100644 (file)
@@ -5,10 +5,7 @@ import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiRequestStatusEn
 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServiceStatus;
 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServicestatusServiceStatus;
 
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.Table;
+import javax.persistence.*;
 
 @Entity(name="CONFIG_GRA_SERVICES")
 @Table(name="CONFIG_GRA_SERVICES")
@@ -17,6 +14,7 @@ public class ConfigServices {
     String svcInstanceId;
 
     @Lob
+    @Column(columnDefinition = "clob")
     String svcData;
 
     // Service status fields
@@ -142,6 +140,16 @@ public class ConfigServices {
     }
 
     public GenericResourceApiServicestatusServiceStatus getServiceStatus() {
+
+        if ((serviceStatusAction == null) &&
+                (serviceStatusFinalIndicator == null) &&
+                (serviceStatusRequestStatus == null) &&
+                (serviceStatusResponseCode == null) &&
+                (serviceStatusResponseMessage == null) &&
+                (serviceStatusResponseTimestamp == null)) {
+            return null;
+        }
+
         GenericResourceApiServicestatusServiceStatus serviceStatus = new GenericResourceApiServicestatusServiceStatus();
         serviceStatus.setAction(serviceStatusAction);
         serviceStatus.setFinalIndicator(serviceStatusFinalIndicator);
@@ -154,11 +162,20 @@ public class ConfigServices {
     }
 
     public void setServiceStatus(GenericResourceApiServicestatusServiceStatus serviceStatus) {
-        this.serviceStatusAction = serviceStatus.getAction();
-        this.serviceStatusFinalIndicator = serviceStatus.getFinalIndicator();
-        this.serviceStatusRequestStatus = serviceStatus.getRequestStatus().toString();
-        this.serviceStatusResponseCode = serviceStatus.getResponseCode();
-        this.serviceStatusResponseMessage = serviceStatus.getResponseMessage();
-        this.serviceStatusResponseTimestamp = serviceStatus.getResponseTimestamp();
+        if (serviceStatus == null) {
+            this.serviceStatusAction = null;
+            this.serviceStatusFinalIndicator = null;
+            this.serviceStatusRequestStatus = null;
+            this.serviceStatusResponseCode = null;
+            this.serviceStatusResponseMessage = null;
+            this.serviceStatusResponseTimestamp = null;
+        } else {
+            this.serviceStatusAction = serviceStatus.getAction();
+            this.serviceStatusFinalIndicator = serviceStatus.getFinalIndicator();
+            this.serviceStatusRequestStatus = serviceStatus.getRequestStatus().toString();
+            this.serviceStatusResponseCode = serviceStatus.getResponseCode();
+            this.serviceStatusResponseMessage = serviceStatus.getResponseMessage();
+            this.serviceStatusResponseTimestamp = serviceStatus.getResponseTimestamp();
+        }
     }
 }
\ No newline at end of file
index 936d2f7..c39e24f 100644 (file)
@@ -39,6 +39,7 @@ public class OperationalPreloadData {
     private String preloadType;
 
     @Lob
+    @Column(columnDefinition = "clob")
     private String preloadData;
 
     public OperationalPreloadData() {
index eb46816..aab5246 100644 (file)
@@ -4,10 +4,7 @@ import org.hibernate.validator.constraints.Length;
 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiRequestStatusEnumeration;
 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServicestatusServiceStatus;
 
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.Table;
+import javax.persistence.*;
 
 @Entity(name="OPERATIONAL_GRA_SERVICES")
 @Table(name="OPERATIONAL_GRA_SERVICES")
@@ -16,7 +13,9 @@ public class OperationalServices {
     String svcInstanceId;
 
     @Lob
+    @Column(columnDefinition = "clob")
     String svcData;
+
     // Service status fields
     String serviceStatusResponseCode;
 
index 42ef339..5f04e33 100644 (file)
@@ -36,8 +36,7 @@ export MYSQL_DB_HOST=${MYSQL_DB_HOST:-dbhost}
 # Wait for database
 #
 echo "Waiting for database"
-until mysqladmin ping -h ${MYSQL_DB_HOST} --silent
-do
+until mysqladmin ping -h ${MYSQL_DB_HOST} --silent; do
   printf "."
   sleep 1
 done
@@ -45,30 +44,26 @@ echo -e "\nDatabase ready"
 
 # Create tablespace and user account
 
-mysql -h ${MYSQL_DB_HOST} -u root -p${MYSQL_ROOT_PASSWORD} mysql <<-END
-CREATE DATABASE ${MYSQL_DB_DATABASE};
-CREATE USER '${MYSQL_DB_USER}'@'localhost' IDENTIFIED BY '${MYSQL_DB_PASSWD}';
-CREATE USER '${MYSQL_DB_USER}'@'%' IDENTIFIED BY '${MYSQL_DB_PASSWD}';
-GRANT ALL PRIVILEGES ON ${MYSQL_DB_DATABASE}.* TO '${MYSQL_DB_USER}'@'localhost' WITH GRANT OPTION;
-GRANT ALL PRIVILEGES ON ${MYSQL_DB_DATABASE}.* TO '${MYSQL_DB_USER}'@'%' WITH GRANT OPTION;
-commit;
-END
+#mysql -h ${MYSQL_DB_HOST} -u root -p${MYSQL_ROOT_PASSWORD} mysql <<-END
+#CREATE DATABASE ${MYSQL_DB_DATABASE};
+#CREATE USER '${MYSQL_DB_USER}'@'localhost' IDENTIFIED BY '${MYSQL_DB_PASSWD}';
+#CREATE USER '${MYSQL_DB_USER}'@'%' IDENTIFIED BY '${MYSQL_DB_PASSWD}';
+#GRANT ALL PRIVILEGES ON ${MYSQL_DB_DATABASE}.* TO '${MYSQL_DB_USER}'@'localhost' WITH GRANT OPTION;
+#GRANT ALL PRIVILEGES ON ${MYSQL_DB_DATABASE}.* TO '${MYSQL_DB_USER}'@'%' WITH GRANT OPTION;
+#commit;
+#END
 
 # Initialize schema
 #mysql -h ${MYSQL_DB_HOST} -u ${MYSQL_DB_USER} -p${MYSQL_DB_PASSWD} ${MYSQL_DB_DATABASE} < ${SDNC_HOME}/config/schema.sql
 
-if [ ! -f ${SDNC_CERT_DIR}/${TRUSTSTORE} ]
-then
-    echo "${SDNC_CERT_DIR}/${TRUSTSTORE} not found ... cannot install ONAP CA certs"
-elif [ -z "$TRUSTSTORE_PASSWORD" ]
-then
-    echo "TRUSTSTORE_PASSWORD unset - cannot install ONAP CA certs"
+if [ ! -f ${SDNC_CERT_DIR}/${TRUSTSTORE} ]; then
+  echo "${SDNC_CERT_DIR}/${TRUSTSTORE} not found ... cannot install ONAP CA certs"
+elif [ -z "$TRUSTSTORE_PASSWORD" ]; then
+  echo "TRUSTSTORE_PASSWORD unset - cannot install ONAP CA certs"
 else
-    sudo keytool -importkeystore -srckeystore ${SDNC_CERT_DIR}/${TRUSTSTORE} -srcstorepass ${TRUSTSTORE_PASSWORD} -destkeystore ${JAVA_SECURITY_DIR}/cacerts  -deststorepass ${CACERT_PASSWORD}
-    echo -e "\nCerts ready"
+  sudo keytool -importkeystore -srckeystore ${SDNC_CERT_DIR}/${TRUSTSTORE} -srcstorepass ${TRUSTSTORE_PASSWORD} -destkeystore ${JAVA_SECURITY_DIR}/cacerts -deststorepass ${CACERT_PASSWORD}
+  echo -e "\nCerts ready"
 fi
 
-
 cd $SDNC_HOME
 java -DserviceLogicDirectory=${SVCLOGIC_DIR} -DLOG_PATH=${LOG_PATH} -jar ${SDNC_HOME}/lib/${GRA_JAR}
-
diff --git a/ms/generic-resource-api/src/main/templates/api.mustache b/ms/generic-resource-api/src/main/templates/api.mustache
new file mode 100644 (file)
index 0000000..c28642c
--- /dev/null
@@ -0,0 +1,136 @@
+/**
+* NOTE: This class is auto generated by the swagger code generator program ({{{generatorVersion}}}).
+* https://github.com/swagger-api/swagger-codegen
+* Do not edit the class manually.
+*/
+package {{package}};
+
+{{#imports}}import {{import}};
+{{/imports}}
+{{#jdk8-no-delegate}}
+    import com.fasterxml.jackson.databind.ObjectMapper;
+{{/jdk8-no-delegate}}
+import io.swagger.annotations.*;
+{{#jdk8-no-delegate}}
+    import org.slf4j.Logger;
+    import org.slf4j.LoggerFactory;
+    import org.springframework.http.HttpStatus;
+{{/jdk8-no-delegate}}
+import org.springframework.http.ResponseEntity;
+{{#useBeanValidation}}
+    import org.springframework.validation.annotation.Validated;
+{{/useBeanValidation}}
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+import org.onap.ccsdk.apps.services.RestException;
+
+{{#jdk8-no-delegate}}
+    import javax.servlet.http.HttpServletRequest;
+{{/jdk8-no-delegate}}
+{{#useBeanValidation}}
+    import javax.validation.Valid;
+    import javax.validation.constraints.*;
+{{/useBeanValidation}}
+{{#jdk8-no-delegate}}
+    import java.io.IOException;
+{{/jdk8-no-delegate}}
+import java.util.List;
+{{#jdk8-no-delegate}}
+    import java.util.Optional;
+{{/jdk8-no-delegate}}
+{{^jdk8-no-delegate}}
+    {{#useOptional}}
+        import java.util.Optional;
+    {{/useOptional}}
+{{/jdk8-no-delegate}}
+{{#async}}
+    import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
+{{/async}}
+{{>generatedAnnotation}}
+@Api(value = "{{{baseName}}}", description = "the {{{baseName}}} API")
+{{#operations}}
+    public interface {{classname}} {
+    {{#jdk8}}
+
+        {{^isDelegate}}
+            Logger log = LoggerFactory.getLogger({{classname}}.class);
+
+            default Optional<ObjectMapper> getObjectMapper() {
+                return Optional.empty();
+                }
+
+                default Optional<HttpServletRequest> getRequest() {
+                return Optional.empty();
+                }
+
+                default Optional<String> getAcceptHeader() {
+                return getRequest().map(r -> r.getHeader("Accept"));
+                }
+        {{/isDelegate}}
+        {{#isDelegate}}
+            {{classname}}Delegate getDelegate();
+        {{/isDelegate}}
+    {{/jdk8}}
+    {{#operation}}
+
+            @ApiOperation(value = "{{{summary}}}", nickname = "{{{operationId}}}", notes = "{{{notes}}}"{{#returnBaseType}}, response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
+        {{#authMethods}}@Authorization(value = "{{name}}"{{#isOAuth}}, scopes = {
+        {{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}},
+        {{/hasMore}}{{/scopes}}
+            }{{/isOAuth}}){{#hasMore}},
+        {{/hasMore}}{{/authMethods}}
+            }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} })
+            @ApiResponses(value = { {{#responses}}
+                @ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}} })
+        {{#implicitHeaders}}
+                @ApiImplicitParams({
+            {{#headerParams}}
+                {{>implicitHeader}}
+            {{/headerParams}}
+                })
+        {{/implicitHeaders}}
+            @RequestMapping(value = "{{{path}}}",{{#singleContentTypes}}
+                produces = "{{{vendorExtensions.x-accepts}}}",
+                consumes = "{{{vendorExtensions.x-contentType}}}",{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}}
+                produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}{{#hasConsumes}}
+                consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}{{/singleContentTypes}}
+            method = RequestMethod.{{httpMethod}})
+        {{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}){{^jdk8}};{{/jdk8}}{{#jdk8}} throws RestException {
+        {{#delegate-method}}
+                return {{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+                }
+
+                // Override this method
+                default {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{{dataType}}}{{/isFile}}{{#isFile}}MultipartFile{{/isFile}} {{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}}) throws RestException {
+        {{/delegate-method}}
+        {{^isDelegate}}
+                if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
+            {{#examples}}
+                    if (getAcceptHeader().get().contains("{{{contentType}}}")) {
+                    try {
+                    return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(getObjectMapper().get().readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
+                    } catch (IOException e) {
+                    log.error("Couldn't serialize response for content type {{{contentType}}}", e);
+                    return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR){{#async}}){{/async}};
+                    }
+                    }
+            {{/examples}}
+                } else {
+                log.warn("ObjectMapper or HttpServletRequest not configured in default {{classname}} interface so no example is generated");
+                }
+                return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
+        {{/isDelegate}}
+        {{#isDelegate}}
+                return getDelegate().{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+        {{/isDelegate}}
+            }{{/jdk8}}
+
+    {{/operation}}
+        }
+{{/operations}}
\ No newline at end of file
diff --git a/ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/ConfigApiPreloadControllerTest.java b/ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/ConfigApiPreloadControllerTest.java
new file mode 100644 (file)
index 0000000..7e7a3ac
--- /dev/null
@@ -0,0 +1,468 @@
+package org.onap.sdnc.apps.ms.gra.controllers;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.sdnc.apps.ms.gra.core.GenericResourceMsApp;
+import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadData;
+import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadDataRepository;
+import org.onap.sdnc.apps.ms.gra.data.ConfigServicesRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.assertEquals;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes={GenericResourceMsApp.class})
+@AutoConfigureMockMvc
+@Transactional
+public class ConfigApiPreloadControllerTest {
+
+    private final static String CONFIG_PRELOAD_URL = "/config/GENERIC-RESOURCE-API:preload-information/";
+    private final static String CONFIG_PRELOAD_LIST_URL = "/config/GENERIC-RESOURCE-API:preload-information/GENERIC-RESOURCE-API:preload-list/";
+
+
+    @Autowired
+    private MockMvc mvc;
+
+    @Autowired
+    ConfigPreloadDataRepository configPreloadDataRepository;
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        System.setProperty("serviceLogicProperties", "src/test/resources/svclogic.properties");
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationDelete() throws Exception {
+
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        // Load test data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+
+        assertEquals(1, configPreloadDataRepository.count());
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_PRELOAD_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+
+        // Test with no data
+        mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_PRELOAD_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGet() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_PRELOAD_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+        // Test with no data
+        configPreloadDataRepository.deleteAll();
+        mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_PRELOAD_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationPost() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/preload1-net-model-info.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+        // Test with existing data - should return 409
+        mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(409, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationPut() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/preload1-net-model-info.json");
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPost() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/preload1-net-model-info.json");
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_LIST_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeDelete() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+
+        // Test without data
+        mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGet() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+        // Test with no data
+        configPreloadDataRepository.deleteAll();
+        mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypePostNoData() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/preload1-net-list-item.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypePostExistingData() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+
+        String content = readFileContent("src/test/resources/preload1-net-list-item.json");
+
+        // Test with existing data - should return 409
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(409, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+    }
+
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypePut() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String badContent = readFileContent("src/test/resources/preload1-net-model-info.json");
+        String goodContent = readFileContent("src/test/resources/preload1-net-list-item.json");
+
+        // Test with bad file content
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(badContent))
+                .andReturn();
+        assertEquals(400, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+
+        // Test with no data
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+        // Test with existing data - should return 204
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_LIST_URL+"preload1/network/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+    }
+
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataDelete() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+        // Test without data
+        configPreloadDataRepository.deleteAll();
+        assertEquals(0, configPreloadDataRepository.count());
+        mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataGet() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+        // Test with no data
+        configPreloadDataRepository.deleteAll();
+        mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPostNoData() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String goodContent = readFileContent("src/test/resources/preload1-net-preload-data.json");
+
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPostBadContent() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String badContent = readFileContent("src/test/resources/preload1-net-model-info.json");
+
+        // Load single entry with no preloadData
+        ConfigPreloadData preloadData = new ConfigPreloadData();
+        preloadData.setPreloadId("preload1");
+        preloadData.setPreloadType("network");
+        preloadData.setPreloadData(null);
+        configPreloadDataRepository.save(preloadData);
+
+        // Test with bad file content
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(badContent))
+                .andReturn();
+        assertEquals(400, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPostGoodData() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String goodContent = readFileContent("src/test/resources/preload1-net-preload-data.json");
+
+        // Load single entry with no preloadData
+        ConfigPreloadData preloadData = new ConfigPreloadData();
+        preloadData.setPreloadId("preload1");
+        preloadData.setPreloadType("network");
+        preloadData.setPreloadData(null);
+        configPreloadDataRepository.save(preloadData);
+
+
+        // Test with no existing preload data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPostExistingRecord() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String goodContent = readFileContent("src/test/resources/preload1-net-preload-data.json");
+
+
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+
+
+        // Test with existing preload dat
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+        assertEquals(409, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+    }
+
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPutNoData() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String goodContent = readFileContent("src/test/resources/preload1-net-preload-data.json");
+
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configPreloadDataRepository.count());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPutBadContent() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String badContent = readFileContent("src/test/resources/preload1-net-model-info.json");
+
+        // Load single entry with no preloadData
+        ConfigPreloadData preloadData = new ConfigPreloadData();
+        preloadData.setPreloadId("preload1");
+        preloadData.setPreloadType("network");
+        preloadData.setPreloadData(null);
+        configPreloadDataRepository.save(preloadData);
+
+        // Test with bad file content
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(badContent))
+                .andReturn();
+        assertEquals(400, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPutGoodData() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String goodContent = readFileContent("src/test/resources/preload1-net-preload-data.json");
+
+        // Load single entry with no preloadData
+        ConfigPreloadData preloadData = new ConfigPreloadData();
+        preloadData.setPreloadId("preload1");
+        preloadData.setPreloadType("network");
+        preloadData.setPreloadData(null);
+        configPreloadDataRepository.save(preloadData);
+
+
+        // Test with no existing preload data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIpreloadInformationGENERICRESOURCEAPIpreloadListPreloadIdPreloadTypeGENERICRESOURCEAPIpreloadDataPutExistingRecord() throws Exception {
+        // Clean up data
+        configPreloadDataRepository.deleteAll();
+
+        String goodContent = readFileContent("src/test/resources/preload1-net-preload-data.json");
+
+
+        // Test with data
+        loadData(CONFIG_PRELOAD_URL, "src/test/resources/preload1-net-model-info.json");
+        assert(configPreloadDataRepository.count() > 0);
+
+
+        // Test with existing preload dat
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_PRELOAD_LIST_URL+"preload1/network/GENERIC-RESOURCE-API:preload-data/").contentType(MediaType.APPLICATION_JSON).content(goodContent))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(1, configPreloadDataRepository.count());
+    }
+
+    private String readFileContent(String path) throws IOException {
+        String content = new String(Files.readAllBytes(Paths.get(path)));
+        return content;
+    }
+
+    private void deleteData(String url) throws Exception {
+        mvc.perform(MockMvcRequestBuilders.delete(url).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+    }
+
+    private void loadData(String url, String path) throws Exception {
+        String content = readFileContent(path);
+        mvc.perform(MockMvcRequestBuilders.post(url).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+
+
+    }
+}
\ No newline at end of file
diff --git a/ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/ConfigApiServicesControllerTest.java b/ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/ConfigApiServicesControllerTest.java
new file mode 100644 (file)
index 0000000..5653b3b
--- /dev/null
@@ -0,0 +1,487 @@
+package org.onap.sdnc.apps.ms.gra.controllers;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.sdnc.apps.ms.gra.core.GenericResourceMsApp;
+import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadData;
+import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadDataRepository;
+import org.onap.sdnc.apps.ms.gra.data.ConfigServices;
+import org.onap.sdnc.apps.ms.gra.data.ConfigServicesRepository;
+import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServiceModelInfrastructure;
+import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServicemodelinfrastructureService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes={GenericResourceMsApp.class})
+@AutoConfigureMockMvc
+@Transactional
+public class ConfigApiServicesControllerTest {
+
+    private final static String CONFIG_SERVICES_URL = "/config/GENERIC-RESOURCE-API:services/";
+    private final static String CONFIG_SERVICES_SERVICE_URL = "/config/GENERIC-RESOURCE-API:services/GENERIC-RESOURCE-API:service/";
+
+    @Autowired
+    private MockMvc mvc;
+
+    @Autowired
+    ConfigServicesRepository configServicesRepository;
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        System.setProperty("serviceLogicProperties", "src/test/resources/svclogic.properties");
+    }
+
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesDelete() throws Exception {
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Load test data
+        loadServicesData( "src/test/resources/service1.json");
+
+        assertEquals(1, configServicesRepository.count());
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Test with no data
+        mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGet() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Test with data
+        loadServicesData("src/test/resources/service1.json");
+        assert(configServicesRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+        // Test with no data
+        configServicesRepository.deleteAll();
+        mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesPost() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Test with existing data - should return 409
+        mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(409, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesPut() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Test with existing data - should return 409
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_URL).contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdDelete() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Load data
+        loadServicesData("src/test/resources/service1.json");
+        assertEquals(1, configServicesRepository.count());
+
+        // Test with data
+        mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGet() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Test with data
+        loadServicesData("src/test/resources/service1.json");
+        assert(configServicesRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+        // Test with no data
+        configServicesRepository.deleteAll();
+        mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdPost() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1-serviceitem.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Test with existing data - should return 409
+        mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(409, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdPut() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1-serviceitem.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Test with existing data - should return 409
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataDelete() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Load data
+        loadServicesData("src/test/resources/service1.json");
+        assertEquals(1, configServicesRepository.count());
+
+        // Test with data
+        mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId("service1");
+        assertEquals(1, services.size());
+        assertEquals(null, services.get(0).getSvcData());
+
+
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataGet() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Test with data
+        loadServicesData("src/test/resources/service1.json");
+        assert(configServicesRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+        // Test with no data
+        configServicesRepository.deleteAll();
+        mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataPost() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1-servicedata.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Test with empty service data
+        ConfigServices service = new ConfigServices();
+        service.setSvcInstanceId("service1");
+        configServicesRepository.save(service);
+        assertEquals(1, configServicesRepository.count());
+        mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+        List<ConfigServices> updatedService = configServicesRepository.findBySvcInstanceId("service1");
+        assertEquals(1, updatedService.size());
+        assertNotEquals(null, updatedService.get(0).getSvcData());
+
+        // Test with existing data - should return 409
+        mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(409, mvcResult.getResponse().getStatus());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceDataPut() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1-servicedata.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Test with empty service data
+        ConfigServices service = new ConfigServices();
+        service.setSvcInstanceId("service1");
+        configServicesRepository.save(service);
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+        List<ConfigServices> updatedService = configServicesRepository.findBySvcInstanceId("service1");
+        assertEquals(1, updatedService.size());
+        assertNotEquals(null, updatedService.get(0).getSvcData());
+
+        // Test with existing data - should return 204
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-data/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusDelete() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Load data
+        loadServicesData("src/test/resources/service1.json");
+        assertEquals(1, configServicesRepository.count());
+
+        // Test with data
+        mvcResult = mvc.perform(MockMvcRequestBuilders.delete(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+        List<ConfigServices> services = configServicesRepository.findBySvcInstanceId("service1");
+        assertEquals(1, services.size());
+        assertEquals(null, services.get(0).getServiceStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusGet() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        // Test with data
+        loadServicesData("src/test/resources/service1.json");
+        assert(configServicesRepository.count() > 0);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+        // Test with no data
+        configServicesRepository.deleteAll();
+        mvcResult = mvc.perform(MockMvcRequestBuilders.get(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusPost() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1-servicestatus.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Test with empty service data
+        ConfigServices service = new ConfigServices();
+        service.setSvcInstanceId("service1");
+        configServicesRepository.save(service);
+        mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+        List<ConfigServices> updatedService = configServicesRepository.findBySvcInstanceId("service1");
+        assertEquals(1, updatedService.size());
+        assertNotEquals(null, updatedService.get(0).getServiceStatus());
+
+        // Test with existing data - should return 409
+        mvcResult = mvc.perform(MockMvcRequestBuilders.post(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(409, mvcResult.getResponse().getStatus());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+    }
+
+    @Test
+    public void configGENERICRESOURCEAPIservicesGENERICRESOURCEAPIserviceServiceInstanceIdGENERICRESOURCEAPIserviceStatusPut() throws Exception {
+        // Clean up data
+        configServicesRepository.deleteAll();
+
+        String content = readFileContent("src/test/resources/service1-servicestatus.json");
+
+        // Test with no data
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(404, mvcResult.getResponse().getStatus());
+        assertEquals(0, configServicesRepository.count());
+
+        // Test with empty service status
+        ConfigServices service = new ConfigServices();
+        service.setSvcInstanceId("service1");
+        configServicesRepository.save(service);
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(201, mvcResult.getResponse().getStatus());
+        assertEquals(1, configServicesRepository.count());
+        List<ConfigServices> updatedService = configServicesRepository.findBySvcInstanceId("service1");
+        assertEquals(1, updatedService.size());
+        assertNotEquals(null, updatedService.get(0).getServiceStatus());
+
+        // Test with existing data - should return 204
+        mvcResult = mvc.perform(MockMvcRequestBuilders.put(CONFIG_SERVICES_SERVICE_URL+"service1/GENERIC-RESOURCE-API:service-status/").contentType(MediaType.APPLICATION_JSON).content(content))
+                .andReturn();
+        assertEquals(204, mvcResult.getResponse().getStatus());
+
+        // Clean up data
+        configServicesRepository.deleteAll();
+    }
+
+    private String readFileContent(String path) throws IOException {
+        String content = new String(Files.readAllBytes(Paths.get(path)));
+        return content;
+    }
+
+    private void deleteData(String url) throws Exception {
+        mvc.perform(MockMvcRequestBuilders.delete(url).contentType(MediaType.APPLICATION_JSON).content(""))
+                .andReturn();
+    }
+
+    private void loadServicesData(String path) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        String content = readFileContent(path);
+        GenericResourceApiServiceModelInfrastructure services = objectMapper.readValue(content, GenericResourceApiServiceModelInfrastructure.class);
+
+        for (GenericResourceApiServicemodelinfrastructureService service : services.getService()) {
+            ConfigServices newService = new ConfigServices();
+            newService.setSvcInstanceId(service.getServiceInstanceId());
+            newService.setSvcData(objectMapper.writeValueAsString(service.getServiceData()));
+            newService.setServiceStatus(service.getServiceStatus());
+            configServicesRepository.save(newService);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/GenericResourceMsAppTest.java b/ms/generic-resource-api/src/test/java/org/onap/sdnc/apps/ms/gra/controllers/GenericResourceMsAppTest.java
new file mode 100644 (file)
index 0000000..0a19f39
--- /dev/null
@@ -0,0 +1,42 @@
+package org.onap.sdnc.apps.ms.gra.controllers;
+
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.PropertiesRealm;
+import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.sdnc.apps.ms.gra.core.GenericResourceMsApp;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class GenericResourceMsAppTest {
+
+    GenericResourceMsApp app;
+
+    @Before
+    public  void setUp() throws Exception {
+        app = new GenericResourceMsApp();
+        System.setProperty("serviceLogicProperties", "src/test/resources/svclogic.properties");
+    }
+
+    @Test
+    public void realm() {
+        Realm realm = app.realm();
+        assertTrue(realm instanceof PropertiesRealm);
+
+
+    }
+
+    @Test
+    public void shiroFilterChainDefinition() {
+        ShiroFilterChainDefinition chainDefinition = app.shiroFilterChainDefinition();
+        Map<String, String> chainMap = chainDefinition.getFilterChainMap();
+        assertEquals("anon", chainMap.get("/**"));
+
+
+    }
+}
\ No newline at end of file
diff --git a/ms/generic-resource-api/src/test/resources/application.properties b/ms/generic-resource-api/src/test/resources/application.properties
new file mode 100644 (file)
index 0000000..04538f1
--- /dev/null
@@ -0,0 +1,20 @@
+springfox.documentation.swagger.v2.path=/api-docs
+server.servlet.context-path=/restconf
+server.port=8080
+spring.jackson.date-format=org.onap.sdnc.apps.ms.gra.swagger.RFC3339DateFormat
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
+logging.level.com.att=TRACE
+logging.level.org.onap=TRACE
+spring.datasource.url=jdbc:derby:memory:sdnctl;create=true
+spring.datasource.username=sdnc
+spring.datasource.password=abc123
+spring.datasource.driver-class-name=org.apache.derby.jdbc.EmbeddedDriver
+spring.datasource.testWhileIdle=true
+spring.datasource.validationQuery=SELECT 1
+spring.jpa.show-sql=true
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
+# spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
+spring.jpa.database=derby
+serviceLogicProperties=src/test/resources/svclogic.properties
\ No newline at end of file
diff --git a/ms/generic-resource-api/src/test/resources/preload.data b/ms/generic-resource-api/src/test/resources/preload.data
deleted file mode 100644 (file)
index d1e52f5..0000000
+++ /dev/null
@@ -1,518 +0,0 @@
-{
-    "preload-list": [
-        {
-            "preload-data": {
-                "preload-network-topology-information": {
-                    "host-routes": null,
-                    "network-policy": null,
-                    "network-topology-identifier-structure": {
-                        "related-networks": null,
-                        "network-role": "master",
-                        "is-trunked": false,
-                        "network-technology": "AI",
-                        "network-id": "123",
-                        "eipam-v4-address-plan": "evilv4",
-                        "network-instance-group-id": null,
-                        "network-name": "sky-net",
-                        "segmentation-id": null,
-                        "eipam-v6-address-plan": "evilv6",
-                        "network-type": "evil"
-                    },
-                    "physical-network-name": null,
-                    "is-external-network": null,
-                    "is-shared-network": null,
-                    "is-provider-network": null,
-                    "route-table-reference": null,
-                    "subnets": null,
-                    "vpn-bindings": null
-                },
-                "preload-oper-status": null,
-                "preload-vf-module-topology-information": null
-            },
-            "preload-type": "network",
-            "preload-id": "preload1"
-        },
-        {
-            "preload-data": {
-                "preload-network-topology-information": {
-                    "host-routes": [
-                        {
-                            "route-prefix": "12",
-                            "next-hop": "10.1.12.1"
-                        }
-                    ],
-                    "network-policy": [
-                        {
-                            "network-policy-fqdn": "policy-sdnc.onap.org",
-                            "network-policy-id": "123"
-                        }
-                    ],
-                    "network-topology-identifier-structure": {
-                        "related-networks": {
-                            "related-network": [
-                                {
-                                    "vlan-tags": {
-                                        "is-private": true,
-                                        "vlan-interface": "string",
-                                        "upper-tag-id": 0,
-                                        "lower-tag-id": 0
-                                    },
-                                    "network-role": "string",
-                                    "network-id": "string"
-                                }
-                            ]
-                        },
-                        "network-role": "secret",
-                        "is-trunked": true,
-                        "network-technology": "soupcan",
-                        "network-id": "321",
-                        "eipam-v4-address-plan": "plan9",
-                        "network-instance-group-id": "abc123",
-                        "network-name": "syfy",
-                        "segmentation-id": "string",
-                        "eipam-v6-address-plan": "plan9v6",
-                        "network-type": "fake"
-                    },
-                    "physical-network-name": "string",
-                    "is-external-network": true,
-                    "is-shared-network": true,
-                    "is-provider-network": true,
-                    "route-table-reference": [
-                        {
-                            "route-table-reference-id": "string",
-                            "route-table-reference-fqdn": "string"
-                        }
-                    ],
-                    "subnets": [
-                        {
-                            "subnet-role": "string",
-                            "cidr-mask": "string",
-                            "subnet-sequence": 0,
-                            "addr-from-start": "Y",
-                            "dhcp-start-address": "string",
-                            "gateway-address": "string",
-                            "dhcp-end-address": "string",
-                            "ip-version": "string",
-                            "start-address": "string",
-                            "dhcp-enabled": "Y",
-                            "subnet-name": "string"
-                        }
-                    ],
-                    "vpn-bindings": [
-                        {
-                            "vpn-name": "string",
-                            "vpn-binding-id": "string",
-                            "route-target-role": "string",
-                            "aic-zone": "string",
-                            "global-route-target": "string"
-                        }
-                    ]
-                },
-                "preload-oper-status": null,
-                "preload-vf-module-topology-information": null
-            },
-            "preload-type": null,
-            "preload-id": null
-        },
-        {
-            "preload-data": {
-                "preload-network-topology-information": null,
-                "preload-oper-status": null,
-                "preload-vf-module-topology-information": {
-                    "vf-module-topology": {
-                        "onap-model-information": {
-                            "model-name": "string",
-                            "model-version": "string",
-                            "model-customization-uuid": "string",
-                            "model-uuid": "string",
-                            "model-invariant-uuid": "string"
-                        },
-                        "aic-clli": "string",
-                        "aic-cloud-region": "string",
-                        "cloud-owner": "string",
-                        "tenant": "string",
-                        "vf-module-assignments": {
-                            "vlan-vnfc-instance-groups": {
-                                "vlan-vnfc-instance-group": [
-                                    {
-                                        "vnf-id": "string",
-                                        "vnfcs": {
-                                            "vnfc": [
-                                                {
-                                                    "vnic-groups": {
-                                                        "vnic-group": [
-                                                            {
-                                                                "vlan-vnics": {
-                                                                    "vlan-vnic": [
-                                                                        {
-                                                                            "vnic-sub-interfaces": {
-                                                                                "sub-interface-network-data": [
-                                                                                    {
-                                                                                        "network-role": "string",
-                                                                                        "floating-ips": {
-                                                                                            "floating-ip-v4": [
-                                                                                                "string"
-                                                                                            ],
-                                                                                            "floating-ip-v6": [
-                                                                                                "string"
-                                                                                            ]
-                                                                                        },
-                                                                                        "network-id": "string",
-                                                                                        "network-information-items": {
-                                                                                            "network-information-item": [
-                                                                                                {
-                                                                                                    "ip-version": "string",
-                                                                                                    "network-ips": {
-                                                                                                        "network-ip": [
-                                                                                                            "string"
-                                                                                                        ]
-                                                                                                    },
-                                                                                                    "ip-count": 0,
-                                                                                                    "use-dhcp": "Y"
-                                                                                                }
-                                                                                            ]
-                                                                                        },
-                                                                                        "neutron-network-id": "string",
-                                                                                        "network-name": 0,
-                                                                                        "network-role-tag": "string",
-                                                                                        "vlan-tag-id": 0
-                                                                                    }
-                                                                                ]
-                                                                            },
-                                                                            "vnic-port-id": "string"
-                                                                        }
-                                                                    ]
-                                                                },
-                                                                "vlan-assignment-policy-name": "string",
-                                                                "vlan-common-ip-addresses": {
-                                                                    "ip-addresses": {
-                                                                        "vipv6-address": "string",
-                                                                        "ipv4-address": "string",
-                                                                        "vipv4-address": "string",
-                                                                        "ipv6-address": "string"
-                                                                    }
-                                                                },
-                                                                "network-instance-group-function": "string",
-                                                                "vlan-tag-index-next": 0,
-                                                                "vnic-interface-role": "string"
-                                                            }
-                                                        ]
-                                                    },
-                                                    "vnfc-name": "string"
-                                                }
-                                            ]
-                                        },
-                                        "instance-group-id": "string",
-                                        "instance-group-function": "string"
-                                    }
-                                ]
-                            },
-                            "vf-module-status": "string",
-                            "vms": {
-                                "vm": [
-                                    {
-                                        "onap-model-information": {
-                                            "model-name": "string",
-                                            "model-version": "string",
-                                            "model-customization-uuid": "string",
-                                            "model-uuid": "string",
-                                            "model-invariant-uuid": "string"
-                                        },
-                                        "vm-type": "string",
-                                        "vm-names": {
-                                            "vnfc-names": [
-                                                {
-                                                    "vnfc-networks": {
-                                                        "vnfc-network-data": [
-                                                            {
-                                                                "connection-point": {
-                                                                    "vlan-data": [
-                                                                        {
-                                                                            "vlan-tag-description": "string",
-                                                                            "vlan-uuid": "string",
-                                                                            "vlan-role": "string",
-                                                                            "vlan-tag-id": "string"
-                                                                        }
-                                                                    ],
-                                                                    "port-id": "string",
-                                                                    "connection-point-id": "string"
-                                                                },
-                                                                "vnfc-ports": {
-                                                                    "vnfc-port": [
-                                                                        {
-                                                                            "vnfc-port-id": "string",
-                                                                            "vnic-sub-interfaces": {
-                                                                                "sub-interface-network-data": [
-                                                                                    {
-                                                                                        "network-role": "string",
-                                                                                        "floating-ips": {
-                                                                                            "floating-ip-v4": [
-                                                                                                "string"
-                                                                                            ],
-                                                                                            "floating-ip-v6": [
-                                                                                                "string"
-                                                                                            ]
-                                                                                        },
-                                                                                        "network-id": "string",
-                                                                                        "network-information-items": {
-                                                                                            "network-information-item": [
-                                                                                                {
-                                                                                                    "ip-version": "string",
-                                                                                                    "network-ips": {
-                                                                                                        "network-ip": [
-                                                                                                            "string"
-                                                                                                        ]
-                                                                                                    },
-                                                                                                    "ip-count": 0,
-                                                                                                    "use-dhcp": "Y"
-                                                                                                }
-                                                                                            ]
-                                                                                        },
-                                                                                        "neutron-network-id": "string",
-                                                                                        "network-name": 0,
-                                                                                        "network-role-tag": "string",
-                                                                                        "vlan-tag-id": 0
-                                                                                    }
-                                                                                ]
-                                                                            },
-                                                                            "common-sub-interface-role": "string"
-                                                                        }
-                                                                    ]
-                                                                },
-                                                                "vnfc-type": "string",
-                                                                "vnfc-subnet": [
-                                                                    {
-                                                                        "vnfc-subnet-role": "string",
-                                                                        "vnfc-ip-assignments": [
-                                                                            {
-                                                                                "vnfc-subnet-dhcp": "Y",
-                                                                                "vnfc-address-family": "ipv4",
-                                                                                "vnfc-subnet-ip": [
-                                                                                    {
-                                                                                        "vnfc-ip-address": "string",
-                                                                                        "vnfc-client-key": "string",
-                                                                                        "ip-type": "FIXED"
-                                                                                    }
-                                                                                ],
-                                                                                "vnfc-subnet-ip-count": 0
-                                                                            }
-                                                                        ]
-                                                                    }
-                                                                ],
-                                                                "vnfc-network-role": "string"
-                                                            }
-                                                        ]
-                                                    },
-                                                    "vnfc-name": "string"
-                                                }
-                                            ],
-                                            "vm-name": [
-                                                "string"
-                                            ]
-                                        },
-                                        "vm-type-tag": "string",
-                                        "vm-count": 0,
-                                        "vm-networks": {
-                                            "vm-network": [
-                                                {
-                                                    "related-networks": {
-                                                        "related-network": [
-                                                            {
-                                                                "vlan-tags": {
-                                                                    "is-private": true,
-                                                                    "vlan-interface": "string",
-                                                                    "upper-tag-id": 0,
-                                                                    "lower-tag-id": 0
-                                                                },
-                                                                "network-role": "string",
-                                                                "network-id": "string"
-                                                            }
-                                                        ]
-                                                    },
-                                                    "network-role": "string",
-                                                    "is-trunked": true,
-                                                    "floating-ips": {
-                                                        "floating-ip-v4": [
-                                                            "string"
-                                                        ],
-                                                        "floating-ip-v6": [
-                                                            "string"
-                                                        ]
-                                                    },
-                                                    "sriov-parameters": {
-                                                        "application-tags": {
-                                                            "stags": {
-                                                                "stag": [
-                                                                    "string"
-                                                                ],
-                                                                "s-tag": [
-                                                                    "string"
-                                                                ]
-                                                            },
-                                                            "ctags": {
-                                                                "ctag": [
-                                                                    "string"
-                                                                ],
-                                                                "c-tag": [
-                                                                    "string"
-                                                                ]
-                                                            },
-                                                            "s-tags": {
-                                                                "stag": [
-                                                                    "string"
-                                                                ],
-                                                                "s-tag": [
-                                                                    "string"
-                                                                ]
-                                                            },
-                                                            "c-tags": {
-                                                                "ctag": [
-                                                                    "string"
-                                                                ],
-                                                                "c-tag": [
-                                                                    "string"
-                                                                ]
-                                                            }
-                                                        },
-                                                        "heat-vlan-filters": {
-                                                            "heat-vlan-filter": [
-                                                                "string"
-                                                            ]
-                                                        }
-                                                    },
-                                                    "network-information-items": {
-                                                        "network-information-item": [
-                                                            {
-                                                                "ip-version": "string",
-                                                                "network-ips": {
-                                                                    "network-ip": [
-                                                                        "string"
-                                                                    ]
-                                                                },
-                                                                "ip-count": 0,
-                                                                "use-dhcp": "Y"
-                                                            }
-                                                        ]
-                                                    },
-                                                    "mac-addresses": {
-                                                        "mac-address": [
-                                                            "string"
-                                                        ]
-                                                    },
-                                                    "network-role-tag": "string",
-                                                    "segmentation-id": "string",
-                                                    "interface-route-prefixes": {
-                                                        "interface-route-prefix": [
-                                                            "string"
-                                                        ]
-                                                    }
-                                                }
-                                            ]
-                                        },
-                                        "nfc-naming-code": "string"
-                                    }
-                                ]
-                            },
-                            "dhcp-subnet-assignments": {
-                                "dhcp-subnet-assignment": [
-                                    {
-                                        "network-role": "string",
-                                        "neutron-subnet-id": "string",
-                                        "ip-version": "string"
-                                    }
-                                ]
-                            }
-                        },
-                        "vf-module-topology-identifier": {
-                            "vf-module-name": "string",
-                            "vf-module-id": "string",
-                            "vf-module-type": "string"
-                        },
-                        "vf-module-parameters": {
-                            "param": [
-                                {
-                                    "name": "string",
-                                    "resource-resolution-data": {
-                                        "payload": "string",
-                                        "resource-key": [
-                                            {
-                                                "name": "string",
-                                                "value": "string"
-                                            }
-                                        ],
-                                        "capability-name": "string",
-                                        "status": "string"
-                                    },
-                                    "value": "string"
-                                }
-                            ]
-                        },
-                        "sdnc-generated-cloud-resources": true
-                    },
-                    "vnf-resource-assignments": {
-                        "availability-zones": {
-                            "max-count": 0,
-                            "availability-zone": [
-                                "string"
-                            ]
-                        },
-                        "vnf-status": "string",
-                        "vnf-networks": {
-                            "vnf-network": [
-                                {
-                                    "related-networks": {
-                                        "related-network": [
-                                            {
-                                                "vlan-tags": {
-                                                    "is-private": true,
-                                                    "vlan-interface": "string",
-                                                    "upper-tag-id": 0,
-                                                    "lower-tag-id": 0
-                                                },
-                                                "network-role": "string",
-                                                "network-id": "string"
-                                            }
-                                        ]
-                                    },
-                                    "network-role": "string",
-                                    "is-trunked": true,
-                                    "network-id": "string",
-                                    "subnets-data": {
-                                        "subnet-data": [
-                                            {
-                                                "network-start-address": "string",
-                                                "subnet-role": "string",
-                                                "cidr-mask": "string",
-                                                "gateway-address": "string",
-                                                "sdnc-subnet-id": "string",
-                                                "subnet-id": "string",
-                                                "ip-version": "string",
-                                                "dhcp-enabled": "Y",
-                                                "subnet-name": "string"
-                                            }
-                                        ]
-                                    },
-                                    "contrail-network-fqdn": "string",
-                                    "network-name": "string",
-                                    "segmentation-id": "string",
-                                    "neutron-id": "string"
-                                }
-                            ]
-                        }
-                    },
-                    "vnf-topology-identifier-structure": {
-                        "nf-role": "string",
-                        "nf-function": "string",
-                        "nf-type": "string",
-                        "vnf-id": "string",
-                        "nf-code": "string",
-                        "vnf-name": "string",
-                        "vnf-type": "string"
-                    }
-                }
-            },
-            "preload-type": null,
-            "preload-id": null
-        }
-    ]
-}
diff --git a/ms/generic-resource-api/src/test/resources/preload1-net-list-item.json b/ms/generic-resource-api/src/test/resources/preload1-net-list-item.json
new file mode 100644 (file)
index 0000000..4a91388
--- /dev/null
@@ -0,0 +1,81 @@
+{
+  "preload-id": "preload1",
+  "preload-type": "network",
+  "preload-data": {
+    "preload-network-topology-information": {
+      "host-routes": [
+        {
+          "next-hop": "10.1.12.1",
+          "route-prefix": "12"
+        }
+      ],
+      "is-external-network": false,
+      "is-provider-network": false,
+      "is-shared-network": false,
+      "network-policy": [
+        {
+          "network-policy-fqdn": "policy-sdnc.onap.org",
+          "network-policy-id": "123"
+        }
+      ],
+      "network-topology-identifier-structure": {
+        "eipam-v4-address-plan": "plan9",
+        "eipam-v6-address-plan": "plan9v6",
+        "is-trunked": true,
+        "network-id": "preload1",
+        "network-instance-group-id": "abc123",
+        "network-name": "syfy",
+        "network-role": "secret",
+        "network-technology": "soupcan",
+        "network-type": "fake",
+        "related-networks": {
+          "related-network": [
+            {
+              "network-id": "skynet",
+              "network-role": "master",
+              "vlan-tags": {
+                "is-private": true,
+                "lower-tag-id": 0,
+                "upper-tag-id": 0,
+                "vlan-interface": "le0"
+              }
+            }
+          ]
+        },
+        "segmentation-id": "seg1"
+      },
+      "physical-network-name": "skynet",
+      "route-table-reference": [
+        {
+          "route-table-reference-fqdn": "sky.net",
+          "route-table-reference-id": "ref1"
+        }
+      ],
+      "subnets": [
+        {
+          "addr-from-start": "Y",
+          "cidr-mask": "255.255.0.0",
+          "dhcp-enabled": "Y",
+          "dhcp-end-address": "10.1.2.254",
+          "dhcp-start-address": "10.1.2.1",
+          "gateway-address": "10.1.2.255",
+          "ip-version": "ipv4",
+          "start-address": "10.1.2.1",
+          "subnet-name": "subnet1",
+          "subnet-role": "puppies",
+          "subnet-sequence": 0
+        }
+      ],
+      "vpn-bindings": [
+        {
+          "aic-zone": "zone1",
+          "global-route-target": "string",
+          "route-target-role": "string",
+          "vpn-binding-id": "string",
+          "vpn-name": "string"
+        }
+      ]
+    }
+  }
+}
+
@@ -24,7 +24,7 @@
                         "eipam-v4-address-plan": "plan9",
                         "eipam-v6-address-plan": "plan9v6",
                         "is-trunked": true,
-                        "network-id": "321",
+                        "network-id": "preload1",
                         "network-instance-group-id": "abc123",
                         "network-name": "syfy",
                         "network-role": "secret",
diff --git a/ms/generic-resource-api/src/test/resources/preload1-net-preload-data.json b/ms/generic-resource-api/src/test/resources/preload1-net-preload-data.json
new file mode 100644 (file)
index 0000000..74da3de
--- /dev/null
@@ -0,0 +1,78 @@
+{
+
+    "preload-network-topology-information": {
+      "host-routes": [
+        {
+          "next-hop": "10.1.12.1",
+          "route-prefix": "12"
+        }
+      ],
+      "is-external-network": false,
+      "is-provider-network": false,
+      "is-shared-network": false,
+      "network-policy": [
+        {
+          "network-policy-fqdn": "policy-sdnc.onap.org",
+          "network-policy-id": "123"
+        }
+      ],
+      "network-topology-identifier-structure": {
+        "eipam-v4-address-plan": "plan9",
+        "eipam-v6-address-plan": "plan9v6",
+        "is-trunked": true,
+        "network-id": "preload1",
+        "network-instance-group-id": "abc123",
+        "network-name": "syfy",
+        "network-role": "secret",
+        "network-technology": "soupcan",
+        "network-type": "fake",
+        "related-networks": {
+          "related-network": [
+            {
+              "network-id": "skynet",
+              "network-role": "master",
+              "vlan-tags": {
+                "is-private": true,
+                "lower-tag-id": 0,
+                "upper-tag-id": 0,
+                "vlan-interface": "le0"
+              }
+            }
+          ]
+        },
+        "segmentation-id": "seg1"
+      },
+      "physical-network-name": "skynet",
+      "route-table-reference": [
+        {
+          "route-table-reference-fqdn": "sky.net",
+          "route-table-reference-id": "ref1"
+        }
+      ],
+      "subnets": [
+        {
+          "addr-from-start": "Y",
+          "cidr-mask": "255.255.0.0",
+          "dhcp-enabled": "Y",
+          "dhcp-end-address": "10.1.2.254",
+          "dhcp-start-address": "10.1.2.1",
+          "gateway-address": "10.1.2.255",
+          "ip-version": "ipv4",
+          "start-address": "10.1.2.1",
+          "subnet-name": "subnet1",
+          "subnet-role": "puppies",
+          "subnet-sequence": 0
+        }
+      ],
+      "vpn-bindings": [
+        {
+          "aic-zone": "zone1",
+          "global-route-target": "string",
+          "route-target-role": "string",
+          "vpn-binding-id": "string",
+          "vpn-name": "string"
+        }
+      ]
+    }
+}
+
@@ -20,7 +20,7 @@
                 "eipam-v4-address-plan": "plan9",
                 "eipam-v6-address-plan": "plan9v6",
                 "is-trunked": true,
-                "network-id": "321",
+                "network-id": "preload1",
                 "network-instance-group-id": "abc123",
                 "network-name": "syfy",
                 "network-role": "secret",
         "nf-function": "function1",
         "nf-role": "role1",
         "nf-type": "type1",
-        "vnf-id": "123",
+        "vnf-id": "preload1",
         "vnf-name": "vnf1",
         "vnf-type": "vnftype1"
       }
diff --git a/ms/generic-resource-api/src/test/resources/preload2-net-list-item.json b/ms/generic-resource-api/src/test/resources/preload2-net-list-item.json
new file mode 100644 (file)
index 0000000..65a7bc4
--- /dev/null
@@ -0,0 +1,81 @@
+{
+  "preload-id": "preload2",
+  "preload-type": "network",
+  "preload-data": {
+    "preload-network-topology-information": {
+      "host-routes": [
+        {
+          "next-hop": "10.1.12.1",
+          "route-prefix": "12"
+        }
+      ],
+      "is-external-network": true,
+      "is-provider-network": true,
+      "is-shared-network": true,
+      "network-policy": [
+        {
+          "network-policy-fqdn": "policy-sdnc.onap.org",
+          "network-policy-id": "123"
+        }
+      ],
+      "network-topology-identifier-structure": {
+        "eipam-v4-address-plan": "plan9",
+        "eipam-v6-address-plan": "plan9v6",
+        "is-trunked": true,
+        "network-id": "preload2",
+        "network-instance-group-id": "abc123",
+        "network-name": "syfy",
+        "network-role": "secret",
+        "network-technology": "soupcan",
+        "network-type": "fake",
+        "related-networks": {
+          "related-network": [
+            {
+              "network-id": "skynet",
+              "network-role": "master",
+              "vlan-tags": {
+                "is-private": true,
+                "lower-tag-id": 0,
+                "upper-tag-id": 0,
+                "vlan-interface": "le0"
+              }
+            }
+          ]
+        },
+        "segmentation-id": "seg1"
+      },
+      "physical-network-name": "skynet",
+      "route-table-reference": [
+        {
+          "route-table-reference-fqdn": "sky.net",
+          "route-table-reference-id": "ref1"
+        }
+      ],
+      "subnets": [
+        {
+          "addr-from-start": "Y",
+          "cidr-mask": "255.255.0.0",
+          "dhcp-enabled": "Y",
+          "dhcp-end-address": "10.1.2.254",
+          "dhcp-start-address": "10.1.2.1",
+          "gateway-address": "10.1.2.255",
+          "ip-version": "ipv4",
+          "start-address": "10.1.2.1",
+          "subnet-name": "subnet1",
+          "subnet-role": "puppies",
+          "subnet-sequence": 0
+        }
+      ],
+      "vpn-bindings": [
+        {
+          "aic-zone": "zone1",
+          "global-route-target": "string",
+          "route-target-role": "string",
+          "vpn-binding-id": "string",
+          "vpn-name": "string"
+        }
+      ]
+    }
+  }
+}
+
diff --git a/ms/generic-resource-api/src/test/resources/preload2-net-model-info.json b/ms/generic-resource-api/src/test/resources/preload2-net-model-info.json
new file mode 100644 (file)
index 0000000..2b7b12e
--- /dev/null
@@ -0,0 +1,84 @@
+{
+    "preload-list": [
+        {
+            "preload-id": "preload2",
+            "preload-type": "network",
+            "preload-data": {
+                "preload-network-topology-information": {
+                    "host-routes": [
+                        {
+                            "next-hop": "10.1.12.1",
+                            "route-prefix": "12"
+                        }
+                    ],
+                    "is-external-network": true,
+                    "is-provider-network": true,
+                    "is-shared-network": true,
+                    "network-policy": [
+                        {
+                            "network-policy-fqdn": "policy-sdnc.onap.org",
+                            "network-policy-id": "123"
+                        }
+                    ],
+                    "network-topology-identifier-structure": {
+                        "eipam-v4-address-plan": "plan9",
+                        "eipam-v6-address-plan": "plan9v6",
+                        "is-trunked": true,
+                        "network-id": "preload2",
+                        "network-instance-group-id": "abc123",
+                        "network-name": "syfy",
+                        "network-role": "secret",
+                        "network-technology": "soupcan",
+                        "network-type": "fake",
+                        "related-networks": {
+                            "related-network": [
+                                {
+                                    "network-id": "skynet",
+                                    "network-role": "master",
+                                    "vlan-tags": {
+                                        "is-private": true,
+                                        "lower-tag-id": 0,
+                                        "upper-tag-id": 0,
+                                        "vlan-interface": "le0"
+                                    }
+                                }
+                            ]
+                        },
+                        "segmentation-id": "seg1"
+                    },
+                    "physical-network-name": "skynet",
+                    "route-table-reference": [
+                        {
+                            "route-table-reference-fqdn": "sky.net",
+                            "route-table-reference-id": "ref1"
+                        }
+                    ],
+                    "subnets": [
+                        {
+                            "addr-from-start": "Y",
+                            "cidr-mask": "255.255.0.0",
+                            "dhcp-enabled": "Y",
+                            "dhcp-end-address": "10.1.2.254",
+                            "dhcp-start-address": "10.1.2.1",
+                            "gateway-address": "10.1.2.255",
+                            "ip-version": "ipv4",
+                            "start-address": "10.1.2.1",
+                            "subnet-name": "subnet1",
+                            "subnet-role": "puppies",
+                            "subnet-sequence": 0
+                        }
+                    ],
+                    "vpn-bindings": [
+                        {
+                            "aic-zone": "zone1",
+                            "global-route-target": "string",
+                            "route-target-role": "string",
+                            "vpn-binding-id": "string",
+                            "vpn-name": "string"
+                        }
+                    ]
+                }
+            }
+        }
+    ]
+}
diff --git a/ms/generic-resource-api/src/test/resources/service1-servicedata.json b/ms/generic-resource-api/src/test/resources/service1-servicedata.json
new file mode 100644 (file)
index 0000000..6fe0ef7
--- /dev/null
@@ -0,0 +1,221 @@
+{
+  "request-information": {
+    "request-id": "f5554477-51c7-4f8e-9183-f8968f3f86bf",
+    "request-action": "CreateServiceInstance",
+    "source": "MSO"
+  },
+  "service-request-input": {
+    "service-instance-name": "NGINX-INGRESS-1"
+  },
+  "service-information": {
+    "service-id": "service1",
+    "onap-model-information": {
+      "model-name": "service-nginx-ingress-1",
+      "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+      "model-version": "1.0",
+      "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+    },
+    "service-instance-id": "service1",
+    "global-customer-id": "Demonstration",
+    "subscription-service-type": "service-nginx-ingress-1"
+  },
+  "service-topology": {
+    "service-topology-identifier": {
+      "service-instance-id": "service1",
+      "service-instance-name": "NGINX-INGRESS-1",
+      "service-type": "service-nginx-ingress-1",
+      "global-customer-id": "Demonstration"
+    },
+    "onap-model-information": {
+      "model-name": "service-nginx-ingress-1",
+      "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+      "model-version": "1.0",
+      "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+    }
+  },
+  "service-level-oper-status": {
+    "order-status": "Created",
+    "last-rpc-action": "assign",
+    "last-action": "CreateServiceInstance"
+  },
+  "sdnc-request-header": {
+    "svc-action": "assign",
+    "svc-request-id": "6d06a832-69da-4369-9d99-049767a39400"
+  },
+  "vnfs": {
+    "vnf": [
+      {
+        "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+        "vnf-data": {
+          "vnf-level-oper-status": {
+            "order-status": "Created",
+            "last-rpc-action": "activate",
+            "last-action": "CreateVnfInstance"
+          },
+          "service-information": {
+            "service-id": "service1",
+            "onap-model-information": {
+              "model-name": "service-nginx-ingress-1",
+              "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+              "model-version": "1.0",
+              "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+            },
+            "service-instance-id": "service1",
+            "global-customer-id": "Demonstration",
+            "subscription-service-type": "service-nginx-ingress-1"
+          },
+          "sdnc-request-header": {
+            "svc-action": "activate",
+            "svc-request-id": "acf0c0db-106f-42e4-b77b-191e9d229eb9",
+            "svc-notification-url": "http://so-bpmn-infra.onap:8081/mso/WorkflowMessage/SDNCCallback/b8f92243-85cb-4954-970d-7e0159b9a48b"
+          },
+          "vnf-information": {
+            "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+            "onap-model-information": {
+              "model-name": "nginx-ingress-1",
+              "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+              "model-version": "1.0",
+              "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+              "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+            },
+            "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+            "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+          },
+          "request-information": {
+            "request-id": "c382d6d1-2108-4c39-ab7a-c3e67cdbc749",
+            "request-action": "CreateVnfInstance",
+            "source": "MSO"
+          },
+          "vnf-request-input": {
+            "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2",
+            "tenant": "k8s_tenant_1",
+            "cloud-owner": "k8sCloudOwner",
+            "aic-cloud-region": "k8s_region_1"
+          },
+          "vnf-topology": {
+            "onap-model-information": {
+              "model-name": "nginx-ingress-1",
+              "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+              "model-version": "1.0",
+              "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+              "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+            },
+            "tenant": "k8s_tenant_1",
+            "aic-clli": "complexMC",
+            "aic-cloud-region": "k8s_region_1",
+            "vnf-topology-identifier-structure": {
+              "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+              "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+              "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+            },
+            "vnf-resource-assignments": {
+              "availability-zones": {
+                "availability-zone": [
+                  "k8s_availability_zone_1"
+                ]
+              }
+            }
+          },
+          "vf-modules": {
+            "vf-module": [
+              {
+                "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                "vf-module-data": {
+                  "service-information": {
+                    "service-id": "service1",
+                    "onap-model-information": {
+                      "model-name": "service-nginx-ingress-1",
+                      "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+                      "model-version": "1.0",
+                      "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+                    },
+                    "service-instance-id": "service1",
+                    "global-customer-id": "Demonstration",
+                    "subscription-service-type": "service-nginx-ingress-1"
+                  },
+                  "vf-module-topology": {
+                    "onap-model-information": {
+                      "model-name": "NginxIngress1..nginx-ingress..module-0",
+                      "model-invariant-uuid": "caa22b8e-e0de-4d2c-9048-9a71d39afd91",
+                      "model-version": "1",
+                      "model-customization-uuid": "d6403fe2-ebe4-4fce-bec2-0218f61b2564",
+                      "model-uuid": "e5d2fe74-9534-4a7c-9a1b-f49ecf1105e3"
+                    },
+                    "vf-module-parameters": {
+                      "param": [
+                        {
+                          "name": "availability_zone_0",
+                          "value": "k8s_availability_zone_1"
+                        },
+                        {
+                          "name": "k8s-rb-profile-name",
+                          "value": "default"
+                        }
+                      ]
+                    },
+                    "tenant": "k8s_tenant_1",
+                    "sdnc-generated-cloud-resources": true,
+                    "aic-clli": "complexMC",
+                    "vf-module-topology-identifier": {
+                      "vf-module-type": "NginxIngress1..nginx-ingress..module-0",
+                      "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                      "vf-module-name": "Python_ONAP_SDK_vf_module_instance_678cc889-0c89-40f3-9f5b-1f475d5c4ebb"
+                    },
+                    "aic-cloud-region": "k8s_region_1"
+                  },
+                  "vf-module-request-input": {
+                    "vf-module-name": "Python_ONAP_SDK_vf_module_instance_678cc889-0c89-40f3-9f5b-1f475d5c4ebb",
+                    "tenant": "k8s_tenant_1",
+                    "cloud-owner": "k8sCloudOwner",
+                    "aic-cloud-region": "k8s_region_1"
+                  },
+                  "sdnc-request-header": {
+                    "svc-action": "activate",
+                    "svc-request-id": "bf81d48a-d5f9-42f2-bc49-9277f0e2a836",
+                    "svc-notification-url": "http://so-bpmn-infra.onap:8081/mso/WorkflowMessage/SDNCCallback/64780567-ecf5-41c9-af36-bb06f8ae0e5d"
+                  },
+                  "vnf-information": {
+                    "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+                    "onap-model-information": {
+                      "model-name": "nginx-ingress-1",
+                      "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+                      "model-version": "1.0",
+                      "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+                      "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+                    },
+                    "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+                    "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+                  },
+                  "vf-module-information": {
+                    "onap-model-information": {
+                      "model-name": "NginxIngress1..nginx-ingress..module-0",
+                      "model-invariant-uuid": "caa22b8e-e0de-4d2c-9048-9a71d39afd91",
+                      "model-version": "1",
+                      "model-customization-uuid": "d6403fe2-ebe4-4fce-bec2-0218f61b2564",
+                      "model-uuid": "e5d2fe74-9534-4a7c-9a1b-f49ecf1105e3"
+                    },
+                    "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                    "vf-module-type": "NginxIngress1..nginx-ingress..module-0",
+                    "from-preload": true
+                  },
+                  "request-information": {
+                    "request-id": "051f3665-002c-4e3c-b62e-f8c0b48ef12e",
+                    "request-action": "CreateVfModuleInstance",
+                    "source": "MSO"
+                  },
+                  "vf-module-level-oper-status": {
+                    "order-status": "Created",
+                    "last-rpc-action": "activate"
+                  }
+                }
+              }
+            ]
+          }
+        }
+      }
+    ]
+  }
+}
+
+
+
diff --git a/ms/generic-resource-api/src/test/resources/service1-serviceitem.json b/ms/generic-resource-api/src/test/resources/service1-serviceitem.json
new file mode 100644 (file)
index 0000000..c950377
--- /dev/null
@@ -0,0 +1,233 @@
+{
+  "service-instance-id": "service1",
+  "service-data": {
+    "request-information": {
+      "request-id": "f5554477-51c7-4f8e-9183-f8968f3f86bf",
+      "request-action": "CreateServiceInstance",
+      "source": "MSO"
+    },
+    "service-request-input": {
+      "service-instance-name": "NGINX-INGRESS-1"
+    },
+    "service-information": {
+      "service-id": "service1",
+      "onap-model-information": {
+        "model-name": "service-nginx-ingress-1",
+        "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+        "model-version": "1.0",
+        "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+      },
+      "service-instance-id": "service1",
+      "global-customer-id": "Demonstration",
+      "subscription-service-type": "service-nginx-ingress-1"
+    },
+    "service-topology": {
+      "service-topology-identifier": {
+        "service-instance-id": "service1",
+        "service-instance-name": "NGINX-INGRESS-1",
+        "service-type": "service-nginx-ingress-1",
+        "global-customer-id": "Demonstration"
+      },
+      "onap-model-information": {
+        "model-name": "service-nginx-ingress-1",
+        "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+        "model-version": "1.0",
+        "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+      }
+    },
+    "service-level-oper-status": {
+      "order-status": "Created",
+      "last-rpc-action": "assign",
+      "last-action": "CreateServiceInstance"
+    },
+    "sdnc-request-header": {
+      "svc-action": "assign",
+      "svc-request-id": "6d06a832-69da-4369-9d99-049767a39400"
+    },
+    "vnfs": {
+      "vnf": [
+        {
+          "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+          "vnf-data": {
+            "vnf-level-oper-status": {
+              "order-status": "Created",
+              "last-rpc-action": "activate",
+              "last-action": "CreateVnfInstance"
+            },
+            "service-information": {
+              "service-id": "service1",
+              "onap-model-information": {
+                "model-name": "service-nginx-ingress-1",
+                "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+                "model-version": "1.0",
+                "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+              },
+              "service-instance-id": "service1",
+              "global-customer-id": "Demonstration",
+              "subscription-service-type": "service-nginx-ingress-1"
+            },
+            "sdnc-request-header": {
+              "svc-action": "activate",
+              "svc-request-id": "acf0c0db-106f-42e4-b77b-191e9d229eb9",
+              "svc-notification-url": "http://so-bpmn-infra.onap:8081/mso/WorkflowMessage/SDNCCallback/b8f92243-85cb-4954-970d-7e0159b9a48b"
+            },
+            "vnf-information": {
+              "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+              "onap-model-information": {
+                "model-name": "nginx-ingress-1",
+                "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+                "model-version": "1.0",
+                "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+                "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+              },
+              "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+              "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+            },
+            "request-information": {
+              "request-id": "c382d6d1-2108-4c39-ab7a-c3e67cdbc749",
+              "request-action": "CreateVnfInstance",
+              "source": "MSO"
+            },
+            "vnf-request-input": {
+              "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2",
+              "tenant": "k8s_tenant_1",
+              "cloud-owner": "k8sCloudOwner",
+              "aic-cloud-region": "k8s_region_1"
+            },
+            "vnf-topology": {
+              "onap-model-information": {
+                "model-name": "nginx-ingress-1",
+                "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+                "model-version": "1.0",
+                "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+                "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+              },
+              "tenant": "k8s_tenant_1",
+              "aic-clli": "complexMC",
+              "aic-cloud-region": "k8s_region_1",
+              "vnf-topology-identifier-structure": {
+                "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+                "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+                "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+              },
+              "vnf-resource-assignments": {
+                "availability-zones": {
+                  "availability-zone": [
+                    "k8s_availability_zone_1"
+                  ]
+                }
+              }
+            },
+            "vf-modules": {
+              "vf-module": [
+                {
+                  "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                  "vf-module-data": {
+                    "service-information": {
+                      "service-id": "service1",
+                      "onap-model-information": {
+                        "model-name": "service-nginx-ingress-1",
+                        "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+                        "model-version": "1.0",
+                        "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+                      },
+                      "service-instance-id": "service1",
+                      "global-customer-id": "Demonstration",
+                      "subscription-service-type": "service-nginx-ingress-1"
+                    },
+                    "vf-module-topology": {
+                      "onap-model-information": {
+                        "model-name": "NginxIngress1..nginx-ingress..module-0",
+                        "model-invariant-uuid": "caa22b8e-e0de-4d2c-9048-9a71d39afd91",
+                        "model-version": "1",
+                        "model-customization-uuid": "d6403fe2-ebe4-4fce-bec2-0218f61b2564",
+                        "model-uuid": "e5d2fe74-9534-4a7c-9a1b-f49ecf1105e3"
+                      },
+                      "vf-module-parameters": {
+                        "param": [
+                          {
+                            "name": "availability_zone_0",
+                            "value": "k8s_availability_zone_1"
+                          },
+                          {
+                            "name": "k8s-rb-profile-name",
+                            "value": "default"
+                          }
+                        ]
+                      },
+                      "tenant": "k8s_tenant_1",
+                      "sdnc-generated-cloud-resources": true,
+                      "aic-clli": "complexMC",
+                      "vf-module-topology-identifier": {
+                        "vf-module-type": "NginxIngress1..nginx-ingress..module-0",
+                        "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                        "vf-module-name": "Python_ONAP_SDK_vf_module_instance_678cc889-0c89-40f3-9f5b-1f475d5c4ebb"
+                      },
+                      "aic-cloud-region": "k8s_region_1"
+                    },
+                    "vf-module-request-input": {
+                      "vf-module-name": "Python_ONAP_SDK_vf_module_instance_678cc889-0c89-40f3-9f5b-1f475d5c4ebb",
+                      "tenant": "k8s_tenant_1",
+                      "cloud-owner": "k8sCloudOwner",
+                      "aic-cloud-region": "k8s_region_1"
+                    },
+                    "sdnc-request-header": {
+                      "svc-action": "activate",
+                      "svc-request-id": "bf81d48a-d5f9-42f2-bc49-9277f0e2a836",
+                      "svc-notification-url": "http://so-bpmn-infra.onap:8081/mso/WorkflowMessage/SDNCCallback/64780567-ecf5-41c9-af36-bb06f8ae0e5d"
+                    },
+                    "vnf-information": {
+                      "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+                      "onap-model-information": {
+                        "model-name": "nginx-ingress-1",
+                        "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+                        "model-version": "1.0",
+                        "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+                        "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+                      },
+                      "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+                      "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+                    },
+                    "vf-module-information": {
+                      "onap-model-information": {
+                        "model-name": "NginxIngress1..nginx-ingress..module-0",
+                        "model-invariant-uuid": "caa22b8e-e0de-4d2c-9048-9a71d39afd91",
+                        "model-version": "1",
+                        "model-customization-uuid": "d6403fe2-ebe4-4fce-bec2-0218f61b2564",
+                        "model-uuid": "e5d2fe74-9534-4a7c-9a1b-f49ecf1105e3"
+                      },
+                      "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                      "vf-module-type": "NginxIngress1..nginx-ingress..module-0",
+                      "from-preload": true
+                    },
+                    "request-information": {
+                      "request-id": "051f3665-002c-4e3c-b62e-f8c0b48ef12e",
+                      "request-action": "CreateVfModuleInstance",
+                      "source": "MSO"
+                    },
+                    "vf-module-level-oper-status": {
+                      "order-status": "Created",
+                      "last-rpc-action": "activate"
+                    }
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ]
+    }
+  },
+  "service-status": {
+    "final-indicator": "Y",
+    "rpc-action": "activate",
+    "rpc-name": "vf-module-topology-operation",
+    "response-code": "200",
+    "response-timestamp": "2020-06-24T13:06:24.525Z",
+    "response-message": "",
+    "action": "CreateVfModuleInstance",
+    "request-status": "synccomplete"
+  }
+}
+
+
diff --git a/ms/generic-resource-api/src/test/resources/service1-servicestatus.json b/ms/generic-resource-api/src/test/resources/service1-servicestatus.json
new file mode 100644 (file)
index 0000000..ca763d3
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "final-indicator": "Y",
+  "rpc-action": "activate",
+  "rpc-name": "vf-module-topology-operation",
+  "response-code": "200",
+  "response-timestamp": "2020-06-24T13:06:24.525Z",
+  "response-message": "",
+  "action": "CreateVfModuleInstance",
+  "request-status": "synccomplete"
+}
\ No newline at end of file
diff --git a/ms/generic-resource-api/src/test/resources/service1.json b/ms/generic-resource-api/src/test/resources/service1.json
new file mode 100644 (file)
index 0000000..f280ae6
--- /dev/null
@@ -0,0 +1,236 @@
+{
+  "service": [
+    {
+      "service-instance-id": "service1",
+      "service-data": {
+        "request-information": {
+          "request-id": "f5554477-51c7-4f8e-9183-f8968f3f86bf",
+          "request-action": "CreateServiceInstance",
+          "source": "MSO"
+        },
+        "service-request-input": {
+          "service-instance-name": "NGINX-INGRESS-1"
+        },
+        "service-information": {
+          "service-id": "service1",
+          "onap-model-information": {
+            "model-name": "service-nginx-ingress-1",
+            "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+            "model-version": "1.0",
+            "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+          },
+          "service-instance-id": "service1",
+          "global-customer-id": "Demonstration",
+          "subscription-service-type": "service-nginx-ingress-1"
+        },
+        "service-topology": {
+          "service-topology-identifier": {
+            "service-instance-id": "service1",
+            "service-instance-name": "NGINX-INGRESS-1",
+            "service-type": "service-nginx-ingress-1",
+            "global-customer-id": "Demonstration"
+          },
+          "onap-model-information": {
+            "model-name": "service-nginx-ingress-1",
+            "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+            "model-version": "1.0",
+            "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+          }
+        },
+        "service-level-oper-status": {
+          "order-status": "Created",
+          "last-rpc-action": "assign",
+          "last-action": "CreateServiceInstance"
+        },
+        "sdnc-request-header": {
+          "svc-action": "assign",
+          "svc-request-id": "6d06a832-69da-4369-9d99-049767a39400"
+        },
+        "vnfs": {
+          "vnf": [
+            {
+              "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+              "vnf-data": {
+                "vnf-level-oper-status": {
+                  "order-status": "Created",
+                  "last-rpc-action": "activate",
+                  "last-action": "CreateVnfInstance"
+                },
+                "service-information": {
+                  "service-id": "service1",
+                  "onap-model-information": {
+                    "model-name": "service-nginx-ingress-1",
+                    "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+                    "model-version": "1.0",
+                    "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+                  },
+                  "service-instance-id": "service1",
+                  "global-customer-id": "Demonstration",
+                  "subscription-service-type": "service-nginx-ingress-1"
+                },
+                "sdnc-request-header": {
+                  "svc-action": "activate",
+                  "svc-request-id": "acf0c0db-106f-42e4-b77b-191e9d229eb9",
+                  "svc-notification-url": "http://so-bpmn-infra.onap:8081/mso/WorkflowMessage/SDNCCallback/b8f92243-85cb-4954-970d-7e0159b9a48b"
+                },
+                "vnf-information": {
+                  "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+                  "onap-model-information": {
+                    "model-name": "nginx-ingress-1",
+                    "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+                    "model-version": "1.0",
+                    "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+                    "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+                  },
+                  "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+                  "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+                },
+                "request-information": {
+                  "request-id": "c382d6d1-2108-4c39-ab7a-c3e67cdbc749",
+                  "request-action": "CreateVnfInstance",
+                  "source": "MSO"
+                },
+                "vnf-request-input": {
+                  "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2",
+                  "tenant": "k8s_tenant_1",
+                  "cloud-owner": "k8sCloudOwner",
+                  "aic-cloud-region": "k8s_region_1"
+                },
+                "vnf-topology": {
+                  "onap-model-information": {
+                    "model-name": "nginx-ingress-1",
+                    "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+                    "model-version": "1.0",
+                    "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+                    "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+                  },
+                  "tenant": "k8s_tenant_1",
+                  "aic-clli": "complexMC",
+                  "aic-cloud-region": "k8s_region_1",
+                  "vnf-topology-identifier-structure": {
+                    "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+                    "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+                    "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+                  },
+                  "vnf-resource-assignments": {
+                    "availability-zones": {
+                      "availability-zone": [
+                        "k8s_availability_zone_1"
+                      ]
+                    }
+                  }
+                },
+                "vf-modules": {
+                  "vf-module": [
+                    {
+                      "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                      "vf-module-data": {
+                        "service-information": {
+                          "service-id": "service1",
+                          "onap-model-information": {
+                            "model-name": "service-nginx-ingress-1",
+                            "model-invariant-uuid": "0fe6193d-2d65-4b8e-a4ee-a07821566b5e",
+                            "model-version": "1.0",
+                            "model-uuid": "48223a6a-f5e1-4354-95eb-f5ea014fc9df"
+                          },
+                          "service-instance-id": "service1",
+                          "global-customer-id": "Demonstration",
+                          "subscription-service-type": "service-nginx-ingress-1"
+                        },
+                        "vf-module-topology": {
+                          "onap-model-information": {
+                            "model-name": "NginxIngress1..nginx-ingress..module-0",
+                            "model-invariant-uuid": "caa22b8e-e0de-4d2c-9048-9a71d39afd91",
+                            "model-version": "1",
+                            "model-customization-uuid": "d6403fe2-ebe4-4fce-bec2-0218f61b2564",
+                            "model-uuid": "e5d2fe74-9534-4a7c-9a1b-f49ecf1105e3"
+                          },
+                          "vf-module-parameters": {
+                            "param": [
+                              {
+                                "name": "availability_zone_0",
+                                "value": "k8s_availability_zone_1"
+                              },
+                              {
+                                "name": "k8s-rb-profile-name",
+                                "value": "default"
+                              }
+                            ]
+                          },
+                          "tenant": "k8s_tenant_1",
+                          "sdnc-generated-cloud-resources": true,
+                          "aic-clli": "complexMC",
+                          "vf-module-topology-identifier": {
+                            "vf-module-type": "NginxIngress1..nginx-ingress..module-0",
+                            "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                            "vf-module-name": "Python_ONAP_SDK_vf_module_instance_678cc889-0c89-40f3-9f5b-1f475d5c4ebb"
+                          },
+                          "aic-cloud-region": "k8s_region_1"
+                        },
+                        "vf-module-request-input": {
+                          "vf-module-name": "Python_ONAP_SDK_vf_module_instance_678cc889-0c89-40f3-9f5b-1f475d5c4ebb",
+                          "tenant": "k8s_tenant_1",
+                          "cloud-owner": "k8sCloudOwner",
+                          "aic-cloud-region": "k8s_region_1"
+                        },
+                        "sdnc-request-header": {
+                          "svc-action": "activate",
+                          "svc-request-id": "bf81d48a-d5f9-42f2-bc49-9277f0e2a836",
+                          "svc-notification-url": "http://so-bpmn-infra.onap:8081/mso/WorkflowMessage/SDNCCallback/64780567-ecf5-41c9-af36-bb06f8ae0e5d"
+                        },
+                        "vnf-information": {
+                          "vnf-id": "fae319cc-68d6-496f-be1e-a09e133c71d4",
+                          "onap-model-information": {
+                            "model-name": "nginx-ingress-1",
+                            "model-invariant-uuid": "ebd1565b-a98f-4d77-9b91-6aefd51d040c",
+                            "model-version": "1.0",
+                            "model-customization-uuid": "69cff101-d1f2-4bf3-9697-57f52ba3c5dd",
+                            "model-uuid": "dfeccc32-2459-43bf-bfdd-36567e696090"
+                          },
+                          "vnf-type": "service-nginx-ingress-1/nginx-ingress-1 0",
+                          "vnf-name": "Python_ONAP_SDK_vnf_instance_2aff902a-4714-4d08-942d-d97b3a3b87c2"
+                        },
+                        "vf-module-information": {
+                          "onap-model-information": {
+                            "model-name": "NginxIngress1..nginx-ingress..module-0",
+                            "model-invariant-uuid": "caa22b8e-e0de-4d2c-9048-9a71d39afd91",
+                            "model-version": "1",
+                            "model-customization-uuid": "d6403fe2-ebe4-4fce-bec2-0218f61b2564",
+                            "model-uuid": "e5d2fe74-9534-4a7c-9a1b-f49ecf1105e3"
+                          },
+                          "vf-module-id": "269bda16-f40c-41a9-baef-e8905ab2b70e",
+                          "vf-module-type": "NginxIngress1..nginx-ingress..module-0",
+                          "from-preload": true
+                        },
+                        "request-information": {
+                          "request-id": "051f3665-002c-4e3c-b62e-f8c0b48ef12e",
+                          "request-action": "CreateVfModuleInstance",
+                          "source": "MSO"
+                        },
+                        "vf-module-level-oper-status": {
+                          "order-status": "Created",
+                          "last-rpc-action": "activate"
+                        }
+                      }
+                    }
+                  ]
+                }
+              }
+            }
+          ]
+        }
+      },
+      "service-status": {
+        "final-indicator": "Y",
+        "rpc-action": "activate",
+        "rpc-name": "vf-module-topology-operation",
+        "response-code": "200",
+        "response-timestamp": "2020-06-24T13:06:24.525Z",
+        "response-message": "",
+        "action": "CreateVfModuleInstance",
+        "request-status": "synccomplete"
+      }
+    }
+  ]
+}
+
diff --git a/ms/generic-resource-api/src/test/resources/svclogic.properties b/ms/generic-resource-api/src/test/resources/svclogic.properties
new file mode 100644 (file)
index 0000000..b57c43d
--- /dev/null
@@ -0,0 +1,29 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                                              reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+org.onap.ccsdk.sli.dbtype = jdbc
+org.onap.ccsdk.sli.jdbc.url=jdbc:derby:memory:sdnctl;create=true
+org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
+org.onap.ccsdk.sli.jdbc.database = sdnctl
+org.onap.ccsdk.sli.jdbc.user = sdnc
+org.onap.ccsdk.sli.jdbc.password = abc123
+
+serviceLogicDirectory=src/test/resources