Merge "Rework authorization controller "
authorSébastien Determe <sebastien.determe@intl.att.com>
Tue, 12 Mar 2019 15:38:23 +0000 (15:38 +0000)
committerGerrit Code Review <gerrit@onap.org>
Tue, 12 Mar 2019 15:38:23 +0000 (15:38 +0000)
42 files changed:
extra/sql/bulkload/create-tables.sql [new file with mode: 0644]
pom.xml
src/main/java/org/onap/clamp/clds/client/DcaeHttpConnectionManager.java
src/main/java/org/onap/clamp/clds/config/CldsUserJsonDecoder.java
src/main/java/org/onap/clamp/clds/config/spring/CldsSdcControllerConfiguration.java
src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java
src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java
src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstallerImpl.java
src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java
src/main/java/org/onap/clamp/clds/transform/XslTransformer.java
src/main/java/org/onap/clamp/clds/util/XmlTools.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/util/drawing/AwtUtils.java [new file with mode: 0755]
src/main/java/org/onap/clamp/clds/util/drawing/ClampGraph.java [new file with mode: 0755]
src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java [new file with mode: 0755]
src/main/java/org/onap/clamp/clds/util/drawing/DocumentBuilder.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/util/drawing/ImageBuilder.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/util/drawing/InvalidStateException.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/util/drawing/Painter.java [new file with mode: 0755]
src/main/java/org/onap/clamp/clds/util/drawing/RectTypes.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/util/drawing/SvgFacade.java [new file with mode: 0644]
src/main/java/org/onap/clamp/loop/CsarInstallerImpl.java [new file with mode: 0644]
src/main/java/org/onap/clamp/loop/Loop.java
src/main/java/org/onap/clamp/loop/LoopController.java
src/main/java/org/onap/clamp/loop/LoopService.java
src/main/java/org/onap/clamp/policy/Policy.java
src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java
src/main/resources/clds/camel/rest/clamp-api-v2.xml
src/test/java/org/onap/clamp/clds/it/config/SdcControllersConfigurationItCase.java
src/test/java/org/onap/clamp/clds/it/sdc/controller/SdcSingleControllerItCase.java
src/test/java/org/onap/clamp/clds/it/sdc/controller/installer/CsarInstallerItCase.java
src/test/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandlerTest.java
src/test/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstallerImplTest.java
src/test/java/org/onap/clamp/clds/util/XmlToolsTest.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphTest.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/util/drawing/DocumentBuilderTest.java [new file with mode: 0644]
src/test/java/org/onap/clamp/loop/CsarInstallerItCase.java [new file with mode: 0644]
src/test/java/org/onap/clamp/loop/LoopServiceTestItCase.java
src/test/resources/application.properties
src/test/resources/clds/util/file.xml [new file with mode: 0644]
src/test/resources/example/sdc/service-Simsfoimap0112.csar

diff --git a/extra/sql/bulkload/create-tables.sql b/extra/sql/bulkload/create-tables.sql
new file mode 100644 (file)
index 0000000..93c80cb
--- /dev/null
@@ -0,0 +1,70 @@
+
+    create table hibernate_sequence (
+       next_val bigint
+    ) engine=InnoDB;
+
+    insert into hibernate_sequence values ( 1 );
+
+    create table loop_logs (
+       id bigint not null,
+        log_instant datetime(6) not null,
+        log_type varchar(255) not null,
+        message varchar(255) not null,
+        loop_id varchar(255) not null,
+        primary key (id)
+    ) engine=InnoDB;
+
+    create table loops (
+       name varchar(255) not null,
+        blueprint_yaml MEDIUMTEXT not null,
+        dcae_blueprint_id varchar(255),
+        dcae_deployment_id varchar(255),
+        dcae_deployment_status_url varchar(255),
+        global_properties_json json,
+        last_computed_state varchar(255) not null,
+        model_properties_json json,
+        svg_representation varchar(255),
+        primary key (name)
+    ) engine=InnoDB;
+
+    create table loops_microservicepolicies (
+       loop_id varchar(255) not null,
+        microservicepolicy_id varchar(255) not null,
+        primary key (loop_id, microservicepolicy_id)
+    ) engine=InnoDB;
+
+    create table micro_service_policies (
+       name varchar(255) not null,
+        json_representation json not null,
+        policy_tosca MEDIUMTEXT not null,
+        properties json,
+        shared bit not null,
+        primary key (name)
+    ) engine=InnoDB;
+
+    create table operational_policies (
+       name varchar(255) not null,
+        configurations_json json,
+        loop_id varchar(255) not null,
+        primary key (name)
+    ) engine=InnoDB;
+
+    alter table loop_logs 
+       add constraint FK1j0cda46aickcaoxqoo34khg2 
+       foreign key (loop_id) 
+       references loops (name);
+
+    alter table loops_microservicepolicies 
+       add constraint FKem7tp1cdlpwe28av7ef91j1yl 
+       foreign key (microservicepolicy_id) 
+       references micro_service_policies (name);
+
+    alter table loops_microservicepolicies 
+       add constraint FKsvx91jekgdkfh34iaxtjfgebt 
+       foreign key (loop_id) 
+       references loops (name);
+
+    alter table operational_policies 
+       add constraint FK1ddoggk9ni2bnqighv6ecmuwu 
+       foreign key (loop_id) 
+       references loops (name);
diff --git a/pom.xml b/pom.xml
index bb59a88..b295262 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                </dependencyManagement>
 
                <dependencies>
+                       <dependency>
+                               <groupId>org.apache.xmlgraphics</groupId>
+                               <artifactId>batik-svggen</artifactId>
+                               <version>1.11</version>
+                       </dependency>
+                       <dependency>
+                               <groupId>org.apache.xmlgraphics</groupId>
+                               <artifactId>batik-svg-dom</artifactId>
+                               <version>1.11</version>
+                       </dependency>
+                       <dependency>
+                               <groupId>org.apache.xmlgraphics</groupId>
+                               <artifactId>batik-transcoder</artifactId>
+                               <version>1.11</version>
+                       </dependency>
                                <dependency>
                                                <groupId>com.att.eelf</groupId>
                                                <artifactId>eelf-core</artifactId>
index 059cc2b..8781fc3 100644 (file)
@@ -19,7 +19,7 @@
  * ============LICENSE_END============================================
  * Modifications copyright (c) 2018 Nokia
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.client;
@@ -42,20 +42,17 @@ import org.onap.clamp.clds.util.LoggingUtils;
 import org.springframework.stereotype.Component;
 
 /**
- * 
+ *
  * This class manages the HTTP and HTTPS connections to DCAE.
  *
  */
 @Component
 public class DcaeHttpConnectionManager {
-    protected static final EELFLogger logger                  = EELFManager.getInstance()
-            .getLogger(DcaeHttpConnectionManager.class);
-    protected static final EELFLogger metricsLogger           = EELFManager.getInstance().getMetricsLogger();
-    private static final String       DCAE_REQUEST_FAILED_LOG = "Request Failed - response payload=";
-
+    protected static final EELFLogger logger = EELFManager.getInstance().getLogger(DcaeHttpConnectionManager.class);
+    protected static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+    private static final String DCAE_REQUEST_FAILED_LOG = "Request Failed - response payload=";
 
-    private String doHttpsQuery(URL url, String requestMethod, String payload, String contentType)
-            throws IOException {
+    private String doHttpsQuery(URL url, String requestMethod, String payload, String contentType) throws IOException {
         logger.info("Using HTTPS URL to contact DCAE:" + url.toString());
         HttpsURLConnection secureConnection = (HttpsURLConnection) url.openConnection();
         secureConnection.setRequestMethod(requestMethod);
@@ -87,12 +84,11 @@ public class DcaeHttpConnectionManager {
         }
     }
 
-    private String doHttpQuery(URL url, String requestMethod, String payload, String contentType)
-            throws IOException {
-        LoggingUtils utils = new LoggingUtils (logger);
+    private String doHttpQuery(URL url, String requestMethod, String payload, String contentType) throws IOException {
+        LoggingUtils utils = new LoggingUtils(logger);
         logger.info("Using HTTP URL to contact DCAE:" + url);
         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-        connection = utils.invoke(connection,"DCAE", requestMethod);
+        connection = utils.invoke(connection, "DCAE", requestMethod);
         connection.setRequestMethod(requestMethod);
         connection.setRequestProperty("X-ECOMP-RequestID", LoggingUtils.getRequestId());
         if (payload != null && contentType != null) {
@@ -126,21 +122,21 @@ public class DcaeHttpConnectionManager {
 
     /**
      * This method does a HTTP/HTTPS query to DCAE with parameters specified.
-     * 
+     *
      * @param url
-     *            The string HTTP or HTTPS that mustr be used to connect
+     *        The string HTTP or HTTPS that mustr be used to connect
      * @param requestMethod
-     *            The Request Method (PUT, POST, GET, DELETE, etc ...)
+     *        The Request Method (PUT, POST, GET, DELETE, etc ...)
      * @param payload
-     *            The payload if any, in that case an ouputstream is opened
+     *        The payload if any, in that case an ouputstream is opened
      * @param contentType
-     *            The "application/json or application/xml, or whatever"
+     *        The "application/json or application/xml, or whatever"
      * @return The payload of the answer
      * @throws IOException
-     *             In case of issue with the streams
+     *         In case of issue with the streams
      */
     public String doDcaeHttpQuery(String url, String requestMethod, String payload, String contentType)
-            throws IOException {
+        throws IOException {
         URL urlObj = new URL(url);
         if (url.contains("https://")) { // Support for HTTPS
             return doHttpsQuery(urlObj, requestMethod, payload, contentType);
index d1beb95..8af1286 100644 (file)
@@ -5,32 +5,30 @@
  * Copyright (C) 2017-2018 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. 
+ * 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 
+ *
+ * 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============================================
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.config;
 
 import com.google.gson.JsonParseException;
-import com.google.gson.reflect.TypeToken;
+
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.reflect.Type;
 import java.nio.charset.StandardCharsets;
 
-import java.util.List;
 import org.apache.commons.io.IOUtils;
 import org.onap.clamp.clds.exception.CldsUsersException;
 import org.onap.clamp.clds.service.CldsUser;
@@ -39,13 +37,13 @@ import org.onap.clamp.clds.util.JsonUtils;
 public class CldsUserJsonDecoder {
 
     /**
-     * This method decodes the JSON file provided to a CldsUser Array. The
-     * stream is closed after this call, this is not possible to reuse it.
-     * 
+     * This method decodes the JSON file provided to a CldsUser Array. The stream is
+     * closed after this call, this is not possible to reuse it.
+     *
      * @param cldsUsersFile
-     *            The inputStream containing the users json file
-     * @return CldsUser[] Array containing a list of the user defined in the
-     *         JSON file
+     *        The inputStream containing the users json file
+     * @return CldsUser[] Array containing a list of the user defined in the JSON
+     *         file
      */
     public static CldsUser[] decodeJson(InputStream cldsUsersFile) {
         try {
index 1fb86c0..3f1403f 100644 (file)
@@ -17,6 +17,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * ============LICENSE_END============================================
+ *  * Modifications copyright (c) 2019 Nokia
  * ===================================================================
  *
  */
@@ -92,11 +93,6 @@ public class CldsSdcControllerConfiguration {
         });
     }
 
-    @Bean(name = "csarInstaller")
-    public CsarInstaller getCsarInstaller() {
-        return new CsarInstallerImpl();
-    }
-
     @Bean(name = "sdcControllersConfiguration")
     public SdcControllersConfiguration getSdcControllersConfiguration() {
         return new SdcControllersConfiguration();
diff --git a/src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java b/src/main/java/org/onap/clamp/clds/config/spring/SdcControllerConfiguration.java
new file mode 100644 (file)
index 0000000..2977d1a
--- /dev/null
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.config.spring;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.onap.clamp.clds.config.ClampProperties;
+import org.onap.clamp.clds.config.sdc.SdcControllersConfiguration;
+import org.onap.clamp.clds.exception.sdc.controller.SdcControllerException;
+import org.onap.clamp.clds.sdc.controller.SdcSingleController;
+import org.onap.clamp.clds.sdc.controller.SdcSingleControllerStatus;
+import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller;
+import org.onap.clamp.loop.CsarInstallerImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.scheduling.annotation.Scheduled;
+
+@Configuration
+@Profile("clamp-sdc-controller-new")
+public class SdcControllerConfiguration {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(SdcControllerConfiguration.class);
+    private List<SdcSingleController> sdcControllersList = new ArrayList<>();
+    @Autowired
+    private ClampProperties clampProp;
+    @Autowired
+    protected CsarInstaller csarInstaller;
+
+    @PostConstruct
+    public void loadSdcControllers() {
+        SdcControllersConfiguration sdcControllersConfig = getSdcControllersConfiguration();
+        sdcControllersConfig.getAllDefinedControllers().forEach((k, v) -> {
+            logger.info("Creating controller instance:" + k);
+            SdcSingleController sdcController = new SdcSingleController(clampProp, csarInstaller, v, null);
+            sdcControllersList.add(sdcController);
+        });
+    }
+
+    @Scheduled(fixedRate = 120000)
+    public void checkAllSdcControllers() {
+        logger.info("Checking that all SDC Controllers defined are up and running");
+        for (SdcSingleController controller : sdcControllersList) {
+            try {
+                if (SdcSingleControllerStatus.STOPPED.equals(controller.getControllerStatus())) {
+                    controller.initSdc();
+                }
+            } catch (SdcControllerException e) {
+                logger.error("Exception caught when booting sdc controller", e);
+            }
+        }
+        logger.info("SDC Controllers check completed");
+    }
+
+    @PreDestroy
+    public void killSdcControllers() {
+        sdcControllersList.forEach(e -> {
+            try {
+                e.closeSdc();
+            } catch (SdcControllerException e1) {
+                logger.error("Exception caught when stopping sdc controller", e1);
+            }
+        });
+    }
+
+    @Bean(name = "csarInstaller")
+    public CsarInstaller getCsarInstaller() {
+        return new CsarInstallerImpl();
+    }
+
+    @Bean(name = "sdcControllersConfiguration")
+    public SdcControllersConfiguration getSdcControllersConfiguration() {
+        return new SdcControllersConfiguration();
+    }
+}
\ No newline at end of file
index 16aee27..542411b 100644 (file)
@@ -26,12 +26,14 @@ import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
+
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+
 import org.json.JSONObject;
 import org.springframework.stereotype.Component;
 import org.yaml.snakeyaml.Yaml;
@@ -52,10 +54,8 @@ public class BlueprintParser {
     private static final String CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM = "clamp_node.relationships.gets_input_from";
     private static final String TARGET = "target";
 
-    BlueprintParser() {}
-
-    Set<MicroService> getMicroServices(String blueprintString) {
-        Set <MicroService> microServices = new HashSet<>();
+    public Set<MicroService> getMicroServices(String blueprintString) {
+        Set<MicroService> microServices = new HashSet<>();
         JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString);
         JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject();
 
@@ -70,15 +70,15 @@ public class BlueprintParser {
         return microServices;
     }
 
-    List<MicroService> fallbackToOneMicroService(String blueprintString) {
+    public List<MicroService> fallbackToOneMicroService(String blueprintString) {
         JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString);
         JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject();
         String theBiggestMicroServiceContent = "";
         String theBiggestMicroServiceKey = "";
         for (Entry<String, JsonElement> entry : results.entrySet()) {
             String msAsString = entry.getValue().toString();
-            int len =msAsString.length();
-            if(len > theBiggestMicroServiceContent.length()) {
+            int len = msAsString.length();
+            if (len > theBiggestMicroServiceContent.length()) {
                 theBiggestMicroServiceContent = msAsString;
                 theBiggestMicroServiceKey = entry.getKey();
             }
@@ -105,7 +105,7 @@ public class BlueprintParser {
             JsonArray relationships = ob.getAsJsonArray(RELATIONSHIPS);
             for (JsonElement element : relationships) {
                 String target = getTarget(element.getAsJsonObject());
-                if(!target.isEmpty()) {
+                if (!target.isEmpty()) {
                     return target;
                 }
             }
@@ -120,9 +120,8 @@ public class BlueprintParser {
     }
 
     private String getTarget(JsonObject elementObject) {
-        if (elementObject.has(TYPE) &&
-            elementObject.has(TARGET) &&
-            elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) {
+        if (elementObject.has(TYPE) && elementObject.has(TARGET)
+            && elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) {
             return elementObject.get(TARGET).getAsString();
         }
         return "";
index f2c75ef..b65a994 100644 (file)
@@ -29,6 +29,7 @@ import com.att.eelf.configuration.EELFManager;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -135,7 +136,7 @@ public class CsarHandler {
                     blueprintArtifact
                         .setBlueprintInvariantServiceUuid(this.getSdcNotification().getServiceInvariantUUID());
                     try (InputStream stream = zipFile.getInputStream(entry)) {
-                        blueprintArtifact.setDcaeBlueprint(IOUtils.toString(stream));
+                        blueprintArtifact.setDcaeBlueprint(IOUtils.toString(stream, StandardCharsets.UTF_8));
                     }
                     blueprintArtifact.setResourceAttached(searchForResourceByInstanceName(entry.getName().substring(
                         entry.getName().indexOf(RESOURCE_INSTANCE_NAME_PREFIX) + RESOURCE_INSTANCE_NAME_PREFIX.length(),
@@ -170,13 +171,13 @@ public class CsarHandler {
         return mapOfBlueprints;
     }
 
-    Optional<String> getPolicyModelYaml() throws IOException {
+    public Optional<String> getPolicyModelYaml() throws IOException {
         String result = null;
         try (ZipFile zipFile = new ZipFile(csarFilePath)) {
             ZipEntry entry = zipFile.getEntry(POLICY_DEFINITION_NAME_SUFFIX);
             if (entry != null) {
-                result = IOUtils.toString(zipFile.getInputStream(entry));
-            } else{
+                result = IOUtils.toString(zipFile.getInputStream(entry), StandardCharsets.UTF_8);
+            } else {
                 logger.info("Policy model not found inside the CSAR file: " + csarFilePath);
             }
             return Optional.ofNullable(result);
index 1303f2a..6dc4183 100644 (file)
@@ -17,6 +17,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * ============LICENSE_END============================================
+ * Modifications copyright (c) 2019 Nokia
  * ===================================================================
  *
  */
@@ -26,19 +27,17 @@ package org.onap.clamp.clds.sdc.controller.installer;
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
 import com.google.gson.JsonObject;
-
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-
 import java.util.Optional;
 import java.util.Set;
 import javax.annotation.PostConstruct;
 import javax.xml.transform.TransformerException;
-
 import org.apache.commons.io.IOUtils;
 import org.json.simple.parser.ParseException;
 import org.onap.clamp.clds.client.DcaeInventoryServices;
@@ -55,9 +54,11 @@ import org.onap.clamp.clds.service.CldsService;
 import org.onap.clamp.clds.service.CldsTemplateService;
 import org.onap.clamp.clds.transform.XslTransformer;
 import org.onap.clamp.clds.util.JsonUtils;
+import org.onap.clamp.clds.util.drawing.SvgFacade;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.yaml.snakeyaml.Yaml;
 
@@ -66,6 +67,7 @@ import org.yaml.snakeyaml.Yaml;
  * There is no state kept by the bean. It's used to deploy the csar/notification
  * received from SDC in DB.
  */
+@Component
 public class CsarInstallerImpl implements CsarInstaller {
 
     private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarInstallerImpl.class);
@@ -80,25 +82,34 @@ public class CsarInstallerImpl implements CsarInstaller {
      */
     @Value("${clamp.config.sdc.blueprint.parser.mapping:'classpath:/clds/blueprint-parser-mapping.json'}")
     protected String blueprintMappingFile;
-    @Autowired
     protected ApplicationContext appContext;
-    @Autowired
     private CldsDao cldsDao;
-    @Autowired
     CldsTemplateService cldsTemplateService;
-    @Autowired
     CldsService cldsService;
-    @Autowired
     DcaeInventoryServices dcaeInventoryService;
-    @Autowired
     private XslTransformer cldsBpmnTransformer;
 
+    @Autowired
+    public CsarInstallerImpl(ApplicationContext appContext,
+                             CldsDao cldsDao, CldsTemplateService cldsTemplateService, CldsService cldsService,
+                             DcaeInventoryServices dcaeInventoryService, XslTransformer cldsBpmnTransformer) {
+        this.appContext = appContext;
+        this.cldsDao = cldsDao;
+        this.cldsTemplateService = cldsTemplateService;
+        this.cldsService = cldsService;
+        this.dcaeInventoryService = dcaeInventoryService;
+        this.cldsBpmnTransformer = cldsBpmnTransformer;
+    }
+
     @Autowired
     private BlueprintParser blueprintParser;
 
     @Autowired
     private ChainGenerator chainGenerator;
 
+    @Autowired
+    private SvgFacade svgFacade;
+
     @PostConstruct
     public void loadConfiguration() throws IOException {
         BlueprintParserMappingConfiguration
@@ -154,16 +165,7 @@ public class CsarInstallerImpl implements CsarInstaller {
         }
     }
 
-    private void createPolicyModel(CsarHandler csar) throws PolicyModelException {
-        try{
-            Optional<String> policyModelYaml = csar.getPolicyModelYaml();
-            // save policy model into the database
-        } catch (IOException e) {
-            throw new PolicyModelException("TransformerException when decoding the YamlText", e);
-        }
-    }
-
-    private BlueprintParserFilesConfiguration searchForRightMapping(BlueprintArtifact blueprintArtifact)
+    BlueprintParserFilesConfiguration searchForRightMapping(BlueprintArtifact blueprintArtifact)
         throws SdcArtifactInstallerException {
         List<BlueprintParserFilesConfiguration> listConfig = new ArrayList<>();
         Yaml yaml = new Yaml();
@@ -202,6 +204,15 @@ public class CsarInstallerImpl implements CsarInstaller {
         return node.toString();
     }
 
+    private void createPolicyModel(CsarHandler csar) throws PolicyModelException {
+        try{
+            Optional<String> policyModelYaml = csar.getPolicyModelYaml();
+            // save policy model into the database
+        } catch (IOException e) {
+            throw new PolicyModelException("TransformerException when decoding the YamlText", e);
+        }
+    }
+
     private static String searchForPolicyScopePrefix(BlueprintArtifact blueprintArtifact)
         throws SdcArtifactInstallerException {
         String policyName = null;
@@ -255,16 +266,16 @@ public class CsarInstallerImpl implements CsarInstaller {
         if(microServicesChain.isEmpty()) {
             microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint());
         }
-        //place where SVG text will be generated
+        String imageText = svgFacade.getSvgImage(microServicesChain);
 
         CldsTemplate template = new CldsTemplate();
         template.setBpmnId("Sdc-Generated");
-        template
-            .setBpmnText(IOUtils.toString(appContext.getResource(configFiles.getBpmnXmlFilePath()).getInputStream()));
+        template.setBpmnText(IOUtils.toString(appContext.getResource(configFiles.getBpmnXmlFilePath()).getInputStream(),
+            StandardCharsets.UTF_8));
         template.setPropText(
             "{\"global\":[{\"name\":\"service\",\"value\":[\"" + blueprintArtifact.getDcaeBlueprint() + "\"]}]}");
         template
-            .setImageText(IOUtils.toString(appContext.getResource(configFiles.getSvgXmlFilePath()).getInputStream()));
+            .setImageText(imageText);
         template.setName(TEMPLATE_NAME_PREFIX + buildModelName(csar, blueprintArtifact));
         template.save(cldsDao, null);
         logger.info("Fake Clds Template created for blueprint " + blueprintArtifact.getBlueprintArtifactName()
index 784d95e..8a172ab 100644 (file)
@@ -82,13 +82,15 @@ public class ToscaYamlToJsonConvertor {
         this.cldsDao = cldsDao;
     }
 
-    @SuppressWarnings("unchecked")
     public String parseToscaYaml(String yamlString) {
 
         Yaml yaml = new Yaml();
-        LinkedHashMap<String, Object> loadedYaml = (LinkedHashMap<String, Object>) yaml.load(yamlString);
-        LinkedHashMap<String, Object> nodeTypes = new LinkedHashMap<String, Object>();
-        LinkedHashMap<String, Object> dataNodes = new LinkedHashMap<String, Object>();
+        LinkedHashMap<String, Object> loadedYaml = yaml.load(yamlString);
+        if (loadedYaml == null) {
+            return "";
+        }
+        LinkedHashMap<String, Object> nodeTypes = new LinkedHashMap<>();
+        LinkedHashMap<String, Object> dataNodes = new LinkedHashMap<>();
         JSONObject jsonEditorObject = new JSONObject();
         JSONObject jsonParentObject = new JSONObject();
         JSONObject jsonTempObject = new JSONObject();
index 5886e01..a8f233e 100644 (file)
@@ -23,6 +23,7 @@
 
 package org.onap.clamp.clds.transform;
 
+import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
 import java.io.StringReader;
 import java.io.StringWriter;
 
@@ -45,7 +46,7 @@ public class XslTransformer {
     private Templates templates;
 
     public void setXslResourceName(String xslResourceName) throws TransformerConfigurationException {
-        TransformerFactory tfactory = TransformerFactory.newInstance();
+        TransformerFactory tfactory = new TransformerFactoryImpl();
         tfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
         tfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
         templates = tfactory.newTemplates(new StreamSource(ResourceFileUtil.getResourceAsStream(xslResourceName)));
diff --git a/src/main/java/org/onap/clamp/clds/util/XmlTools.java b/src/main/java/org/onap/clamp/clds/util/XmlTools.java
new file mode 100644 (file)
index 0000000..391f008
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util;
+
+import java.io.StringWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.batik.anim.dom.SVGDOMImplementation;
+import org.apache.batik.dom.GenericDOMImplementation;
+import org.apache.batik.util.SVGConstants;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+
+public class XmlTools {
+    public static String exportXmlDocumentAsString(Document doc) {
+        try {
+            TransformerFactory tf = TransformerFactory.newInstance();
+            Transformer transformer = tf.newTransformer();
+            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+            StringWriter writer = new StringWriter();
+            transformer.transform(new DOMSource(doc), new StreamResult(writer));
+            return writer.getBuffer().toString();
+        } catch (TransformerException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    public static Document createEmptySvgDocument() {
+        DOMImplementation domImplementation = GenericDOMImplementation.getDOMImplementation();
+        String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
+        return domImplementation.createDocument(svgNS, SVGConstants.SVG_SVG_TAG, null);
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/AwtUtils.java b/src/main/java/org/onap/clamp/clds/util/drawing/AwtUtils.java
new file mode 100755 (executable)
index 0000000..f746ab1
--- /dev/null
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+public class AwtUtils {
+    private static final int ARROW_W = 4;
+    private static final int ARROW_H = 2;
+    private static final  int FONT_SIZE = 12;
+    private static final  int FONT_STYLE = Font.PLAIN;
+    private static final String FONT_FACE = "SansSerif";
+    private static final Color TRANSPARENT = new Color(0.0f, 0.0f,0.0f,0.0f);
+
+    static void rectWithText(Graphics2D g2d, String text, Point p, int w, int h) {
+        Rectangle rect = new Rectangle(p.x, p.y, w, h);
+        g2d.draw(rect);
+        Color oldColor = g2d.getColor();
+        g2d.setColor(TRANSPARENT);
+        g2d.fill(rect);
+        g2d.setColor(oldColor);
+        addText(g2d, text, p.x+w/2, p.y+h/2);
+    }
+
+    static void drawArrow(Graphics2D g2d, Point from, Point to, int lineThickness) {
+        int x2 = to.x - lineThickness;
+        g2d.drawLine(from.x, from.y, x2-lineThickness, to.y);
+        g2d.drawPolygon(new int[] {x2-ARROW_W, x2-ARROW_W, x2},new int[] {to.y- ARROW_H, to.y+ ARROW_H, to.y},3);
+        g2d.fillPolygon(new int[] {x2-ARROW_W, x2-ARROW_W, x2},new int[] {to.y- ARROW_H, to.y+ ARROW_H, to.y},3);
+    }
+
+    private static void addText(Graphics2D g2d, String text, int x, int y) {
+        Font f = new Font(FONT_FACE, FONT_STYLE, FONT_SIZE);
+        g2d.setFont(f);
+
+        FontMetrics fm1 = g2d.getFontMetrics();
+        int w1 = fm1.stringWidth(text);
+        int x1 = x - (w1 / 2);
+
+        g2d.setFont(f);
+        g2d.setColor(Color.BLACK);
+        g2d.drawString(text, x1, y);
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraph.java b/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraph.java
new file mode 100755 (executable)
index 0000000..f49e735
--- /dev/null
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import java.util.Objects;
+import org.onap.clamp.clds.util.XmlTools;
+
+public class ClampGraph {
+    private final DocumentBuilder documentBuilder;
+    private String svg;
+
+    ClampGraph(DocumentBuilder documentBuilder) {
+        this.documentBuilder = documentBuilder;
+    }
+
+    public String getAsSVG() {
+        if(Objects.isNull(svg) || svg.isEmpty()) {
+            svg = XmlTools.exportXmlDocumentAsString(this.documentBuilder.getGroupingDocument());
+        }
+        return svg;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java b/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java
new file mode 100755 (executable)
index 0000000..243cb4a
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class ClampGraphBuilder {
+    private String policy;
+    private String collector;
+    private List<String> microServices = new ArrayList<>();
+    private final Painter painter;
+
+    public ClampGraphBuilder(Painter painter) {
+        this.painter = painter;
+    }
+
+    public ClampGraphBuilder collector(String c) {
+        collector = c;
+        return this;
+    }
+
+    public ClampGraphBuilder policy(String p) {
+        policy = p;
+        return this;
+    }
+
+    public ClampGraphBuilder microService(String ms) {
+        microServices.add(ms);
+        return this;
+    }
+
+    public ClampGraph build() {
+        if(microServices.isEmpty()) {
+            throw new InvalidStateException("At least one microservice is required");
+        }
+        if(Objects.isNull(policy) || policy.trim().isEmpty()) {
+            throw new InvalidStateException("Policy element must be present");
+        }
+        return new ClampGraph(painter.doPaint(collector, microServices, policy));
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/DocumentBuilder.java b/src/main/java/org/onap/clamp/clds/util/drawing/DocumentBuilder.java
new file mode 100644 (file)
index 0000000..f34eaf2
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import org.apache.batik.svggen.SVGGraphics2D;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class DocumentBuilder {
+    private final Document groupingDocument;
+    private final Document documentFactory;
+
+    static final String DATA_ELEMENT_ID_ATTRIBUTE = "data-element-id";
+
+    DocumentBuilder(Document groupingDocument, Document documentFactory) {
+        this.groupingDocument = groupingDocument;
+        this.documentFactory = documentFactory;
+    }
+
+    void pushChangestoDocument(SVGGraphics2D g2d, String dataElementId) {
+        Element element =
+            this.documentFactory.createElementNS(SVGGraphics2D.SVG_NAMESPACE_URI,
+                SVGGraphics2D.SVG_G_TAG);
+        element.setAttribute(DATA_ELEMENT_ID_ATTRIBUTE, dataElementId);
+        g2d.getRoot(element);
+        Node node = this.groupingDocument.importNode(element, true);
+        this.groupingDocument.getDocumentElement().appendChild(node);
+    }
+
+    Document getGroupingDocument() {
+        return groupingDocument;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/ImageBuilder.java b/src/main/java/org/onap/clamp/clds/util/drawing/ImageBuilder.java
new file mode 100644 (file)
index 0000000..4d76581
--- /dev/null
@@ -0,0 +1,135 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import java.awt.BasicStroke;
+import java.awt.Point;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.Ellipse2D;
+import java.util.UUID;
+import org.apache.batik.svggen.SVGGraphics2D;
+
+public class ImageBuilder {
+
+    public static final int POLICY_LINE_RATIO = 2;
+    public static final int COLLECTOR_LINE_RATIO = 6;
+    public static final float MS_LINE_TO_HEIGHT_RATIO = 0.75f;
+
+    private Point currentPoint;
+    private final int baseLength;
+    private final int rectHeight;
+    private final SVGGraphics2D g2d;
+    private final DocumentBuilder documentBuilder;
+
+    private static final int LINE_THICKNESS = 2;
+    private static final int CIRCLE_RADIUS = 17;
+
+    ImageBuilder(SVGGraphics2D svgGraphics2D, DocumentBuilder documentBuilder,
+            Point startingPoint, int baseLength, int rectHeight) {
+        this.g2d = svgGraphics2D;
+        this.documentBuilder = documentBuilder;
+        this.currentPoint = new Point(startingPoint);
+        this.baseLength = baseLength;
+        this.rectHeight = rectHeight;
+    }
+
+    ImageBuilder rectangle(String dataElementId, RectTypes rectType, String text) {
+        Point next = new Point(currentPoint.x + baseLength, currentPoint.y);
+        Point p = coordinatesForRectangle(currentPoint, next);
+
+        handleBasedOnRectType(rectType, text, p, baseLength, rectHeight);
+
+        documentBuilder.pushChangestoDocument(g2d, dataElementId);
+        currentPoint = next;
+        return this;
+    }
+
+    ImageBuilder arrow() {
+        String dataElementId = "Arrow-" + UUID.randomUUID().toString();
+        Point to = new Point(currentPoint.x + baseLength, currentPoint.y);
+        AwtUtils.drawArrow(g2d, currentPoint, to, LINE_THICKNESS);
+        documentBuilder.pushChangestoDocument(g2d, dataElementId);
+        currentPoint = to;
+        return this;
+    }
+
+    ImageBuilder circle(String dataElementId, int lineThickness) {
+        Point to = new Point(currentPoint.x + 2 * CIRCLE_RADIUS, currentPoint.y);
+        Shape circleStart =
+            new Ellipse2D.Double(currentPoint.x, currentPoint.y - CIRCLE_RADIUS,
+                2 * CIRCLE_RADIUS, 2 * CIRCLE_RADIUS);
+
+        Stroke oldStroke = g2d.getStroke();
+        g2d.setStroke(new BasicStroke(lineThickness));
+        g2d.draw(circleStart);
+        g2d.setStroke(oldStroke);
+        documentBuilder.pushChangestoDocument(g2d, dataElementId);
+        currentPoint = to;
+        return this;
+    }
+
+    DocumentBuilder getDocumentBuilder() {
+        return documentBuilder;
+    }
+
+    private void handleBasedOnRectType(RectTypes rectType, String text, Point p, int w, int h) {
+        AwtUtils.rectWithText(g2d, text, p, w, h);
+        switch (rectType) {
+            case COLECTOR:
+                drawVerticalLineForCollector(p, w, h);
+                break;
+            case MICROSERVICE:
+                drawHorizontalLineForMicroService(p, w, h);
+                break;
+            case POLICY:
+                drawDiagonalLineForPolicy(p, w, h);
+                break;
+        }
+    }
+
+    private void drawVerticalLineForCollector(Point p, int w, int h) {
+        g2d.drawLine(p.x + w / COLLECTOR_LINE_RATIO, p.y, p.x + w / COLLECTOR_LINE_RATIO, p.y + h);
+    }
+
+    private void drawHorizontalLineForMicroService(Point p, int w, int h) {
+        int y = calculateMsHorizontalLineYCoordinate(p,h);
+        g2d.drawLine(p.x, y, p.x + w, y);
+    }
+
+    private void drawDiagonalLineForPolicy(Point p, int w, int h) {
+        g2d.drawLine(p.x, p.y + h / POLICY_LINE_RATIO, p.x + w / POLICY_LINE_RATIO, p.y);
+    }
+
+    private int calculateMsHorizontalLineYCoordinate(Point p, int h) {
+        return (int)(p.y * h * MS_LINE_TO_HEIGHT_RATIO);
+    }
+
+    private Point coordinatesForRectangle(Point from, Point next) {
+        int x = from.x;
+        int y = from.y - next.y + LINE_THICKNESS / 2;
+        return new Point(x,y);
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/InvalidStateException.java b/src/main/java/org/onap/clamp/clds/util/drawing/InvalidStateException.java
new file mode 100644 (file)
index 0000000..91af9f1
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+public class InvalidStateException extends RuntimeException {
+    public InvalidStateException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java b/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java
new file mode 100755 (executable)
index 0000000..e41ca8f
--- /dev/null
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.util.List;
+import org.apache.batik.svggen.SVGGraphics2D;
+
+public class Painter {
+    private final int canvasSize;
+    private final SVGGraphics2D g2d;
+    private final DocumentBuilder documentBuilder;
+
+    private static final int DEFALUT_CANVAS_SIZE = 900;
+    private static final int SLIM_LINE = 2;
+    private static final int THICK_LINE = 4;
+    private static final double RECT_RATIO = 3.0 / 2.0;
+    private static final int CIRCLE_RADIUS = 17;
+
+    public Painter(SVGGraphics2D svgGraphics2D, DocumentBuilder documentBuilder) {
+        this.g2d = svgGraphics2D;
+        this.documentBuilder = documentBuilder;
+        this.canvasSize = DEFALUT_CANVAS_SIZE;
+    }
+
+    DocumentBuilder doPaint(String collector, List<String> microServices, String policy) {
+        int numOfRectangles = 2 + microServices.size();
+        int numOfArrows = numOfRectangles + 1;
+        int baseLength = (canvasSize - 2 * CIRCLE_RADIUS) / (numOfArrows + numOfRectangles);
+        int rectHeight = (int) (baseLength / RECT_RATIO);
+
+        adjustGraphics2DProperties();
+
+        Point origin = new Point(0, rectHeight / 2);
+        ImageBuilder ib = new ImageBuilder(g2d, documentBuilder, origin, baseLength, rectHeight);
+
+        doTheActualDrawing(collector, microServices, policy, ib);
+
+        return ib.getDocumentBuilder();
+    }
+
+    private void doTheActualDrawing(String collector, List<String> microServices, String policy, ImageBuilder ib) {
+        ib.circle("start-circle", SLIM_LINE)
+            .arrow()
+            .rectangle(collector, RectTypes.COLECTOR, collector);
+
+        for(String ms : microServices) {
+            ib.arrow().rectangle(ms, RectTypes.MICROSERVICE, ms);
+        }
+
+        ib.arrow()
+            .rectangle(policy, RectTypes.POLICY, policy)
+            .arrow()
+            .circle("stop-circle", THICK_LINE);
+    }
+
+    private void adjustGraphics2DProperties() {
+        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+            RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+            RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
+        g2d.setStroke(new BasicStroke(SLIM_LINE));
+        g2d.setPaint(Color.BLACK);
+    }
+
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/RectTypes.java b/src/main/java/org/onap/clamp/clds/util/drawing/RectTypes.java
new file mode 100644 (file)
index 0000000..e693243
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+enum RectTypes {
+    COLECTOR, MICROSERVICE, POLICY
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/SvgFacade.java b/src/main/java/org/onap/clamp/clds/util/drawing/SvgFacade.java
new file mode 100644 (file)
index 0000000..0ba8486
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import java.util.List;
+import org.apache.batik.svggen.SVGGraphics2D;
+import org.onap.clamp.clds.sdc.controller.installer.MicroService;
+import org.onap.clamp.clds.util.XmlTools;
+import org.springframework.stereotype.Component;
+import org.w3c.dom.Document;
+
+@Component
+public class SvgFacade {
+    public String getSvgImage(List<MicroService> microServicesChain) {
+        SVGGraphics2D svgGraphics2D = new SVGGraphics2D(XmlTools.createEmptySvgDocument());
+        Document document = XmlTools.createEmptySvgDocument();
+        DocumentBuilder dp = new DocumentBuilder(document, svgGraphics2D.getDOMFactory());
+        Painter p = new Painter(svgGraphics2D, dp);
+        ClampGraphBuilder cgp = new ClampGraphBuilder(p).collector("VES");
+        for(MicroService ms : microServicesChain) {
+            cgp = cgp.microService(ms.getName());
+        }
+        ClampGraph cg = cgp.policy("Policy").build();
+        return cg.getAsSVG();
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/loop/CsarInstallerImpl.java b/src/main/java/org/onap/clamp/loop/CsarInstallerImpl.java
new file mode 100644 (file)
index 0000000..6e12f29
--- /dev/null
@@ -0,0 +1,223 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.loop;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.json.simple.parser.ParseException;
+import org.onap.clamp.clds.client.DcaeInventoryServices;
+import org.onap.clamp.clds.exception.policy.PolicyModelException;
+import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;
+import org.onap.clamp.clds.model.dcae.DcaeInventoryResponse;
+import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact;
+import org.onap.clamp.clds.sdc.controller.installer.BlueprintParser;
+import org.onap.clamp.clds.sdc.controller.installer.ChainGenerator;
+import org.onap.clamp.clds.sdc.controller.installer.CsarHandler;
+import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller;
+import org.onap.clamp.clds.sdc.controller.installer.MicroService;
+import org.onap.clamp.clds.util.JsonUtils;
+import org.onap.clamp.policy.Policy;
+import org.onap.clamp.policy.microservice.MicroServicePolicy;
+import org.onap.clamp.policy.operational.OperationalPolicy;
+import org.onap.sdc.tosca.parser.enums.SdcTypes;
+import org.onap.sdc.toscaparser.api.NodeTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * This class will be instantiated by spring config, and used by Sdc Controller.
+ * There is no state kept by the bean. It's used to deploy the csar/notification
+ * received from SDC in DB.
+ */
+public class CsarInstallerImpl implements CsarInstaller {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarInstallerImpl.class);
+    public static final String TEMPLATE_NAME_PREFIX = "DCAE-Designer-Template-";
+    public static final String CONTROL_NAME_PREFIX = "ClosedLoop-";
+    public static final String GET_INPUT_BLUEPRINT_PARAM = "get_input";
+    // This will be used later as the policy scope
+    public static final String MODEL_NAME_PREFIX = "Loop_";
+
+    @Autowired
+    LoopsRepository loopRepository;
+
+    @Autowired
+    BlueprintParser blueprintParser;
+
+    @Autowired
+    ChainGenerator chainGenerator;
+
+    @Autowired
+    DcaeInventoryServices dcaeInventoryService;
+
+    @Override
+    public boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException {
+        boolean alreadyInstalled = true;
+        for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
+            alreadyInstalled = alreadyInstalled
+                && loopRepository.existsById(Loop.generateLoopName(csar.getSdcNotification().getServiceName(),
+                    csar.getSdcNotification().getServiceVersion(),
+                    blueprint.getValue().getResourceAttached().getResourceInstanceName(),
+                    blueprint.getValue().getBlueprintArtifactName()));
+        }
+        return alreadyInstalled;
+    }
+
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED)
+    public void installTheCsar(CsarHandler csar)
+        throws SdcArtifactInstallerException, InterruptedException, PolicyModelException {
+        try {
+            logger.info("Installing the CSAR " + csar.getFilePath());
+            for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
+                logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName());
+                loopRepository.save(createLoopFromBlueprint(csar, blueprint.getValue()));
+            }
+            logger.info("Successfully installed the CSAR " + csar.getFilePath());
+        } catch (IOException e) {
+            throw new SdcArtifactInstallerException("Exception caught during the Csar installation in database", e);
+        } catch (ParseException e) {
+            throw new SdcArtifactInstallerException("Exception caught during the Dcae query to get ServiceTypeId", e);
+        }
+    }
+
+    private Loop createLoopFromBlueprint(CsarHandler csar, BlueprintArtifact blueprintArtifact)
+        throws IOException, ParseException, InterruptedException {
+        Loop newLoop = new Loop();
+        newLoop.setBlueprint(blueprintArtifact.getDcaeBlueprint());
+        newLoop.setName(Loop.generateLoopName(csar.getSdcNotification().getServiceName(),
+            csar.getSdcNotification().getServiceVersion(),
+            blueprintArtifact.getResourceAttached().getResourceInstanceName(),
+            blueprintArtifact.getBlueprintArtifactName()));
+        newLoop.setLastComputedState(LoopState.DESIGN);
+        newLoop.setMicroServicePolicies(createMicroServicePolicies(csar, blueprintArtifact, newLoop));
+        newLoop.setOperationalPolicies(createOperationalPolicies(csar, blueprintArtifact, newLoop));
+        // Set SVG XML computed
+        // newLoop.setSvgRepresentation(svgRepresentation);
+        newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(csar, blueprintArtifact));
+        newLoop.setModelPropertiesJson(createModelPropertiesJson(csar, blueprintArtifact));
+        DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact);
+        newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId());
+        return newLoop;
+    }
+
+    private HashSet<OperationalPolicy> createOperationalPolicies(CsarHandler csar, BlueprintArtifact blueprintArtifact,
+        Loop newLoop) {
+        return new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL",
+            csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(),
+            blueprintArtifact.getResourceAttached().getResourceInstanceName(),
+            blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject())));
+    }
+
+    private HashSet<MicroServicePolicy> createMicroServicePolicies(CsarHandler csar,
+        BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException {
+        HashSet<MicroServicePolicy> newSet = new HashSet<>();
+        for (MicroService microService : blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint())) {
+            newSet.add(new MicroServicePolicy(microService.getName(), csar.getPolicyModelYaml().orElse(""), false,
+                new HashSet<>(Arrays.asList(newLoop))));
+        }
+        return newSet;
+    }
+
+    private JsonObject createGlobalPropertiesJson(CsarHandler csar, BlueprintArtifact blueprintArtifact) {
+        JsonObject globalProperties = new JsonObject();
+        globalProperties.add("dcaeDeployParameters", getAllBlueprintParametersInJson(blueprintArtifact));
+        return globalProperties;
+
+    }
+
+    private JsonObject createModelPropertiesJson(CsarHandler csar, BlueprintArtifact blueprintArtifact) {
+        JsonObject modelProperties = new JsonObject();
+        Gson gson = new Gson();
+        modelProperties.add("serviceDetails",
+            gson.fromJson(gson.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class));
+
+        JsonObject resourcesProp = new JsonObject();
+        for (SdcTypes type : SdcTypes.values()) {
+            JsonObject resourcesPropByType = new JsonObject();
+            for (NodeTemplate nodeTemplate : csar.getSdcCsarHelper().getServiceNodeTemplateBySdcType(type)) {
+                resourcesPropByType.add(nodeTemplate.getName(), JsonUtils.GSON_JPA_MODEL
+                    .fromJson(new Gson().toJson(nodeTemplate.getMetaData().getAllProperties()), JsonObject.class));
+            }
+            resourcesProp.add(type.getValue(), resourcesPropByType);
+        }
+        modelProperties.add("resourceDetails", resourcesProp);
+        return modelProperties;
+    }
+
+    private JsonObject getAllBlueprintParametersInJson(BlueprintArtifact blueprintArtifact) {
+        JsonObject node = new JsonObject();
+        Yaml yaml = new Yaml();
+        Map<String, Object> inputsNodes = ((Map<String, Object>) ((Map<String, Object>) yaml
+            .load(blueprintArtifact.getDcaeBlueprint())).get("inputs"));
+        inputsNodes.entrySet().stream().filter(e -> !e.getKey().contains("policy_id")).forEach(elem -> {
+            Object defaultValue = ((Map<String, Object>) elem.getValue()).get("default");
+            if (defaultValue != null) {
+                addPropertyToNode(node, elem.getKey(), defaultValue);
+            } else {
+                node.addProperty(elem.getKey(), "");
+            }
+        });
+        node.addProperty("policy_id", "AUTO_GENERATED_POLICY_ID_AT_SUBMIT");
+        return node;
+    }
+
+    /**
+     * ll get the latest version of the artifact (version can be specified to DCAE
+     * call)
+     *
+     * @return The DcaeInventoryResponse object containing the dcae values
+     */
+    private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact)
+        throws IOException, ParseException, InterruptedException {
+        return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(),
+            blueprintArtifact.getBlueprintInvariantServiceUuid(),
+            blueprintArtifact.getResourceAttached().getResourceInvariantUUID());
+    }
+
+    private void addPropertyToNode(JsonObject node, String key, Object value) {
+        if (value instanceof String) {
+            node.addProperty(key, (String) value);
+        } else if (value instanceof Number) {
+            node.addProperty(key, (Number) value);
+        } else if (value instanceof Boolean) {
+            node.addProperty(key, (Boolean) value);
+        } else if (value instanceof Character) {
+            node.addProperty(key, (Character) value);
+        } else {
+            node.addProperty(key, JsonUtils.GSON.toJson(value));
+        }
+    }
+}
index 910c5aa..a4cd86d 100644 (file)
@@ -46,10 +46,10 @@ import javax.persistence.Table;
 import org.hibernate.annotations.Type;
 import org.hibernate.annotations.TypeDef;
 import org.hibernate.annotations.TypeDefs;
+import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
 import org.onap.clamp.loop.log.LoopLog;
 import org.onap.clamp.policy.microservice.MicroServicePolicy;
 import org.onap.clamp.policy.operational.OperationalPolicy;
-import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
 
 @Entity
 @Table(name = "loops")
@@ -86,7 +86,12 @@ public class Loop implements Serializable {
     @Column(columnDefinition = "json", name = "global_properties_json")
     private JsonObject globalPropertiesJson;
 
-    @Column(nullable = false, name = "blueprint_yaml")
+    @Expose
+    @Type(type = "json")
+    @Column(columnDefinition = "json", name = "model_properties_json")
+    private JsonObject modelPropertiesJson;
+
+    @Column(columnDefinition = "MEDIUMTEXT", nullable = false, name = "blueprint_yaml")
     private String blueprint;
 
     @Expose
@@ -213,14 +218,29 @@ public class Loop implements Serializable {
         log.setLoop(this);
     }
 
-    public String getDcaeBlueprintId() {
+    String getDcaeBlueprintId() {
         return dcaeBlueprintId;
     }
 
-    public void setDcaeBlueprintId(String dcaeBlueprintId) {
+    void setDcaeBlueprintId(String dcaeBlueprintId) {
         this.dcaeBlueprintId = dcaeBlueprintId;
     }
 
+    JsonObject getModelPropertiesJson() {
+        return modelPropertiesJson;
+    }
+
+    void setModelPropertiesJson(JsonObject modelPropertiesJson) {
+        this.modelPropertiesJson = modelPropertiesJson;
+    }
+
+    public static String generateLoopName(String serviceName, String serviceVersion, String resourceName,
+        String blueprintFilename) {
+        StringBuilder buffer = new StringBuilder("LOOP_").append(serviceName).append("_v").append(serviceVersion)
+            .append("_").append(resourceName).append("_").append(blueprintFilename.replaceAll(".yaml", ""));
+        return buffer.toString().replace('.', '_').replaceAll(" ", "");
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
index eeb6105..7e45174 100644 (file)
@@ -25,15 +25,16 @@ package org.onap.clamp.loop;
 
 import com.google.gson.JsonArray;
 import com.google.gson.reflect.TypeToken;
+
 import java.lang.reflect.Type;
 import java.util.List;
+
 import org.onap.clamp.clds.util.JsonUtils;
 import org.onap.clamp.policy.microservice.MicroServicePolicy;
 import org.onap.clamp.policy.operational.OperationalPolicy;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 
-
 @Controller
 public class LoopController {
 
@@ -67,4 +68,9 @@ public class LoopController {
             .fromJson(microServicePoliciesJson, MICROSERVICE_POLICY_TYPE);
         return loopService.updateMicroservicePolicies(loopName, microservicePolicies);
     }
+
+    public String getSVGRepresentation(String loopName) {
+        return loopService.getClosedLoopModelSVG(loopName);
+
+    }
 }
index 7b79c11..91b4bdf 100644 (file)
@@ -47,7 +47,7 @@ public class LoopService {
         this.operationalPolicyService = operationalPolicyService;
     }
 
-    Loop addNewLoop(Loop loop) {
+    Loop saveOrUpdateLoop(Loop loop) {
         return loopsRepository.save(loop);
     }
 
index 13ba1a9..c104b13 100644 (file)
@@ -21,7 +21,6 @@
  *
  */
 
-
 package org.onap.clamp.policy;
 
 import com.google.gson.JsonObject;
@@ -32,4 +31,12 @@ public interface Policy {
 
     JsonObject getJsonRepresentation();
 
+    static String generatePolicyName(String policyType, String serviceName, String serviceVersion, String resourceName,
+        String blueprintFilename) {
+        StringBuilder buffer = new StringBuilder(policyType).append("_").append(serviceName).append("_v")
+            .append(serviceVersion).append("_").append(resourceName).append("_")
+            .append(blueprintFilename.replaceAll(".yaml", ""));
+        return buffer.toString().replace('.', '_').replaceAll(" ", "");
+    }
+
 }
index e5b333d..857a3d7 100644 (file)
@@ -39,9 +39,11 @@ import javax.persistence.Table;
 import org.hibernate.annotations.Type;
 import org.hibernate.annotations.TypeDef;
 import org.hibernate.annotations.TypeDefs;
+import org.onap.clamp.clds.tosca.ToscaYamlToJsonConvertor;
+import org.onap.clamp.clds.util.JsonUtils;
+import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
 import org.onap.clamp.loop.Loop;
 import org.onap.clamp.policy.Policy;
-import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
 
 @Entity
 @Table(name = "micro_service_policies")
@@ -66,8 +68,7 @@ public class MicroServicePolicy implements Serializable, Policy {
     @Column(name = "shared", nullable = false)
     private Boolean shared;
 
-    @Expose
-    @Column(name = "policy_tosca", nullable = false)
+    @Column(columnDefinition = "MEDIUMTEXT", name = "policy_tosca", nullable = false)
     private String policyTosca;
 
     @Expose
@@ -79,7 +80,16 @@ public class MicroServicePolicy implements Serializable, Policy {
     private Set<Loop> usedByLoops = new HashSet<>();
 
     public MicroServicePolicy() {
-        //serialization
+        // serialization
+    }
+
+    public MicroServicePolicy(String name, String policyTosca, Boolean shared, Set<Loop> usedByLoops) {
+        this.name = name;
+        this.policyTosca = policyTosca;
+        this.shared = shared;
+        this.jsonRepresentation = JsonUtils.GSON_JPA_MODEL
+            .fromJson(new ToscaYamlToJsonConvertor(null).parseToscaYaml(policyTosca), JsonObject.class);
+        this.usedByLoops = usedByLoops;
     }
 
     public MicroServicePolicy(String name, String policyTosca, Boolean shared, JsonObject jsonRepresentation,
@@ -87,10 +97,11 @@ public class MicroServicePolicy implements Serializable, Policy {
         this.name = name;
         this.policyTosca = policyTosca;
         this.shared = shared;
-        this.jsonRepresentation = jsonRepresentation;
         this.usedByLoops = usedByLoops;
+        this.jsonRepresentation = jsonRepresentation;
     }
 
+    @Override
     public String getName() {
         return name;
     }
@@ -119,6 +130,7 @@ public class MicroServicePolicy implements Serializable, Policy {
         this.policyTosca = policyTosca;
     }
 
+    @Override
     public JsonObject getJsonRepresentation() {
         return jsonRepresentation;
     }
index 0fd1250..4fa575a 100644 (file)
                 <to uri="bean:org.onap.clamp.loop.LoopController?method=getLoop(${header.loopName})" />
             </route>
         </get>
+        <get uri="/v2/loop/svgRepresentation/{loopName}"
+            outType="java.lang.String"
+
+            produces="application/xml">
+            <to
+                uri="bean:org.onap.clamp.loop.LoopController?method=getSVGRepresentation(${header.loopName})" />
+        </get>
+        <post uri="/v2/loop/globalProperties/{loopName}"
+            type="com.google.gson.JsonArray"
+            consumes="application/json"
+            outType="org.onap.clamp.loop.Loop"
+            produces="application/json">
+            <to
+                uri="bean:org.onap.clamp.loop.LoopController?method=updateOperationalPolicies(${header.loopName},${body})" />
+        </post>
         <post uri="/v2/loop/updateOperationalPolicies/{loopName}"
             type="com.google.gson.JsonArray"
             consumes="application/json"
index 8fd817c..9b83e72 100644 (file)
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import com.google.gson.JsonSyntaxException;
+
 import java.io.IOException;
 import java.util.Map;
 
@@ -35,6 +36,7 @@ import org.onap.clamp.clds.config.sdc.SdcSingleControllerConfiguration;
 import org.onap.clamp.clds.exception.sdc.controller.SdcParametersException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.test.util.ReflectionTestUtils;
 
@@ -43,6 +45,7 @@ import org.springframework.test.util.ReflectionTestUtils;
  */
 @RunWith(SpringRunner.class)
 @SpringBootTest
+@ActiveProfiles(profiles = "clamp-default,clamp-default-user,clamp-sdc-controller")
 public class SdcControllersConfigurationItCase {
 
     @Autowired
index c6dbce4..55657c9 100644 (file)
@@ -41,19 +41,18 @@ import org.onap.sdc.api.notification.INotificationData;
 import org.onap.sdc.api.notification.IResourceInstance;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
 @SpringBootTest
+@ActiveProfiles(profiles = "clamp-default,clamp-default-user,clamp-sdc-controller")
 public class SdcSingleControllerItCase {
 
-    private static final String SDC_FOLDER = "/tmp/csar-handler-tests";
     private static final String CSAR_ARTIFACT_NAME = "testArtifact.csar";
     private static final String SERVICE_UUID = "serviceUUID";
     private static final String RESOURCE1_UUID = "resource1UUID";
     private static final String RESOURCE1_INSTANCE_NAME = "sim-1802 0";
-    private static final String RESOURCE1_INSTANCE_NAME_IN_CSAR = "sim18020";
-    private static final String BLUEPRINT1_NAME = "FOI.Simfoimap223S0112.event_proc_bp.yaml";
 
     @Autowired
     private ClampProperties clampProp;
index 0df2523..d3a823f 100644 (file)
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -60,13 +61,14 @@ import org.onap.sdc.toscaparser.api.elements.Metadata;
 import org.skyscreamer.jsonassert.JSONAssert;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
 @SpringBootTest
+@ActiveProfiles(profiles = "clamp-default,clamp-default-user,clamp-sdc-controller")
 public class CsarInstallerItCase {
 
-    private static final String CSAR_ARTIFACT_NAME = "testArtifact.csar";
     private static final String INVARIANT_SERVICE_UUID = "4cc5b45a-1f63-4194-8100-cd8e14248c92";
     private static final String INVARIANT_RESOURCE1_UUID = "07e266fc-49ab-4cd7-8378-ca4676f1b9ec";
     private static final String INVARIANT_RESOURCE2_UUID = "023a3f0d-1161-45ff-b4cf-8918a8ccf3ad";
@@ -87,7 +89,8 @@ public class CsarInstallerItCase {
         blueprintMap.put("resourceid", blueprintArtifact);
         Mockito.when(csarHandler.getMapOfBlueprints()).thenReturn(blueprintMap);
         Mockito.when(blueprintArtifact.getDcaeBlueprint()).thenReturn(
-            IOUtils.toString(ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/not-recognized.yaml")));
+            IOUtils.toString(ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/not-recognized.yaml"),
+                StandardCharsets.UTF_8));
         csarInstaller.installTheCsar(csarHandler);
         fail("Should have raised an SdcArtifactInstallerException");
     }
@@ -162,16 +165,17 @@ public class CsarInstallerItCase {
         csarInstaller.installTheCsar(csar);
         CldsModel cldsModel1 = verifyClosedLoopModelLoadedInDb(csar, "tca.yaml");
         JSONAssert.assertEquals(
-            IOUtils.toString(ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/prop-text-for-tca.json")),
+            IOUtils.toString(ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/prop-text-for-tca.json"),
+                StandardCharsets.UTF_8),
             cldsModel1.getPropText(), true);
         CldsModel cldsModel2 = verifyClosedLoopModelLoadedInDb(csar, "tca_2.yaml");
-        JSONAssert.assertEquals(
-            IOUtils
-                .toString(ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/prop-text-for-tca-2.json")),
-            cldsModel2.getPropText(), true);
+        JSONAssert.assertEquals(IOUtils.toString(
+            ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/prop-text-for-tca-2.json"),
+            StandardCharsets.UTF_8), cldsModel2.getPropText(), true);
         CldsModel cldsModel3 = verifyClosedLoopModelLoadedInDb(csar, "tca_3.yaml");
         JSONAssert.assertEquals(
-            IOUtils.toString(ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/prop-text-for-tca.json")),
+            IOUtils.toString(ResourceFileUtil.getResourceAsStream("example/sdc/blueprint-dcae/prop-text-for-tca.json"),
+                StandardCharsets.UTF_8),
             cldsModel3.getPropText(), true);
     }
 
index 544c8ca..e008874 100644 (file)
@@ -161,7 +161,7 @@ public class CsarHandlerTest {
         CsarHandler csar = new CsarHandler(buildFakeSdcNotification(), "test-controller", "/tmp/csar-handler-tests");
         csar.save(buildFakeSdcResut());
         String policyModelYaml = csar.getPolicyModelYaml().get();
-        assertTrue(policyModelYaml.contains("tosca_simple_yaml_1_1"));
+        assertTrue(policyModelYaml.contains("tosca_simple_yaml_1_0_0"));
     }
 
     @Test
index a995c52..1fe3ff3 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * ============LICENSE_END============================================
+ *  * Modifications copyright (c) 2019 Nokia
  * ===================================================================
  *
  */
 
-package org.onap.clamp.clds.sdc.controller.installer;
 
-import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+package org.onap.clamp.clds.sdc.controller.installer;
 
 import com.google.gson.JsonObject;
 import java.io.IOException;
+import java.io.InputStream;
+import org.apache.commons.io.IOUtils;
+import org.assertj.core.api.Assertions;
+import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.clamp.clds.client.DcaeInventoryServices;
+import org.onap.clamp.clds.config.sdc.BlueprintParserFilesConfiguration;
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;
+import org.onap.clamp.clds.service.CldsService;
+import org.onap.clamp.clds.service.CldsTemplateService;
+import org.onap.clamp.clds.transform.XslTransformer;
 import org.onap.clamp.clds.util.JsonUtils;
 import org.onap.clamp.clds.util.ResourceFileUtil;
+import org.onap.sdc.api.notification.INotificationData;
+import org.onap.sdc.api.notification.IResourceInstance;
+import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
+import org.onap.sdc.toscaparser.api.elements.Metadata;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.Resource;
 
+@RunWith(MockitoJUnitRunner.class)
 public class CsarInstallerImplTest {
 
+    @Mock
+    private CsarHandler csarHandler;
+
+    @Mock
+    private ApplicationContext applicationContext;
+
+    @Mock
+    private DcaeInventoryServices dcaeInventoryServices;
+
+    @Mock
+    private IResourceInstance resourceInstance;
+
+    @Mock
+    private CldsService cldsService;
+
+    @Mock
+    private INotificationData notificationData;
+
+    @Mock
+    private Metadata metadata;
+
+    @Mock
+    private ISdcCsarHelper sdcCsarHelper;
+
+    private CsarInstallerImpl csarInstaller;
+    private BlueprintArtifact artifact;
+
+    /**
+     * Set up method.
+     * throws: Exception
+     */
+    @Before
+    public void setUp() throws Exception {
+        String dceaBlueprint = ResourceFileUtil.getResourceAsString("tosca/dcea_blueprint.yml");
+        artifact = prepareBlueprintArtifact(dceaBlueprint);
+        csarInstaller = new CsarInstallerImpl(applicationContext, new CldsDao(), new CldsTemplateService(),
+                cldsService, dcaeInventoryServices, new XslTransformer());
+    }
+
     @Test
-    public void shouldReturnInputParametersFromBlueprint() throws IOException {
+    public void shouldReturnInputParametersFromBlueprint() {
         //given
         String expectedBlueprintInputsText = "{\"aaiEnrichmentHost\":\"aai.onap.svc.cluster.local\""
-            + ",\"aaiEnrichmentPort\":\"8443\""
-            + ",\"enableAAIEnrichment\":true"
-            + ",\"dmaap_host\":\"message-router\""
-            + ",\"dmaap_port\":\"3904\""
-            + ",\"enableRedisCaching\":false"
-            + ",\"redisHosts\":\"dcae-redis:6379\""
-            + ",\"tag_version\":\"nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.tca-cdap-container:1.1.0\""
-            + ",\"consul_host\":\"consul-server\""
-            + ",\"consul_port\":\"8500\",\"cbs_host\":\"{\\\"test\\\":"
-            + "{\\\"test\\\":\\\"test\\\"}}\",\"cbs_port\":\"10000\""
-            + ",\"external_port\":\"32010\",\"policy_id\":\"AUTO_GENERATED_POLICY_ID_AT_SUBMIT\"}";
+                + ",\"aaiEnrichmentPort\":\"8443\""
+                + ",\"enableAAIEnrichment\":true"
+                + ",\"dmaap_host\":\"message-router\""
+                + ",\"dmaap_port\":\"3904\""
+                + ",\"enableRedisCaching\":false"
+                + ",\"redisHosts\":\"dcae-redis:6379\""
+                + ",\"tag_version\":"
+                + "\"nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.tca-cdap-container:1.1.0\""
+                + ",\"consul_host\":\"consul-server\""
+                + ",\"consul_port\":\"8500\",\"cbs_host\":\"{\\\"test\\\":"
+                + "{\\\"test\\\":\\\"test\\\"}}\",\"cbs_port\":\"10000\""
+                + ",\"external_port\":\"32010\",\"policy_id\":\"AUTO_GENERATED_POLICY_ID_AT_SUBMIT\"}";
 
         JsonObject expectedBlueprintInputs = JsonUtils.GSON.fromJson(expectedBlueprintInputsText, JsonObject.class);
-        String dceaBlueprint = ResourceFileUtil.getResourceAsString("tosca/dcea_blueprint.yml");
-        BlueprintArtifact blueprintArtifact = mock(BlueprintArtifact.class);
-        when(blueprintArtifact.getDcaeBlueprint()).thenReturn(dceaBlueprint);
-        CsarInstallerImpl csarInstaller = new CsarInstallerImpl();
+        //when
+        String parametersInJson = csarInstaller.getAllBlueprintParametersInJson(artifact);
+        //then
+        Assertions.assertThat(JsonUtils.GSON.fromJson(parametersInJson, JsonObject.class))
+                .isEqualTo(expectedBlueprintInputs);
+    }
 
+    @Test
+    public void shouldReturnBuildModelName() throws SdcArtifactInstallerException {
+        //given
+        String expectedModelName = "CLAMP_test_name_"
+                + "vtest_service_version_"
+                + "test_resource_instance_name_"
+                + "test_artifact_name";
+        prepareMockCsarHandler("name", "test_name",
+                "test_service_version");
+        Mockito.when(resourceInstance.getResourceInstanceName()).thenReturn("test_resource_instance_name");
         //when
-        String parametersInJson = csarInstaller.getAllBlueprintParametersInJson(blueprintArtifact);
+        String actualModelName = CsarInstallerImpl.buildModelName(csarHandler, artifact);
+        //then
+        Assertions.assertThat(actualModelName).isEqualTo(expectedModelName);
+    }
+
+    @Test
+    public void shouldReturnRightMapping() throws SdcArtifactInstallerException, IOException {
+        //given
+        String input = "[{\"blueprintKey\":\"tca_k8s\","
+                + "\"dcaeDeployable\":false,"
+                + "\"files\":{\"svgXmlFilePath\":\"samplePath\",\"bpmnXmlFilePath\":\"samplePath\"}}]";
+        BlueprintParserFilesConfiguration filesConfiguration = new BlueprintParserFilesConfiguration();
+        filesConfiguration.setBpmnXmlFilePath("samplePath");
+        filesConfiguration.setSvgXmlFilePath("samplePath");
+        Resource resource = Mockito.mock(Resource.class);
+        InputStream inputStream = IOUtils.toInputStream(input, "UTF-8");
+        Mockito.when(applicationContext.getResource(Mockito.any(String.class))).thenReturn(resource);
+        Mockito.when(resource.getInputStream()).thenReturn(inputStream);
+        csarInstaller.loadConfiguration();
+        //when
+        BlueprintParserFilesConfiguration configuration = csarInstaller.searchForRightMapping(artifact);
 
         //then
-        assertThat(JsonUtils.GSON.fromJson(parametersInJson, JsonObject.class)).isEqualTo(expectedBlueprintInputs);
+        Assertions.assertThat(configuration.getBpmnXmlFilePath()).isEqualTo("samplePath");
+        Assertions.assertThat(configuration.getSvgXmlFilePath()).isEqualTo("samplePath");
+    }
+
+    private BlueprintArtifact prepareBlueprintArtifact(String dceaBlueprint) {
+        artifact = new BlueprintArtifact();
+        artifact.setBlueprintArtifactName("test_artifact_name");
+        artifact.setBlueprintInvariantServiceUuid("test_inv_uuid");
+        artifact.setResourceAttached(resourceInstance);
+        artifact.setDcaeBlueprint(dceaBlueprint);
+        return artifact;
+    }
+
+    private void prepareMockCsarHandler(String metadataNameMockInput, String metadataNameMockOutput,
+                                        String serviceVersion) {
+        Mockito.when(csarHandler.getSdcCsarHelper()).thenReturn(sdcCsarHelper);
+        Mockito.when(sdcCsarHelper.getServiceMetadata()).thenReturn(metadata);
+        Mockito.when(metadata.getValue(metadataNameMockInput)).thenReturn(metadataNameMockOutput);
+        Mockito.when(csarHandler.getSdcNotification()).thenReturn(notificationData);
+        Mockito.when(notificationData.getServiceVersion()).thenReturn(serviceVersion);
     }
 }
\ No newline at end of file
diff --git a/src/test/java/org/onap/clamp/clds/util/XmlToolsTest.java b/src/test/java/org/onap/clamp/clds/util/XmlToolsTest.java
new file mode 100644 (file)
index 0000000..4351a80
--- /dev/null
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.apache.batik.anim.dom.SVGDOMImplementation;
+import org.apache.batik.util.SVGConstants;
+import org.junit.Assert;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class XmlToolsTest {
+
+    @Test
+    public void exportXmlDocumentAsStringTest() throws IOException, ParserConfigurationException, SAXException {
+        String expected = ResourceFileUtil.getResourceAsString("clds/util/file.xml");
+        Document document = parseStringToXmlDocument(expected);
+        String actual = XmlTools.exportXmlDocumentAsString(document);
+        Assert.assertEquals(expected.trim(), actual.trim());
+    }
+
+    @Test
+    public void createEmptySvgDocumentTest() {
+        Document doc = XmlTools.createEmptySvgDocument();
+        Assert.assertEquals(SVGDOMImplementation.SVG_NAMESPACE_URI, doc.getDocumentElement().getNamespaceURI());
+        Assert.assertEquals(SVGConstants.SVG_SVG_TAG, doc.getDocumentElement().getNodeName());
+        Assert.assertNull(doc.getDoctype());
+    }
+
+
+    public static Document parseStringToXmlDocument(String res)
+        throws ParserConfigurationException, SAXException, IOException {
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setValidating(false);
+        dbf.setNamespaceAware(true);
+        dbf.setFeature("http://xml.org/sax/features/namespaces", false);
+        dbf.setFeature("http://xml.org/sax/features/validation", false);
+        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
+        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        InputSource is = new InputSource(new StringReader(res));
+        return db.parse(is);
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java b/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java
new file mode 100644 (file)
index 0000000..477e6a7
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ClampGraphBuilderTest {
+    @Mock
+    private Painter mockPainter;
+
+    @Captor
+    private ArgumentCaptor<String> collectorCaptor;
+
+    @Captor
+    private ArgumentCaptor<List<String>> microServicesCaptor;
+
+    @Captor
+    private ArgumentCaptor<String> policyCaptor;
+
+    @Test
+    public void clampGraphBuilderCompleteChainTest() {
+        String collector = "VES";
+        String ms1 = "ms1";
+        String ms2 = "ms2";
+        String policy = "Policy";
+        List<String> microServices = Arrays.asList(ms1, ms2);
+
+        ClampGraphBuilder clampGraphBuilder = new ClampGraphBuilder(mockPainter);
+        clampGraphBuilder.collector(collector).microService(ms1).microService(ms2).policy(policy).build();
+
+        verify(mockPainter, times(1))
+            .doPaint(collectorCaptor.capture(), microServicesCaptor.capture(), policyCaptor.capture());
+
+        Assert.assertEquals(collector, collectorCaptor.getValue());
+        Assert.assertEquals(microServices, microServicesCaptor.getValue());
+        Assert.assertEquals(policy, policyCaptor.getValue());
+    }
+
+    @Test(expected = InvalidStateException.class)
+    public void clampGraphBuilderNoPolicyGivenTest() {
+        String collector = "VES";
+        String ms1 = "ms1";
+        String ms2 = "ms2";
+
+        ClampGraphBuilder clampGraphBuilder = new ClampGraphBuilder(mockPainter);
+        clampGraphBuilder.collector(collector).microService(ms1).microService(ms2).build();
+    }
+
+    @Test(expected = InvalidStateException.class)
+    public void clampGraphBuilderNoMicroServiceGivenTest() {
+        String collector = "VES";
+        String policy = "Policy";
+
+        ClampGraphBuilder clampGraphBuilder = new ClampGraphBuilder(mockPainter);
+        clampGraphBuilder.collector(collector).policy(policy).build();
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphTest.java b/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphTest.java
new file mode 100644 (file)
index 0000000..6bbebdf
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import javax.xml.parsers.ParserConfigurationException;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.clamp.clds.util.ResourceFileUtil;
+import org.onap.clamp.clds.util.XmlToolsTest;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ClampGraphTest {
+    @Mock
+    private DocumentBuilder mockDocumentBuilder;
+
+    @Test
+    public void getAsSVGTest() throws IOException, ParserConfigurationException, SAXException {
+        String expected = ResourceFileUtil.getResourceAsString("clds/util/file.xml");
+        Document document = XmlToolsTest.parseStringToXmlDocument(expected);
+
+        when(mockDocumentBuilder.getGroupingDocument()).thenReturn(document);
+
+        String actual = new ClampGraph(mockDocumentBuilder).getAsSVG();
+        Assert.assertEquals(expected.trim(), actual.trim());
+    }
+
+    @Test
+    public void getAsSVGLazyTest() throws IOException, ParserConfigurationException, SAXException {
+        String expected = ResourceFileUtil.getResourceAsString("clds/util/file.xml");
+        Document document = XmlToolsTest.parseStringToXmlDocument(expected);
+
+        when(mockDocumentBuilder.getGroupingDocument()).thenReturn(document);
+        ClampGraph cg = new ClampGraph(mockDocumentBuilder);
+
+        String actualFirst = cg.getAsSVG();
+        verify(mockDocumentBuilder, times(1)).getGroupingDocument();
+
+        String actualSecond = cg.getAsSVG();
+        verifyNoMoreInteractions(mockDocumentBuilder);
+
+        Assert.assertEquals(expected.trim(), actualFirst.trim());
+        Assert.assertEquals(expected.trim(), actualSecond.trim());
+
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/clamp/clds/util/drawing/DocumentBuilderTest.java b/src/test/java/org/onap/clamp/clds/util/drawing/DocumentBuilderTest.java
new file mode 100644 (file)
index 0000000..6546553
--- /dev/null
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util.drawing;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import javax.xml.parsers.ParserConfigurationException;
+import org.apache.batik.svggen.SVGGraphics2D;
+import org.apache.batik.util.SVGConstants;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.clamp.clds.util.ResourceFileUtil;
+import org.onap.clamp.clds.util.XmlToolsTest;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DocumentBuilderTest {
+    @Mock
+    private SVGGraphics2D mockG2d;
+
+    @Mock
+    private Document mockDomImpl;
+
+    @Test
+    public void pushChangestoDocumentTest() throws IOException, ParserConfigurationException, SAXException {
+        String dataElementId = "someId";
+        String newNodeTag = "tagged";
+        String newNodeText = "Sample text";
+        String xml = ResourceFileUtil.getResourceAsString("clds/util/file.xml");
+        Document document = XmlToolsTest.parseStringToXmlDocument(xml);
+        Node newNode = document.createElement(newNodeTag);
+        newNode.appendChild(document.createTextNode(newNodeText));
+
+        when(mockG2d.getRoot(any(Element.class))).then(a -> a.getArgumentAt(0, Element.class).appendChild(newNode));
+
+        DocumentBuilder db = new DocumentBuilder(document, document);
+        db.pushChangestoDocument(mockG2d, dataElementId);
+        Document actualDocument = db.getGroupingDocument();
+
+        Node addedActualNode = actualDocument.getDocumentElement().getLastChild();
+        String actualDataElementId =
+            addedActualNode.getAttributes().getNamedItem(DocumentBuilder.DATA_ELEMENT_ID_ATTRIBUTE).getTextContent();
+
+        Assert.assertEquals(dataElementId, actualDataElementId);
+        Assert.assertEquals(SVGConstants.SVG_G_TAG, addedActualNode.getNodeName());
+
+        Node addedActualNodeChild = addedActualNode.getLastChild();
+        Assert.assertEquals(newNodeTag, addedActualNodeChild.getNodeName());
+        Assert.assertEquals(newNodeText, addedActualNodeChild.getTextContent());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/clamp/loop/CsarInstallerItCase.java b/src/test/java/org/onap/clamp/loop/CsarInstallerItCase.java
new file mode 100644 (file)
index 0000000..d1a4bdc
--- /dev/null
@@ -0,0 +1,178 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 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============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.loop;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.transaction.Transactional;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.json.JSONException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.onap.clamp.clds.Application;
+import org.onap.clamp.clds.exception.policy.PolicyModelException;
+import org.onap.clamp.clds.exception.sdc.controller.CsarHandlerException;
+import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;
+import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact;
+import org.onap.clamp.clds.sdc.controller.installer.CsarHandler;
+import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller;
+import org.onap.clamp.clds.util.ResourceFileUtil;
+import org.onap.sdc.api.notification.INotificationData;
+import org.onap.sdc.api.notification.IResourceInstance;
+import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
+import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException;
+import org.onap.sdc.tosca.parser.impl.SdcToscaParserFactory;
+import org.onap.sdc.toscaparser.api.elements.Metadata;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Application.class)
+@ActiveProfiles(profiles = "clamp-default,clamp-default-user,clamp-sdc-controller-new")
+public class CsarInstallerItCase {
+
+    private static final String CSAR_ARTIFACT_NAME = "example/sdc/service-Simsfoimap0112.csar";
+    private static final String INVARIANT_SERVICE_UUID = "4cc5b45a-1f63-4194-8100-cd8e14248c92";
+    private static final String INVARIANT_RESOURCE1_UUID = "07e266fc-49ab-4cd7-8378-ca4676f1b9ec";
+    private static final String INVARIANT_RESOURCE2_UUID = "023a3f0d-1161-45ff-b4cf-8918a8ccf3ad";
+    private static final String RESOURCE_INSTANCE_NAME_RESOURCE1 = "ResourceInstanceName1";
+    private static final String RESOURCE_INSTANCE_NAME_RESOURCE2 = "ResourceInstanceName2";
+
+    @Autowired
+    private LoopsRepository loopsRepo;
+
+    @Autowired
+    private CsarInstaller csarInstaller;
+
+    private BlueprintArtifact buildFakeBuildprintArtifact(String instanceName, String invariantResourceUuid,
+        String blueprintFilePath, String artifactName, String invariantServiceUuid) throws IOException {
+        IResourceInstance resource = Mockito.mock(IResourceInstance.class);
+        Mockito.when(resource.getResourceInstanceName()).thenReturn(instanceName);
+        Mockito.when(resource.getResourceInvariantUUID()).thenReturn(invariantResourceUuid);
+        BlueprintArtifact blueprintArtifact = Mockito.mock(BlueprintArtifact.class);
+        Mockito.when(blueprintArtifact.getDcaeBlueprint())
+            .thenReturn(ResourceFileUtil.getResourceAsString(blueprintFilePath));
+        Mockito.when(blueprintArtifact.getBlueprintArtifactName()).thenReturn(artifactName);
+        Mockito.when(blueprintArtifact.getBlueprintInvariantServiceUuid()).thenReturn(invariantServiceUuid);
+        Mockito.when(blueprintArtifact.getResourceAttached()).thenReturn(resource);
+        return blueprintArtifact;
+    }
+
+    private CsarHandler buildFakeCsarHandler(String generatedName) throws IOException, SdcToscaParserException {
+        // Create fake notification
+        INotificationData notificationData = Mockito.mock(INotificationData.class);
+        Mockito.when(notificationData.getServiceVersion()).thenReturn("1.0");
+        // Create fake resource in notification
+        CsarHandler csarHandler = Mockito.mock(CsarHandler.class);
+        List<IResourceInstance> listResources = new ArrayList<>();
+        Mockito.when(notificationData.getResources()).thenReturn(listResources);
+        Map<String, BlueprintArtifact> blueprintMap = new HashMap<>();
+        Mockito.when(csarHandler.getMapOfBlueprints()).thenReturn(blueprintMap);
+        // Create fake blueprint artifact 1 on resource1
+        BlueprintArtifact blueprintArtifact = buildFakeBuildprintArtifact(RESOURCE_INSTANCE_NAME_RESOURCE1,
+            INVARIANT_RESOURCE1_UUID, "example/sdc/blueprint-dcae/tca.yaml", "tca.yaml", INVARIANT_SERVICE_UUID);
+        listResources.add(blueprintArtifact.getResourceAttached());
+        blueprintMap.put(blueprintArtifact.getBlueprintArtifactName(), blueprintArtifact);
+        // Create fake blueprint artifact 2 on resource2
+        blueprintArtifact = buildFakeBuildprintArtifact(RESOURCE_INSTANCE_NAME_RESOURCE2, INVARIANT_RESOURCE2_UUID,
+            "example/sdc/blueprint-dcae/tca_2.yaml", "tca_2.yaml", INVARIANT_SERVICE_UUID);
+        listResources.add(blueprintArtifact.getResourceAttached());
+        blueprintMap.put(blueprintArtifact.getBlueprintArtifactName(), blueprintArtifact);
+
+        // Create fake blueprint artifact 3 on resource 1 so that it's possible to
+        // test multiple CL deployment per Service/vnf
+        blueprintArtifact = buildFakeBuildprintArtifact(RESOURCE_INSTANCE_NAME_RESOURCE1, INVARIANT_RESOURCE1_UUID,
+            "example/sdc/blueprint-dcae/tca_3.yaml", "tca_3.yaml", INVARIANT_SERVICE_UUID);
+        blueprintMap.put(blueprintArtifact.getBlueprintArtifactName(), blueprintArtifact);
+
+        // Build fake csarhandler
+        Mockito.when(csarHandler.getSdcNotification()).thenReturn(notificationData);
+        // Build fake csar Helper
+        ISdcCsarHelper csarHelper = Mockito.mock(ISdcCsarHelper.class);
+        Metadata data = Mockito.mock(Metadata.class);
+        Mockito.when(data.getValue("name")).thenReturn(generatedName);
+        Mockito.when(notificationData.getServiceName()).thenReturn(generatedName);
+        Mockito.when(csarHelper.getServiceMetadata()).thenReturn(data);
+
+        // Create helper based on real csar to test policy yaml and global properties
+        // set
+        SdcToscaParserFactory factory = SdcToscaParserFactory.getInstance();
+        ISdcCsarHelper sdcHelper = factory
+            .getSdcCsarHelper(Thread.currentThread().getContextClassLoader().getResource(CSAR_ARTIFACT_NAME).getFile());
+        Mockito.when(csarHandler.getSdcCsarHelper()).thenReturn(sdcHelper);
+
+        // Mockito.when(csarHandler.getSdcCsarHelper()).thenReturn(csarHelper);
+        Mockito.when(csarHandler.getPolicyModelYaml())
+            .thenReturn(Optional.ofNullable(ResourceFileUtil.getResourceAsString("tosca/tca-policy-test.yaml")));
+        return csarHandler;
+    }
+
+    @Test
+    @Transactional
+    public void testIsCsarAlreadyDeployedTca() throws SdcArtifactInstallerException, SdcToscaParserException,
+        CsarHandlerException, IOException, InterruptedException, PolicyModelException {
+        String generatedName = RandomStringUtils.randomAlphanumeric(5);
+        CsarHandler csarHandler = buildFakeCsarHandler(generatedName);
+        assertThat(csarInstaller.isCsarAlreadyDeployed(csarHandler)).isFalse();
+        csarInstaller.installTheCsar(csarHandler);
+        assertThat(csarInstaller.isCsarAlreadyDeployed(csarHandler)).isTrue();
+    }
+
+    @Test
+    @Transactional
+    public void testInstallTheCsarTca() throws SdcArtifactInstallerException, SdcToscaParserException,
+        CsarHandlerException, IOException, JSONException, InterruptedException, PolicyModelException {
+        String generatedName = RandomStringUtils.randomAlphanumeric(5);
+        CsarHandler csar = buildFakeCsarHandler(generatedName);
+        csarInstaller.installTheCsar(csar);
+        assertThat(loopsRepo
+            .existsById(Loop.generateLoopName(generatedName, "1.0", RESOURCE_INSTANCE_NAME_RESOURCE1, "tca.yaml")))
+                .isTrue();
+        assertThat(loopsRepo
+            .existsById(Loop.generateLoopName(generatedName, "1.0", RESOURCE_INSTANCE_NAME_RESOURCE1, "tca_3.yaml")))
+                .isTrue();
+        assertThat(loopsRepo
+            .existsById(Loop.generateLoopName(generatedName, "1.0", RESOURCE_INSTANCE_NAME_RESOURCE2, "tca_2.yaml")))
+                .isTrue();
+        // Verify now that policy and json representation, global properties are well
+        // set
+        Loop loop = loopsRepo
+            .findById(Loop.generateLoopName(generatedName, "1.0", RESOURCE_INSTANCE_NAME_RESOURCE1, "tca.yaml")).get();
+
+        assertThat(loop.getModelPropertiesJson().get("serviceDetails")).isNotNull();
+        assertThat(loop.getModelPropertiesJson().get("resourceDetails")).isNotNull();
+    }
+
+}
index a9c3087..b7781bf 100644 (file)
@@ -70,7 +70,7 @@ public class LoopServiceTestItCase {
         testLoop.setLastComputedState(LoopState.DESIGN);
 
         //when
-        Loop actualLoop = loopService.addNewLoop(testLoop);
+        Loop actualLoop = loopService.saveOrUpdateLoop(testLoop);
 
         //then
         assertThat(actualLoop).isNotNull();
@@ -166,7 +166,7 @@ public class LoopServiceTestItCase {
     private void saveTestLoopToDb() {
         Loop testLoop = createTestLoop(EXAMPLE_LOOP_NAME, "blueprint", "representation");
         testLoop.setGlobalPropertiesJson(JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class));
-        loopService.addNewLoop(testLoop);
+        loopService.saveOrUpdateLoop(testLoop);
     }
 
     @Test
index 49ed897..e15b873 100644 (file)
@@ -62,7 +62,7 @@ server.port=${clamp.it.tests.http}
 \r
 server.servlet.context-path=/\r
 #Modified engine-rest applicationpath\r
-spring.profiles.active=clamp-default,clamp-default-user,clamp-sdc-controller\r
+spring.profiles.active=clamp-default,clamp-default-user\r
 spring.http.converters.preferred-json-mapper=gson\r
 \r
 #The max number of active threads in this pool\r
diff --git a/src/test/resources/clds/util/file.xml b/src/test/resources/clds/util/file.xml
new file mode 100644 (file)
index 0000000..81560ba
--- /dev/null
@@ -0,0 +1,6 @@
+<note>
+  <to>Tove</to>
+  <from>Jani</from>
+  <heading>Reminder</heading>
+  <body>Message body</body>
+</note>
index ea0e44a..8c16d31 100644 (file)
Binary files a/src/test/resources/example/sdc/service-Simsfoimap0112.csar and b/src/test/resources/example/sdc/service-Simsfoimap0112.csar differ