Additional code for Tosca 00/74100/6
authorsebdet <sebastien.determe@intl.att.com>
Sat, 1 Dec 2018 14:09:54 +0000 (15:09 +0100)
committersebdet <sebastien.determe@intl.att.com>
Wed, 5 Dec 2018 12:18:19 +0000 (13:18 +0100)
Tosca code for policy dynamic configuration

Issue-ID: CLAMP-252,CLAMP-251
Change-Id: Icd96f833567050c1dd4730a61765507ad24ebd2e
Signed-off-by: sebdet <sebastien.determe@intl.att.com>
27 files changed:
pom.xml
src/main/java/org/onap/clamp/clds/client/OperationalPolicyDeleteDelegate.java
src/main/java/org/onap/clamp/clds/client/req/policy/PolicyClient.java
src/main/java/org/onap/clamp/clds/config/ClampProperties.java
src/main/java/org/onap/clamp/clds/dao/CldsDao.java
src/main/java/org/onap/clamp/clds/exception/BadRequestException.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/exception/NotAuthorizedException.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsMonitoringDetails.java
src/main/java/org/onap/clamp/clds/model/CldsToscaModel.java
src/main/java/org/onap/clamp/clds/service/CldsDictionaryService.java
src/main/java/org/onap/clamp/clds/service/CldsToscaService.java
src/main/java/org/onap/clamp/clds/tosca/JsonEditorSchemaConstants.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/tosca/ToscaSchemaConstants.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyAttributesConstructorTest.java
src/test/java/org/onap/clamp/clds/it/CldsDictionaryServiceItCase.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/it/CldsServiceItCase.java
src/test/java/org/onap/clamp/clds/it/CldsToscaServiceItCase.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/it/config/CldsReferencePropertiesItCase.java
src/test/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertorTest.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/util/JacksonUtilsTest.java
src/test/resources/clds/camel/routes/flexible-flow.xml [new file with mode: 0644]
src/test/resources/example/json-editor-schema/tca-policy-json-editor-schema.json [new file with mode: 0644]
src/test/resources/http-cache/start_http_cache.sh
src/test/resources/http-cache/third_party_proxy.py
src/test/resources/tosca/tca-policy-test.yaml [new file with mode: 0644]
src/test/resources/tosca/tosca_example.yaml [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index ad55012..124bee4 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                                <dependency>
                                                <groupId>org.onap.policy.engine</groupId>
                                                <artifactId>PolicyEngineAPI</artifactId>
-                                               <version>1.3.1</version>
+                                               <version>1.3.3</version>
                                                <exclusions>
                                                                <exclusion>
                                                                                <groupId>com.google.guava</groupId>
                                                                <artifactId>maven-surefire-plugin</artifactId>
                                                                <version>2.22.1</version>
                                                                <configuration>
-                                                                               <forkCount>1</forkCount>
+                                                                               <forkCount>1C</forkCount>
                                                                                <reuseForks>true</reuseForks>
                                                                                <useSystemClassLoader>false</useSystemClassLoader>
                                                                </configuration>
                                                                                                                                <include>**/*ItCase.java</include>
                                                                                                                </includes>
                                                                                                                <forkCount>1</forkCount>
-                                                                                                               <reuseForks>false</reuseForks>
+                                                                                                               <reuseForks>true</reuseForks>
                                                                                                                <useSystemClassLoader>false</useSystemClassLoader>
                                                                                                </configuration>
                                                                                </execution>
                                                                <groupId>io.fabric8</groupId>
                                                                <artifactId>docker-maven-plugin</artifactId>
                                                                <version>0.27.2</version>
+                                                               <dependencies>
+                                                                       <dependency>
+                                                                               <groupId>org.apache.httpcomponents</groupId>
+                                                                               <artifactId>httpclient</artifactId>
+                                                                               <version>4.5.5</version>
+                                                                       </dependency>
+                                                               </dependencies>
                                                                <configuration>
                                                                                <verbose>true</verbose>
                                                                                <apiVersion>1.35</apiVersion>
                                                                                                                                                                <mode>direct</mode>
                                                                                                                                                </tcp>
                                                                                                                                                <time>120000</time>
+                                                                                                                                               <kill>5000</kill>
                                                                                                                                </wait>
                                                                                                                                <ports>
                                                                                                                                                <port>${docker.http-cache.port.host}:8080</port>
index 5a983b7..adec94f 100644 (file)
@@ -52,7 +52,7 @@ public class OperationalPolicyDeleteDelegate {
      * Perform activity. Delete Operational Policy via policy api.
      *
      * @param camelExchange
-     *            The Camel Exchange object containing the properties
+     *        The Camel Exchange object containing the properties
      */
     @Handler
     public void execute(Exchange camelExchange) {
@@ -60,19 +60,12 @@ public class OperationalPolicyDeleteDelegate {
         Policy policy = prop.getType(Policy.class);
         prop.setCurrentModelElementId(policy.getId());
         String eventAction = (String) camelExchange.getProperty("eventAction");
-        if(policy.getPolicyChains() != null && policy.getPolicyChains().size() > 0) {
-               String responseMessage = "";
-            
-            if (!eventAction.equalsIgnoreCase(CldsEvent.ACTION_CREATE) && policy.isFound()) {
-                for (PolicyChain policyChain : policy.getPolicyChains()) {
-                    prop.setPolicyUniqueId(policyChain.getPolicyId());
-                    responseMessage = policyClient.deleteBrms(prop);
-                }
-                if (responseMessage != null) {
-                    camelExchange.setProperty("operationalPolicyDeleteResponseMessage", responseMessage.getBytes());
-                }
+        if (policy.getPolicyChains() != null && !policy.getPolicyChains().isEmpty()
+            && !eventAction.equalsIgnoreCase(CldsEvent.ACTION_CREATE) && policy.isFound()) {
+            for (PolicyChain policyChain : policy.getPolicyChains()) {
+                prop.setPolicyUniqueId(policyChain.getPolicyId());
+                logger.info("Policy Delete response: " + policyClient.deleteBrms(prop));
             }
         }
-        
     }
 }
index c26b15c..610bd4c 100644 (file)
@@ -26,6 +26,11 @@ package org.onap.clamp.clds.client.req.policy;
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
 
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Map;
@@ -36,6 +41,7 @@ import javax.ws.rs.BadRequestException;
 import org.onap.clamp.clds.config.ClampProperties;
 import org.onap.clamp.clds.config.PolicyConfiguration;
 import org.onap.clamp.clds.exception.policy.PolicyClientException;
+import org.onap.clamp.clds.model.CldsToscaModel;
 import org.onap.clamp.clds.model.properties.ModelProperties;
 import org.onap.clamp.clds.model.properties.PolicyItem;
 import org.onap.clamp.clds.util.LoggingUtils;
@@ -44,6 +50,8 @@ import org.onap.policy.api.ConfigRequestParameters;
 import org.onap.policy.api.DeletePolicyCondition;
 import org.onap.policy.api.DeletePolicyParameters;
 import org.onap.policy.api.DictionaryType;
+import org.onap.policy.api.ImportParameters;
+import org.onap.policy.api.ImportParameters.IMPORT_TYPE;
 import org.onap.policy.api.PolicyChangeResponse;
 import org.onap.policy.api.PolicyClass;
 import org.onap.policy.api.PolicyConfigException;
@@ -77,6 +85,7 @@ public class PolicyClient {
     public static final String POLICY_MS_NAME_PREFIX_PROPERTY_NAME = "policy.ms.policyNamePrefix";
     public static final String POLICY_OP_TYPE_PROPERTY_NAME = "policy.op.type";
     public static final String POLICY_GUARD_SUFFIX = "_Guard";
+    public static final String TOSCA_FILE_TEMP_PATH = "tosca.filePath";
 
     @Autowired
     protected ApplicationContext appContext;
@@ -572,4 +581,81 @@ public class PolicyClient {
         }
         return responseMessage;
     }
+
+    /**
+     * Create a temp Tosca model file and perform import model to Policy Engine
+     *
+     * @param cldsToscaModel
+     *        Policy model details
+     * @return The response message from policy
+     */
+    public String importToscaModel(CldsToscaModel cldsToscaModel) {
+        String filePath = "";
+        try {
+            String clampToscaPath = refProp.getStringValue(TOSCA_FILE_TEMP_PATH);
+            filePath = buildFilePathForToscaFile(clampToscaPath, cldsToscaModel.getToscaModelName());
+            logger.info("Writing Tosca model : " + filePath);
+            Path path = Paths.get(filePath);
+            Files.createDirectories(path.getParent());
+            // Create or Ovewrite an existing the file
+            try (OutputStream out = Files.newOutputStream(path)) {
+                out.write(cldsToscaModel.getToscaModelYaml().getBytes(), 0,
+                    cldsToscaModel.getToscaModelYaml().getBytes().length);
+            }
+        } catch (IOException e) {
+            logger.error("Exception caught when attempting to write Tosca files to disk", e);
+            throw new PolicyClientException("Exception caught when attempting to write Tosca files to disk", e);
+        }
+
+        ImportParameters importParameters = new ImportParameters();
+        importParameters.setImportParameters(cldsToscaModel.getToscaModelName(), cldsToscaModel.getToscaModelName(),
+            null, filePath, IMPORT_TYPE.MICROSERVICE, String.valueOf(cldsToscaModel.getVersion()));
+        return importModel(importParameters);
+    }
+
+    /**
+     * @param importParameters
+     *        The ImportParameters
+     * @return The response message from policy
+     */
+    protected String importModel(ImportParameters importParameters) {
+        PolicyChangeResponse response = null;
+        String responseMessage = "";
+
+        try {
+            logger.info("Attempting to import tosca policy model for action=" + importParameters.getFilePath());
+            response = getPolicyEngine().policyEngineImport(importParameters);
+            if (response != null) {
+                responseMessage = response.getResponseMessage();
+            }
+        } catch (Exception e) {
+            LoggingUtils.setResponseContext("900", "Policy Model import failed", this.getClass().getName());
+            LoggingUtils.setErrorContext("900", "Policy Model import error");
+            logger.error("Exception occurred during policy communication", e);
+            throw new PolicyClientException("Exception while communicating with Policy", e);
+        }
+        logger.info(LOG_POLICY_PREFIX + responseMessage);
+        if (response != null && (response.getResponseCode() == 200 || response.getResponseCode() == 204)) {
+            LoggingUtils.setResponseContext("0", "Policy Model import success", this.getClass().getName());
+            logger.info("Policy import model successful");
+            metricsLogger.info("Policy import model success");
+        } else {
+            LoggingUtils.setResponseContext("900", "Policy import model failed", this.getClass().getName());
+            logger.warn("Policy import model failed: " + responseMessage);
+            metricsLogger.info("Policy import model failure");
+            throw new BadRequestException("Policy import model failed: " + responseMessage);
+        }
+        return responseMessage;
+    }
+
+    /**
+     * @param clampToscaPath
+     *        Temp directory path for writing tosca files
+     * @param toscaModelName
+     *        Tosca Model Name
+     * @return File Path on the system
+     */
+    private String buildFilePathForToscaFile(String clampToscaPath, String toscaModelName) {
+        return clampToscaPath + "/" + toscaModelName + ".yml";
+    }
 }
\ No newline at end of file
index 7c6c6ff..9acad94 100644 (file)
@@ -18,7 +18,7 @@
  * limitations under the License.
  * ============LICENSE_END============================================
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.config;
@@ -49,14 +49,12 @@ public class ClampProperties {
     @Autowired
     private Environment env;
     public static final String CONFIG_PREFIX = "clamp.config.";
-    public static final String TOSCA_POLICY_TYPES_CONFIG= "tosca.policyTypes";
-    public static final String IMPORT_TOSCA_POLICY= "import.tosca.model";
 
     /**
      * get property value.
      *
      * @param key
-     *            The first key
+     *        The first key
      * @return The string with the value
      */
     public String getStringValue(String key) {
@@ -64,13 +62,13 @@ public class ClampProperties {
     }
 
     /**
-     * get property value for a combo key (key1 + "." + key2). If not found just
-     * use key1.
+     * get property value for a combo key (key1 + "." + key2). If not found just use
+     * key1.
      *
      * @param key1
-     *            The first key
+     *        The first key
      * @param key2
-     *            The second key after a dot
+     *        The second key after a dot
      * @return The string with the value
      */
     public String getStringValue(String key1, String key2) {
@@ -86,49 +84,47 @@ public class ClampProperties {
      * clds-reference file will be used as a filename.
      *
      * @param key
-     *            The key that will be used to access the clds-reference file
+     *        The key that will be used to access the clds-reference file
      * @return A jsonNode
      * @throws IOException
-     *             In case of issues with the JSON parser
+     *         In case of issues with the JSON parser
      */
     public JsonNode getJsonTemplate(String key) throws IOException {
         String fileReference = getStringValue(key);
         return (fileReference != null)
-                ? JacksonUtils.getObjectMapperInstance().readValue(getFileContentFromPath(fileReference),
-                        JsonNode.class)
-                : null;
+            ? JacksonUtils.getObjectMapperInstance().readValue(getFileContentFromPath(fileReference), JsonNode.class)
+            : null;
     }
 
     /**
-     * Return json as objects that can be updated. First try with combo key
-     * (key1 + "." + key2), otherwise default to just key1. The value obtained
-     * from the clds-reference file will be used as a filename.
+     * Return json as objects that can be updated. First try with combo key (key1 +
+     * "." + key2), otherwise default to just key1. The value obtained from the
+     * clds-reference file will be used as a filename.
      *
      * @param key1
-     *            The first key
+     *        The first key
      * @param key2
-     *            The second key after a dot
+     *        The second key after a dot
      * @return A JsonNode
      * @throws IOException
-     *             In case of issues with the JSON parser
+     *         In case of issues with the JSON parser
      */
     public JsonNode getJsonTemplate(String key1, String key2) throws IOException {
         String fileReference = getStringValue(key1, key2);
         return (fileReference != null)
-                ? JacksonUtils.getObjectMapperInstance().readValue(getFileContentFromPath(fileReference),
-                        JsonNode.class)
-                : null;
+            ? JacksonUtils.getObjectMapperInstance().readValue(getFileContentFromPath(fileReference), JsonNode.class)
+            : null;
     }
 
     /**
-     * Return the file content. The value obtained from the clds-reference file
-     * will be used as a filename.
+     * Return the file content. The value obtained from the clds-reference file will
+     * be used as a filename.
      *
      * @param key
-     *            The key that will be used to access the clds-reference file
+     *        The key that will be used to access the clds-reference file
      * @return File content in String
      * @throws IOException
-     *             In case of issues with the JSON parser
+     *         In case of issues with the JSON parser
      */
     public String getFileContent(String key) throws IOException {
         String fileReference = getStringValue(key);
@@ -137,16 +133,16 @@ public class ClampProperties {
 
     /**
      * Return the file content. First try with combo key (key1 + "." + key2),
-     * otherwise default to just key1. The value obtained from the
-     * clds-reference file will be used as a filename.
+     * otherwise default to just key1. The value obtained from the clds-reference
+     * file will be used as a filename.
      *
      * @param key1
-     *            The first key
+     *        The first key
      * @param key2
-     *            The second key after a dot
+     *        The second key after a dot
      * @return File content in String
      * @throws IOException
-     *             In case of issues with the JSON parser
+     *         In case of issues with the JSON parser
      */
     public String getFileContent(String key1, String key2) throws IOException {
         String fileReference = getStringValue(key1, key2);
@@ -157,19 +153,18 @@ public class ClampProperties {
         URL url = appContext.getResource(filepath).getURL();
         return IOUtils.toString(url, StandardCharsets.UTF_8);
     }
-    
-       /**
-        * 
-        * 
-        * @param key
-        *       property key
-        * @param separator
-        *       property value separator
-        * @return
-        *       List of Strings split with a separator
-        */
-       public List<String> getStringList(String key, String separator) {
-               return Splitter.on(separator).trimResults().omitEmptyStrings()
-                               .splitToList(env.getProperty(CONFIG_PREFIX + key));
-       }
+
+    /**
+     * 
+     * 
+     * @param key
+     *        property key
+     * @param separator
+     *        property value separator
+     * @return List of Strings split with a separator
+     */
+    public List<String> getStringList(String key, String separator) {
+        return Splitter.on(separator).trimResults().omitEmptyStrings()
+            .splitToList(env.getProperty(CONFIG_PREFIX + key));
+    }
 }
index 121114b..b6e27c5 100644 (file)
@@ -29,13 +29,9 @@ import com.att.eelf.configuration.EELFManager;
 import java.io.InputStream;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
 
 import javax.sql.DataSource;
 
@@ -515,32 +511,34 @@ public class CldsDao {
     private List<CldsToscaModel> getToscaModel(String toscaModelName, String policyType) {
         SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
         List<CldsToscaModel> cldsToscaModels = new ArrayList<>();
-        MapSqlParameterSource params = new MapSqlParameterSource();
 
-        String toscaModelSql = "SELECT tm.tosca_model_name, tm.tosca_model_id, tm.policy_type, tmr.tosca_model_revision_id, tmr.version, tmr.user_id, tmr.createdTimestamp, tmr.lastUpdatedTimestamp, tmr.tosca_model_yaml FROM tosca_model tm, tosca_model_revision tmr WHERE tm.tosca_model_id = tmr.tosca_model_id ";
-        if (toscaModelName != null) {
-            toscaModelSql += " AND tm.tosca_model_name = :toscaModelName";
-            params.addValue("toscaModelName", toscaModelName);
-        }
-        if (policyType != null) {
-            toscaModelSql += " AND tm.policy_type = :policyType";
-            params.addValue("policyType", policyType);
-        }
-        toscaModelSql += " AND tmr.version = (select max(version) from tosca_model_revision st where tmr.tosca_model_id=st.tosca_model_id)";
+        String toscaModelSql = "SELECT tm.tosca_model_name, tm.tosca_model_id, tm.policy_type, tmr.tosca_model_revision_id, tmr.tosca_model_json, tmr.version, tmr.user_id, tmr.createdTimestamp, tmr.lastUpdatedTimestamp "
+            + ((toscaModelName != null) ? (", tmr.tosca_model_yaml ") : " ")
+            + "FROM tosca_model tm, tosca_model_revision tmr WHERE tm.tosca_model_id = tmr.tosca_model_id "
+            + ((toscaModelName != null) ? (" AND tm.tosca_model_name = '" + toscaModelName + "'") : " ")
+            + ((policyType != null) ? (" AND tm.policy_type = '" + policyType + "'") : " ")
+            + "AND tmr.version = (select max(version) from tosca_model_revision st where tmr.tosca_model_id=st.tosca_model_id)";
+
+        List<Map<String, Object>> rows = jdbcTemplateObject.queryForList(toscaModelSql);
 
-        Optional.ofNullable(jdbcTemplateObject.queryForList(toscaModelSql, params)).orElse(Collections.emptyList())
-            .forEach(row -> {
+        if (rows != null) {
+            rows.forEach(row -> {
                 CldsToscaModel cldsToscaModel = new CldsToscaModel();
                 cldsToscaModel.setId((String) row.get("tosca_model_id"));
                 cldsToscaModel.setPolicyType((String) row.get("policy_type"));
                 cldsToscaModel.setToscaModelName((String) row.get("tosca_model_name"));
                 cldsToscaModel.setUserId((String) row.get("user_id"));
                 cldsToscaModel.setRevisionId((String) row.get("tosca_model_revision_id"));
+                cldsToscaModel.setToscaModelJson((String) row.get("tosca_model_json"));
                 cldsToscaModel.setVersion(((Double) row.get("version")));
                 cldsToscaModel.setCreatedDate(sdf.format(row.get("createdTimestamp")));
-                cldsToscaModel.setToscaModelYaml((String) row.get("tosca_model_yaml"));
+                cldsToscaModel.setLastUpdatedDate(sdf.format(row.get("lastUpdatedTimestamp")));
+                if (toscaModelName != null) {
+                    cldsToscaModel.setToscaModelYaml((String) row.get("tosca_model_yaml"));
+                }
                 cldsToscaModels.add(cldsToscaModel);
             });
+        }
         return cldsToscaModels;
     }
 
@@ -604,11 +602,10 @@ public class CldsDao {
      * @param userId
      */
     public void updateDictionary(String dictionaryId, CldsDictionary cldsDictionary, String userId) {
-        String dictionarySql = "UPDATE dictionary SET dictionary_name = :dictionary_name, modified_by = :modified_by WHERE dictionary_id = :dictionary_id";
-        SqlParameterSource namedParameters = new MapSqlParameterSource()
-            .addValue("dictionary_name", cldsDictionary.getDictionaryName()).addValue("modified_by", userId)
-            .addValue("dictionary_id", dictionaryId);
-        jdbcTemplateObject.update(dictionarySql, namedParameters);
+
+        String dictionarySql = "UPDATE dictionary " + "SET dictionary_name = '" + cldsDictionary.getDictionaryName()
+            + "', modified_by = '" + userId + "'" + "WHERE dictionary_id = '" + dictionaryId + "'";
+        jdbcTemplateObject.update(dictionarySql);
         cldsDictionary.setUpdatedBy(userId);
     }
 
@@ -622,16 +619,17 @@ public class CldsDao {
     public List<CldsDictionary> getDictionary(String dictionaryId, String dictionaryName) {
         SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
         List<CldsDictionary> dictionaries = new ArrayList<>();
-        String dictionarySql = "SELECT dictionary_id, dictionary_name, created_by, modified_by, timestamp FROM dictionary WHERE ";
-        MapSqlParameterSource namedParameters = new MapSqlParameterSource();
-        Optional.ofNullable(dictionaryName).ifPresent(dn -> namedParameters.addValue("dictionary_name", dn));
-        Optional.ofNullable(dictionaryId).ifPresent(dn -> namedParameters.addValue("dictionary_id", dn));
-        dictionarySql += Optional.ofNullable(namedParameters.getParameterNames()).filter(a -> a.length > 0)
-            .map(Arrays::stream).map(s -> s.map(param -> param + " = :" + param).collect(Collectors.joining(" AND ")))
-            .orElse("1");
-
-        Optional.ofNullable(jdbcTemplateObject.queryForList(dictionarySql, namedParameters))
-            .orElse(Collections.emptyList()).forEach(row -> {
+        String dictionarySql = "SELECT dictionary_id, dictionary_name, created_by, modified_by, timestamp FROM dictionary"
+            + ((dictionaryId != null || dictionaryName != null)
+                ? (" WHERE " + ((dictionaryName != null) ? ("dictionary_name = '" + dictionaryName + "'") : "")
+                    + ((dictionaryId != null && dictionaryName != null) ? (" AND ") : "")
+                    + ((dictionaryId != null) ? ("dictionary_id = '" + dictionaryId + "'") : ""))
+                : "");
+
+        List<Map<String, Object>> rows = jdbcTemplateObject.queryForList(dictionarySql);
+
+        if (rows != null) {
+            rows.forEach(row -> {
                 CldsDictionary cldsDictionary = new CldsDictionary();
                 cldsDictionary.setDictionaryId((String) row.get("dictionary_id"));
                 cldsDictionary.setDictionaryName((String) row.get("dictionary_name"));
@@ -640,6 +638,7 @@ public class CldsDao {
                 cldsDictionary.setLastUpdatedDate(sdf.format(row.get("timestamp")));
                 dictionaries.add(cldsDictionary);
             });
+        }
         return dictionaries;
     }
 
@@ -671,14 +670,13 @@ public class CldsDao {
     public void updateDictionaryElements(String dictionaryElementId, CldsDictionaryItem cldsDictionaryItem,
         String userId) {
 
-        String dictionarySql = "UPDATE dictionary_elements SET dict_element_name = :dict_element_name, dict_element_short_name = :dict_element_short_name, dict_element_description = :dict_element_description,dict_element_type=:dict_element_type, modified_by = :modified_by WHERE dict_element_id = :dict_element_id";
-        SqlParameterSource namedParameters = new MapSqlParameterSource()
-            .addValue("dict_element_name", cldsDictionaryItem.getDictElementName())
-            .addValue("dict_element_short_name", cldsDictionaryItem.getDictElementShortName())
-            .addValue("dict_element_description", cldsDictionaryItem.getDictElementDesc())
-            .addValue("dict_element_type", cldsDictionaryItem.getDictElementType()).addValue("modified_by", userId)
-            .addValue("dict_element_id", dictionaryElementId);
-        jdbcTemplateObject.update(dictionarySql, namedParameters);
+        String dictionarySql = "UPDATE dictionary_elements SET dict_element_name = '"
+            + cldsDictionaryItem.getDictElementName() + "', dict_element_short_name = '"
+            + cldsDictionaryItem.getDictElementShortName() + "', dict_element_description= '"
+            + cldsDictionaryItem.getDictElementDesc() + "', dict_element_type = '"
+            + cldsDictionaryItem.getDictElementType() + "', modified_by = '" + userId + "' "
+            + "WHERE dict_element_id = '" + dictionaryElementId + "'";
+        jdbcTemplateObject.update(dictionarySql);
         cldsDictionaryItem.setUpdatedBy(userId);
     }
 
@@ -695,24 +693,17 @@ public class CldsDao {
         String dictElementShortName) {
         SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
         List<CldsDictionaryItem> dictionaryItems = new ArrayList<>();
-        MapSqlParameterSource namedParameters = new MapSqlParameterSource();
         String dictionarySql = "SELECT de.dict_element_id, de.dictionary_id, de.dict_element_name, de.dict_element_short_name, de.dict_element_description, de.dict_element_type, de.created_by, de.modified_by, de.timestamp  "
-            + "FROM dictionary_elements de, dictionary d WHERE de.dictionary_id = d.dictionary_id ";
-        if (dictionaryId != null) {
-            dictionarySql += " AND d.dictionary_id = :dictionaryId";
-            namedParameters.addValue("dictionaryId", dictionaryId);
-        }
-        if (dictElementShortName != null) {
-            dictionarySql += " AND de.dict_element_short_name = :dictElementShortName";
-            namedParameters.addValue("dictElementShortName", dictElementShortName);
-        }
-        if (dictionaryName != null) {
-            dictionarySql += " AND dictionary_name = :dictionaryName";
-            namedParameters.addValue("dictionaryName", dictionaryName);
-        }
+            + "FROM dictionary_elements de, dictionary d WHERE de.dictionary_id = d.dictionary_id "
+            + ((dictionaryId != null) ? (" AND d.dictionary_id = '" + dictionaryId + "'") : "")
+            + ((dictElementShortName != null) ? (" AND de.dict_element_short_name = '" + dictElementShortName + "'")
+                : "")
+            + ((dictionaryName != null) ? (" AND dictionary_name = '" + dictionaryName + "'") : "");
 
-        Optional.ofNullable(jdbcTemplateObject.queryForList(dictionarySql, namedParameters))
-            .orElse(Collections.emptyList()).forEach(row -> {
+        List<Map<String, Object>> rows = jdbcTemplateObject.queryForList(dictionarySql);
+
+        if (rows != null) {
+            rows.forEach(row -> {
                 CldsDictionaryItem dictionaryItem = new CldsDictionaryItem();
                 dictionaryItem.setDictElementId((String) row.get("dict_element_id"));
                 dictionaryItem.setDictionaryId((String) row.get("dictionary_id"));
@@ -725,6 +716,30 @@ public class CldsDao {
                 dictionaryItem.setLastUpdatedDate(sdf.format(row.get("timestamp")));
                 dictionaryItems.add(dictionaryItem);
             });
+        }
+        return dictionaryItems;
+    }
+
+    /**
+     * Method to get Map of all dictionary elements with key as dictionary short
+     * name and value as the full name
+     *
+     * @param dictionaryElementType
+     * @return Map of dictionary elements as key value pair
+     */
+    public Map<String, String> getDictionaryElementsByType(String dictionaryElementType) {
+        Map<String, String> dictionaryItems = new HashMap<>();
+        String dictionarySql = "SELECT dict_element_name, dict_element_short_name " + "FROM dictionary_elements "
+            + "WHERE dict_element_type = '" + dictionaryElementType + "'";
+
+        List<Map<String, Object>> rows = jdbcTemplateObject.queryForList(dictionarySql);
+
+        if (rows != null) {
+            rows.forEach(row -> {
+                dictionaryItems.put(((String) row.get("dict_element_short_name")),
+                    ((String) row.get("dict_element_name")));
+            });
+        }
         return dictionaryItems;
     }
 }
diff --git a/src/main/java/org/onap/clamp/clds/exception/BadRequestException.java b/src/main/java/org/onap/clamp/clds/exception/BadRequestException.java
new file mode 100644 (file)
index 0000000..14d14a4
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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. 
+ * 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.exception;
+
+/**
+ * New exception to request errors.
+ *
+ */
+public class BadRequestException extends RuntimeException {
+
+    /**
+        * 
+        */
+       private static final long serialVersionUID = -5738167530541646123L;
+
+       /**
+     * This constructor can be used to create a new CldsConfigException.
+     * 
+     * @param message
+     *            A string message detailing the problem
+     * @param e
+     *            The exception sent by the code
+     */
+    public BadRequestException(String message, Throwable e) {
+        super(message, e);
+    }
+
+    /**
+     * This constructor can be used to create a new CldsConfigException. Use
+     * this constructor only if you are creating a new exception stack, not if
+     * an exception was already raised by another code.
+     *
+     * @param message
+     *            A string message detailing the problem
+     */
+    public BadRequestException(String message) {
+        super(message);
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/exception/NotAuthorizedException.java b/src/main/java/org/onap/clamp/clds/exception/NotAuthorizedException.java
new file mode 100644 (file)
index 0000000..0cf5c8d
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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. 
+ * 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.exception;
+
+/**
+ * New exception to request errors.
+ *
+ */
+public class NotAuthorizedException extends RuntimeException {
+
+    /**
+        * 
+        */
+       private static final long serialVersionUID = -5738167530541646123L;
+
+       /**
+     * This constructor can be used to create a new CldsConfigException.
+     * 
+     * @param message
+     *            A string message detailing the problem
+     * @param e
+     *            The exception sent by the code
+     */
+    public NotAuthorizedException(String message, Throwable e) {
+        super(message, e);
+    }
+
+    /**
+     * This constructor can be used to create a new CldsConfigException. Use
+     * this constructor only if you are creating a new exception stack, not if
+     * an exception was already raised by another code.
+     *
+     * @param message
+     *            A string message detailing the problem
+     */
+    public NotAuthorizedException(String message) {
+        super(message);
+    }
+
+}
index 000363d..eb05fe4 100644 (file)
@@ -29,6 +29,7 @@ package org.onap.clamp.clds.model;
 public class CldsMonitoringDetails {
 
     private String closeloopName;
+    private String modelId;
     private String modelName;
     private String serviceTypeId;
     private String deploymentId;
@@ -45,6 +46,14 @@ public class CldsMonitoringDetails {
         this.closeloopName = closeloopName;
     }
 
+    public String getModelId() {
+        return modelId;
+    }
+
+    public void setModelId(String modelId) {
+        this.modelId = modelId;
+    }
+
     public String getModelName() {
         return modelName;
     }
@@ -84,7 +93,7 @@ public class CldsMonitoringDetails {
     public void setAction(String action) {
         this.action = action;
     }
-    
+
     public String getUserid() {
         return userid;
     }
@@ -92,9 +101,9 @@ public class CldsMonitoringDetails {
     public void setUserid(String userid) {
         this.userid = userid;
     }
-    
+
     public String getTimestamp() {
-        return timestamp;  
+        return timestamp;
     }
 
     public void setTimestamp(String time) {
index 4a23525..25b8d40 100644 (file)
@@ -25,7 +25,11 @@ package org.onap.clamp.clds.model;
 
 import java.util.List;
 
+import org.apache.commons.lang3.StringUtils;
+import org.onap.clamp.clds.client.req.policy.PolicyClient;
+import org.onap.clamp.clds.config.ClampProperties;
 import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.tosca.ToscaYamlToJsonConvertor;
 
 public class CldsToscaModel extends CldsToscaModelRevision {
 
@@ -40,22 +44,31 @@ public class CldsToscaModel extends CldsToscaModelRevision {
      * @param cldsDao
      * @param userId
      */
-    public CldsToscaModel save(CldsDao cldsDao, String userId) {
+    public CldsToscaModel save(CldsDao cldsDao, ClampProperties refProp, PolicyClient policyClient, String userId) {
         CldsToscaModel cldsToscaModel = null;
-        // TODO tosca parsing logic
-        this.setToscaModelJson("{}");
-        this.setPolicyType("Aging");// TODO update with subString or node_type from the model name
+        refProp.getStringList("tosca.policyTypes", ",").stream().forEach(policyType -> {
+            if (StringUtils.containsIgnoreCase(this.getToscaModelName(), policyType)) {
+                this.setPolicyType(policyType);
+            }
+        });
+
+        ToscaYamlToJsonConvertor convertor = new ToscaYamlToJsonConvertor(cldsDao);
+        this.setToscaModelJson(convertor.parseToscaYaml(this.getToscaModelYaml()));
         List<CldsToscaModel> toscaModels = cldsDao.getToscaModelByName(this.getToscaModelName());
         if (toscaModels != null && !toscaModels.isEmpty()) {
             CldsToscaModel toscaModel = toscaModels.stream().findFirst().get();
-            // CldsToscaModelRevision modelRevision =
-            // revisions.stream().max(Comparator.comparingDouble(CldsToscaModelRevision::getVersion)).get();
             this.setVersion(incrementVersion(toscaModel.getVersion()));
             this.setId(toscaModel.getId());
             this.setUserId(userId);
+            if (refProp.getStringValue("import.tosca.model").equalsIgnoreCase("true")) {
+                policyClient.importToscaModel(this);
+            }
             cldsToscaModel = cldsDao.updateToscaModelWithNewVersion(this, userId);
         } else {
             this.setVersion(1);
+            if (refProp.getStringValue("import.tosca.model").equalsIgnoreCase("true")) {
+                policyClient.importToscaModel(this);
+            }
             cldsToscaModel = cldsDao.insToscaModel(this, userId);
         }
         return cldsToscaModel;
index 5d5e218..0fb1e0f 100644 (file)
@@ -44,106 +44,116 @@ import org.springframework.stereotype.Component;
 @Component
 public class CldsDictionaryService extends SecureServiceBase {
 
-       @Value("${clamp.config.security.permission.type.tosca:permission-type-tosca}")
-       private String cldsPermissionTypeTosca;
-       @Value("${clamp.config.security.permission.instance:dev}")
-       private String cldsPermissionInstance;
-       private SecureServicePermission permissionReadTosca;
-       private SecureServicePermission permissionUpdateTosca;
+    @Value("${clamp.config.security.permission.type.tosca:permission-type-tosca}")
+    private String                  cldsPermissionTypeTosca;
+    @Value("${clamp.config.security.permission.instance:dev}")
+    private String                  cldsPermissionInstance;
+    private SecureServicePermission permissionReadTosca;
+    private SecureServicePermission permissionUpdateTosca;
 
-       @Autowired
-       private CldsDao cldsDao;
+    @Autowired
+    private CldsDao                 cldsDao;
+    
+    private LoggingUtils util = new LoggingUtils(logger);
+    
 
-       @PostConstruct
-       private final void initConstruct() {
-               permissionReadTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "read");
-        permissionUpdateTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "update");
-       }
+    @PostConstruct
+    private final void initConstruct() {
+        permissionReadTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "read");
+        permissionUpdateTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance,
+                "update");
+    }
 
-       /**
-        *  REST Service that creates or Updates a Dictionary
-        *  
-        * @param dictionaryName
-        * @param cldsDictionary
-        * @return CldsDictionary that was created in DB.
-        */
-       public ResponseEntity<CldsDictionary> createOrUpdateDictionary(String dictionaryName,
-                       CldsDictionary cldsDictionary) {
-               Date startTime = new Date();
-               LoggingUtils.setRequestContext("CldsDictionaryService: createOrUpdateDictionary", getPrincipalName());
-               // TODO revisit based on new permissions
-               isAuthorized(permissionUpdateTosca);
-               if (cldsDictionary == null) {
-                       cldsDictionary = new CldsDictionary();
-                       cldsDictionary.setDictionaryName(dictionaryName);
-               }
-               cldsDictionary.save(dictionaryName, cldsDao, getUserId());
-               LoggingUtils.setTimeContext(startTime, new Date());
-               LoggingUtils.setResponseContext("0", "createOrUpdateDictionary success", this.getClass().getName());
-               auditLogger.info("createOrUpdateDictionary completed");
-               return new ResponseEntity<>(cldsDictionary, HttpStatus.OK);
-       }
+    /**
+     * REST Service that creates or Updates a Dictionary
+     * 
+     * @param dictionaryName
+     * @param cldsDictionary
+     * @return CldsDictionary that was created in DB.
+     */
+    public ResponseEntity<CldsDictionary> createOrUpdateDictionary(String dictionaryName,
+            CldsDictionary cldsDictionary) {
+        Date startTime = new Date();
+        LoggingUtils.setRequestContext("CldsDictionaryService: createOrUpdateDictionary", getPrincipalName());
+        // TODO revisit based on new permissions
+        isAuthorized(permissionUpdateTosca);
+        if (cldsDictionary == null) {
+            cldsDictionary = new CldsDictionary();
+            cldsDictionary.setDictionaryName(dictionaryName);
+        }
+        cldsDictionary.save(dictionaryName, cldsDao, getUserId());
+        LoggingUtils.setTimeContext(startTime, new Date());
+        LoggingUtils.setResponseContext("0", "createOrUpdateDictionary success", this.getClass().getName());
+        auditLogger.info("createOrUpdateDictionary completed");
+        return new ResponseEntity<>(cldsDictionary, HttpStatus.OK);
+    }
 
-       /**
-        * REST Service that creates or Updates a Dictionary Elements for dictionary in DB
-        * 
-        * @param dictionaryName
-        * @param dictionaryItem
-        * @return CldsDictionaryItem
-        *                      A dictionary items that was created or updated in DB
-        */
-       public ResponseEntity<CldsDictionaryItem> createOrUpdateDictionaryElements(String dictionaryName,
-                       CldsDictionaryItem dictionaryItem) {
-               Date startTime = new Date();
-               LoggingUtils.setRequestContext("CldsDictionaryService: createOrUpdateDictionaryElements", getPrincipalName());
-               // TODO revisit based on new permissions
-               isAuthorized(permissionUpdateTosca);
-               dictionaryItem.save(dictionaryName, cldsDao, getUserId());
-               LoggingUtils.setTimeContext(startTime, new Date());
-               LoggingUtils.setResponseContext("0", "createOrUpdateDictionaryElements success", this.getClass().getName());
-               auditLogger.info("createOrUpdateDictionaryElements completed");
-               return new ResponseEntity<>(dictionaryItem, HttpStatus.OK);
-       }
+    /**
+     * REST Service that creates or Updates a Dictionary Elements for dictionary
+     * in DB
+     * 
+     * @param dictionaryName
+     * @param dictionaryItem
+     * @return CldsDictionaryItem A dictionary items that was created or updated
+     *         in DB
+     */
+    public ResponseEntity<CldsDictionaryItem> createOrUpdateDictionaryElements(String dictionaryName,
+            CldsDictionaryItem dictionaryItem) {
+        Date startTime = new Date();
+        LoggingUtils.setRequestContext("CldsDictionaryService: createOrUpdateDictionaryElements", getPrincipalName());
+        // TODO revisit based on new permissions
+        isAuthorized(permissionUpdateTosca);
+        dictionaryItem.save(dictionaryName, cldsDao, getUserId());
+        LoggingUtils.setTimeContext(startTime, new Date());
+        LoggingUtils.setResponseContext("0", "createOrUpdateDictionaryElements success", this.getClass().getName());
+        auditLogger.info("createOrUpdateDictionaryElements completed");
+        return new ResponseEntity<>(dictionaryItem, HttpStatus.OK);
+    }
 
-       /**
-        * Rest Service that retrieves all CLDS dictionary in DB
-        * 
-        * @return CldsDictionary List
-        *                      List of CldsDictionary available in DB
-        */
-       public ResponseEntity<List<CldsDictionary>> getAllDictionaryNames() {
-               Date startTime = new Date();
-               LoggingUtils.setRequestContext("CldsDictionaryService: getAllDictionaryNames", getPrincipalName());
-               // TODO revisit based on new permissions
-               isAuthorized(permissionReadTosca);
-               List<CldsDictionary> dictionaries = cldsDao.getDictionary(null, null);
-               LoggingUtils.setTimeContext(startTime, new Date());
-               LoggingUtils.setResponseContext("0", "getAllDictionaryNames success", this.getClass().getName());
-               auditLogger.info("getAllDictionaryNames completed");
-               return new ResponseEntity<>(dictionaries, HttpStatus.OK);
-       }
+    /**
+     * Rest Service that retrieves all CLDS dictionary in DB
+     * 
+     * @return CldsDictionary List List of CldsDictionary available in DB
+     */
+    public ResponseEntity<List<CldsDictionary>> getAllDictionaryNames() {
+        Date startTime = new Date();
+        LoggingUtils.setRequestContext("CldsDictionaryService: getAllDictionaryNames", getPrincipalName());
+        // TODO revisit based on new permissions
+        isAuthorized(permissionReadTosca);
+        List<CldsDictionary> dictionaries = cldsDao.getDictionary(null, null);
+        LoggingUtils.setTimeContext(startTime, new Date());
+        LoggingUtils.setResponseContext("0", "getAllDictionaryNames success", this.getClass().getName());
+        auditLogger.info("getAllDictionaryNames completed");
+        return new ResponseEntity<>(dictionaries, HttpStatus.OK);
+    }
 
-       /**
-        * Rest Service that retrieves all CLDS dictionary items in DB for a give dictionary name
-        * 
-        * @param dictionaryName
-        * @return CldsDictionaryItem list
-        *                      List of CLDS Dictionary items for a given dictionary name
-        */
-       public ResponseEntity<List<CldsDictionaryItem>> getDictionaryElementsByName(String dictionaryName) {
-               Date startTime = new Date();
-               LoggingUtils.setRequestContext("CldsDictionaryService: getDictionaryElementsByName", getPrincipalName());
-               // TODO revisit based on new permissions
-               isAuthorized(permissionReadTosca);
-               List<CldsDictionaryItem> dictionaryItems = cldsDao.getDictionaryElements(dictionaryName, null, null);
-               LoggingUtils.setTimeContext(startTime, new Date());
-               LoggingUtils.setResponseContext("0", "getAllDictionaryNames success", this.getClass().getName());
-               auditLogger.info("getAllDictionaryNames completed");
-               return new ResponseEntity<>(dictionaryItems, HttpStatus.OK);
-       }
+    /**
+     * Rest Service that retrieves all CLDS dictionary items in DB for a give
+     * dictionary name
+     * 
+     * @param dictionaryName
+     * @return CldsDictionaryItem list List of CLDS Dictionary items for a given
+     *         dictionary name
+     */
+    public ResponseEntity<List<CldsDictionaryItem>> getDictionaryElementsByName(String dictionaryName) {
+        Date startTime = new Date();
+        LoggingUtils.setRequestContext("CldsDictionaryService: getDictionaryElementsByName", getPrincipalName());
+        // TODO revisit based on new permissions
+        isAuthorized(permissionReadTosca);
+        List<CldsDictionaryItem> dictionaryItems = cldsDao.getDictionaryElements(dictionaryName, null, null);
+        LoggingUtils.setTimeContext(startTime, new Date());
+        LoggingUtils.setResponseContext("0", "getAllDictionaryNames success", this.getClass().getName());
+        auditLogger.info("getAllDictionaryNames completed");
+        return new ResponseEntity<>(dictionaryItems, HttpStatus.OK);
+    }
 
-       public ResponseEntity<?> deleteDictionary() {
-               return null;
-       }
+    public ResponseEntity<?> deleteDictionary() {
+        return null;
+    }
+
+    // Created for the integration test
+    public void setLoggingUtil(LoggingUtils utilP) {
+        util = utilP;
+    }
 
 }
index f33039f..04205b7 100644 (file)
@@ -29,6 +29,8 @@ import java.util.Optional;
 
 import javax.annotation.PostConstruct;
 
+import org.onap.clamp.clds.client.req.policy.PolicyClient;
+import org.onap.clamp.clds.config.ClampProperties;
 import org.onap.clamp.clds.dao.CldsDao;
 import org.onap.clamp.clds.model.CldsToscaModel;
 import org.onap.clamp.clds.util.LoggingUtils;
@@ -44,106 +46,124 @@ import org.springframework.stereotype.Component;
 @Component
 public class CldsToscaService extends SecureServiceBase {
 
-       @Value("${clamp.config.security.permission.type.tosca:permission-type-tosca}")
-       private String cldsPermissionTypeTosca;
-       @Value("${clamp.config.security.permission.instance:dev}")
-       private String cldsPermissionInstance;
-       private SecureServicePermission permissionReadTosca;
-       private SecureServicePermission permissionUpdateTosca;
-
-       @Autowired
-       private CldsDao cldsDao;
-
-       @PostConstruct
-       private final void initConstruct() {
-               permissionReadTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "read");
-        permissionUpdateTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "update");
-       }
-       
-       /**
-        * REST service to upload a new Tosca Model or update an existing Tosca model with new version.
-        * This API will parse the Tosca model yaml and generates a JSON schema out of it.
-        * 
-        * @param toscaModelName
-        *                      Tosca model name to be used as a key
-        * @param cldsToscaModel
-        *          Object containing the tosca model yaml
-        * 
-        * @return clds tosca models - list of CLDS tosca models for a given policy type 
-        */
-       public ResponseEntity<?> parseToscaModelAndSave(String toscaModelName, CldsToscaModel cldsToscaModel ) {
+    @Value("${clamp.config.security.permission.type.tosca:permission-type-tosca}")
+    private String                  cldsPermissionTypeTosca;
+    @Value("${clamp.config.security.permission.instance:dev}")
+    private String                  cldsPermissionInstance;
+    private SecureServicePermission permissionReadTosca;
+    private SecureServicePermission permissionUpdateTosca;
+
+    @Autowired
+    private CldsDao                 cldsDao;
+
+    @Autowired
+    private ClampProperties         refProp;
+
+    @Autowired
+    private PolicyClient            policyClient;
+    private LoggingUtils util = new LoggingUtils(logger);
+
+    @PostConstruct
+    private final void initConstruct() {
+        permissionReadTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "read");
+        permissionUpdateTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance,
+                "update");
+    }
+
+    /**
+     * REST service to upload a new Tosca Model or update an existing Tosca
+     * model with new version. This API will parse the Tosca model yaml and
+     * generates a JSON schema out of it.
+     * 
+     * @param toscaModelName
+     *            Tosca model name to be used as a key
+     * @param cldsToscaModel
+     *            Object containing the tosca model yaml
+     * 
+     * @return clds tosca models - list of CLDS tosca models for a given policy
+     *         type
+     */
+    public ResponseEntity<?> parseToscaModelAndSave(String toscaModelName, CldsToscaModel cldsToscaModel) {
         Date startTime = new Date();
         LoggingUtils.setRequestContext("CldsToscaService: Parse Tosca model and save", getPrincipalName());
-        //TODO revisit based on new permissions
+        // TODO revisit based on new permissions
         isAuthorized(permissionUpdateTosca);
         cldsToscaModel.setToscaModelName(toscaModelName);
-        cldsToscaModel = cldsToscaModel.save(cldsDao, getUserId());
+        cldsToscaModel = cldsToscaModel.save(cldsDao, refProp, policyClient, getUserId());
         LoggingUtils.setTimeContext(startTime, new Date());
         LoggingUtils.setResponseContext("0", "Parse Tosca model and save success", this.getClass().getName());
         auditLogger.info("Parse Tosca model and save completed");
         return new ResponseEntity<>(cldsToscaModel, HttpStatus.CREATED);
-       }
-       
-       /**
-        * REST service to retrieve all Tosca models from the CLDS database.
-        
-        * @return clds tosca models - list of CLDS tosca models 
-        */
-       public ResponseEntity<List<CldsToscaModel>> getAllToscaModels() {
-               
-               Date startTime = new Date();
+    }
+
+    /**
+     * REST service to retrieve all Tosca models from the CLDS database.
+     * 
+     * @return clds tosca models - list of CLDS tosca models
+     */
+    public ResponseEntity<List<CldsToscaModel>> getAllToscaModels() {
+
+        Date startTime = new Date();
         LoggingUtils.setRequestContext("CldsToscaService: Get All tosca models", getPrincipalName());
-        //TODO revisit based on new permissions
+        // TODO revisit based on new permissions
         isAuthorized(permissionReadTosca);
         List<CldsToscaModel> cldsToscaModels = Optional.ofNullable(cldsDao.getAllToscaModels()).get();
         LoggingUtils.setTimeContext(startTime, new Date());
         LoggingUtils.setResponseContext("0", "Get All tosca models success", this.getClass().getName());
         auditLogger.info("Get All tosca models");
         return new ResponseEntity<>(cldsToscaModels, HttpStatus.OK);
-       }
-       
-       /**
-        * REST service that retrieves a CLDS Tosca model by model name from the database.
-        * 
-        * @param toscaModelName
-        *                      Path param with tosca model name
-        * 
-        * @return clds tosca model -  CLDS tosca model for a given tosca model name 
-        */
-       public ResponseEntity<CldsToscaModel> getToscaModel(String toscaModelName) {
-               Date startTime = new Date();
+    }
+
+    /**
+     * REST service that retrieves a CLDS Tosca model by model name from the
+     * database.
+     * 
+     * @param toscaModelName
+     *            Path param with tosca model name
+     * 
+     * @return clds tosca model - CLDS tosca model for a given tosca model name
+     */
+    public ResponseEntity<CldsToscaModel> getToscaModel(String toscaModelName) {
+        Date startTime = new Date();
         LoggingUtils.setRequestContext("CldsToscaService: Get tosca models by model name", getPrincipalName());
-        //TODO revisit based on new permissions
+        // TODO revisit based on new permissions
         isAuthorized(permissionReadTosca);
         List<CldsToscaModel> cldsToscaModels = Optional.ofNullable(cldsDao.getToscaModelByName(toscaModelName)).get();
         LoggingUtils.setTimeContext(startTime, new Date());
         LoggingUtils.setResponseContext("0", "Get tosca models by model name success", this.getClass().getName());
         auditLogger.info("GET tosca models by model name completed");
-        return new ResponseEntity<>(Optional.ofNullable(cldsToscaModels).get().stream().findFirst().get(), HttpStatus.OK);
-       }
-
-       
-       /**
-        * REST service that retrieves a CLDS Tosca model lists for a policy type from the database.
-        * 
-        * @param policyType
-        * @return clds tosca model -  CLDS tosca model for a given policy type 
-        */
-       public ResponseEntity<CldsToscaModel> getToscaModelsByPolicyType(String policyType) {
-               Date startTime = new Date();
+        return new ResponseEntity<>(Optional.ofNullable(cldsToscaModels).get().stream().findFirst().get(),
+                HttpStatus.OK);
+    }
+
+    /**
+     * REST service that retrieves a CLDS Tosca model lists for a policy type
+     * from the database.
+     * 
+     * @param policyType
+     * @return clds tosca model - CLDS tosca model for a given policy type
+     */
+    public ResponseEntity<CldsToscaModel> getToscaModelsByPolicyType(String policyType) {
+        Date startTime = new Date();
         LoggingUtils.setRequestContext("CldsToscaService: Get tosca models by policyType", getPrincipalName());
-        //TODO revisit based on new permissions
+        // TODO revisit based on new permissions
         isAuthorized(permissionReadTosca);
         List<CldsToscaModel> cldsToscaModels = Optional.ofNullable(cldsDao.getToscaModelByPolicyType(policyType)).get();
         LoggingUtils.setTimeContext(startTime, new Date());
         LoggingUtils.setResponseContext("0", "Get tosca models by policyType success", this.getClass().getName());
         auditLogger.info("GET tosca models by policyType completed");
-        return new ResponseEntity<>(Optional.ofNullable(cldsToscaModels).get().stream().findFirst().get(), HttpStatus.OK);
-       }
-       
-       public ResponseEntity<?> deleteToscaModelById(String toscaModeId) {
-               //TODO
-               return null;
-       }
-       
+        return new ResponseEntity<>(Optional.ofNullable(cldsToscaModels).get().stream().findFirst().get(),
+                HttpStatus.OK);
+    }
+
+    public ResponseEntity<?> deleteToscaModelById(String toscaModeId) {
+        // TODO
+        return null;
+    }
+    
+    // Created for the integration test
+    public void setLoggingUtil(LoggingUtils utilP) {
+        util = utilP;
+    }
+
 }
diff --git a/src/main/java/org/onap/clamp/clds/tosca/JsonEditorSchemaConstants.java b/src/main/java/org/onap/clamp/clds/tosca/JsonEditorSchemaConstants.java
new file mode 100644 (file)
index 0000000..58a2f6f
--- /dev/null
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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.
+ * 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.tosca;
+
+public class JsonEditorSchemaConstants {
+       
+       //Data types in JSON Schema
+       public static final String TYPE_OBJECT = "object";
+       public static final String TYPE_ARRAY = "array";
+       public static final String TYPE_STRING = "string";
+       public static final String TYPE_INTEGER = "integer";
+       
+       //Key elements in JSON Schema
+       public static final String TYPE = "type";
+       public static final String TITLE = "title";
+       public static final String REQUIRED = "required";
+       public static final String DEFAULT = "default";
+       public static final String ENUM = "enum";
+       public static final String ENUM_TITLES = "enum_titles";
+       public static final String OPTIONS = "options";
+       public static final String FORMAT = "format";
+       public static final String ITEMS = "items";
+       public static final String PROPERTIES = "properties";
+       public static final String PROPERTY_ORDER = "propertyOrder";
+       
+       public static final String MINIMUM = "minimum";
+       public static final String MAXIMUM = "maximum";
+       public static final String MIN_LENGTH = "minLength";
+       public static final String MAX_LENGTH = "maxLength";
+       public static final String EXCLUSIVE_MINIMUM = "exclusiveMinimum";
+       public static final String EXCLUSIVE_MAXIMUM = "exclusiveMaximum";
+       
+       public static final String CUSTOM_KEY_FORMAT = "format";
+       public static final String CUSTOM_KEY_FORMAT_TABS_TOP = "tabs-top";
+       public static final String FORMAT_SELECT = "select";
+       public static final String UNIQUE_ITEMS = "uniqueItems";
+       public static final String TRUE = "true";
+       public static final String QSSCHEMA = "qschema";
+       public static final String TYPE_QBLDR = "qbldr";
+       
+       public static final String ID = "id";
+       public static final String LABEL = "label";
+       public static final String OPERATORS = "operators";
+       public static final String FILTERS = "filters";
+       
+       public static final String SCHEMA = "schema";
+       public static final String CURRENT_VALUES = "currentValues";
+       
+       
+       
+       
+       
+       
+       
+       
+       
+}
diff --git a/src/main/java/org/onap/clamp/clds/tosca/ToscaSchemaConstants.java b/src/main/java/org/onap/clamp/clds/tosca/ToscaSchemaConstants.java
new file mode 100644 (file)
index 0000000..f5b5a8d
--- /dev/null
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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.
+ * 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.tosca;
+
+public class ToscaSchemaConstants {
+
+       //Data types in TOSCA Schema
+       public static final String TYPE_LIST = "list";
+       public static final String TYPE_MAP = "map";
+       public static final String TYPE_STRING = "string";
+       public static final String TYPE_INTEGER = "integer";
+       public static final String TYPE_FLOAT = "float";
+       public static final String TYPE_BOOLEAN = "boolean";
+       
+       //Key elements in Tosca
+       public static final String NODE_TYPES = "node_types";
+       public static final String DATA_TYPES = "data_types";
+       public static final String TYPE = "type";
+       public static final String DESCRIPTION = "description";
+       public static final String DEFAULT = "default";
+       public static final String PROPERTIES = "properties";
+       public static final String REQUIRED = "required";
+       public static final String ENTRY_SCHEMA = "entry_schema";
+
+       //Constraints
+       public static final String CONSTRAINTS = "constraints";
+       public static final String VALID_VALUES = "valid_values";
+       public static final String EQUAL = "equal";
+       public static final String GREATER_THAN = "greater_than";
+       public static final String GREATER_OR_EQUAL = "greater_or_equal";
+       public static final String LESS_THAN = "less_than";
+       public static final String LESS_OR_EQUAL = "less_or_equal";
+       public static final String IN_RANGE = "in_range";
+       public static final String  LENGTH = "length";
+       public static final String MIN_LENGTH = "min_length";
+       public static final String MAX_LENGTH = "max_length";
+       public static final String PATTERN = "pattern";
+       
+       //Prefix for policy nodes
+       public static final String POLICY_NODE = "policy.nodes.";
+       
+       //Prefix for data nodes
+       public static final String POLICY_DATA = "policy.data.";
+       
+       //Prefix for dictionary elements
+       public static final String DICTIONARY = "Dictionary:";
+       
+       //Custom Elements that must exist in the Tosca models
+       public static final String NAME = "name";
+       public static final String CONTEXT = "context";
+
+       
+       
+       
+}
diff --git a/src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java b/src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java
new file mode 100644 (file)
index 0000000..784d95e
--- /dev/null
@@ -0,0 +1,589 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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.
+ * 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.tosca;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.model.CldsDictionaryItem;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * Tosca Model Yaml parser and convertor to JSON Schema consumable for JSON
+ * Editor
+ *
+ */
+public class ToscaYamlToJsonConvertor {
+
+    private CldsDao cldsDao;
+    private int simpleTypeOrder = 1000;
+    private int complexTypeOrder = 10000;
+    private int complexSimpleTypeOrder = 1;
+
+    public ToscaYamlToJsonConvertor(CldsDao cldsDao) {
+        this.cldsDao = cldsDao;
+    }
+
+    private int incrementSimpleTypeOrder() {
+        return simpleTypeOrder++;
+    }
+
+    private int incrementComplexTypeOrder() {
+        return complexTypeOrder = complexTypeOrder + 10000;
+    }
+
+    private int incrementComplexSimpleTypeOrder() {
+        complexSimpleTypeOrder++;
+        return complexTypeOrder + complexSimpleTypeOrder;
+    }
+
+    /**
+     * @return the cldsDao
+     */
+    public CldsDao getCldsDao() {
+        return cldsDao;
+    }
+
+    /**
+     * @param cldsDao
+     *        the cldsDao to set
+     */
+    public void setCldsDao(CldsDao cldsDao) {
+        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>();
+        JSONObject jsonEditorObject = new JSONObject();
+        JSONObject jsonParentObject = new JSONObject();
+        JSONObject jsonTempObject = new JSONObject();
+        parseNodeAndDataType(loadedYaml, nodeTypes, dataNodes);
+        populateJsonEditorObject(loadedYaml, nodeTypes, dataNodes, jsonParentObject, jsonTempObject);
+        if (jsonTempObject.length() > 0) {
+            jsonParentObject = jsonTempObject;
+        }
+        jsonEditorObject.put(JsonEditorSchemaConstants.SCHEMA, jsonParentObject);
+        return jsonEditorObject.toString();
+    }
+
+    // Parse node_type and data_type
+    @SuppressWarnings("unchecked")
+    private void parseNodeAndDataType(LinkedHashMap<String, Object> map, LinkedHashMap<String, Object> nodeTypes,
+        LinkedHashMap<String, Object> dataNodes) {
+        map.entrySet().stream().forEach(n -> {
+            if (n.getKey().contains(ToscaSchemaConstants.NODE_TYPES) && n.getValue() instanceof Map) {
+
+                parseNodeAndDataType((LinkedHashMap<String, Object>) n.getValue(), nodeTypes, dataNodes);
+
+            } else if (n.getKey().contains(ToscaSchemaConstants.DATA_TYPES) && n.getValue() instanceof Map) {
+
+                parseNodeAndDataType((LinkedHashMap<String, Object>) n.getValue(), nodeTypes, dataNodes);
+
+            } else if (n.getKey().contains(ToscaSchemaConstants.POLICY_NODE)) {
+
+                nodeTypes.put(n.getKey(), n.getValue());
+
+            } else if (n.getKey().contains(ToscaSchemaConstants.POLICY_DATA)) {
+
+                dataNodes.put(n.getKey(), n.getValue());
+            }
+
+        });
+    }
+
+    @SuppressWarnings("unchecked")
+    private void populateJsonEditorObject(LinkedHashMap<String, Object> map, LinkedHashMap<String, Object> nodeTypes,
+        LinkedHashMap<String, Object> dataNodes, JSONObject jsonParentObject, JSONObject jsonTempObject) {
+
+        Map<String, JSONObject> jsonEntrySchema = new HashMap();
+        jsonParentObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_OBJECT);
+        nodeTypes.entrySet().stream().forEach(nt -> {
+            if (nt.getValue() instanceof Map) {
+                ((LinkedHashMap<String, Object>) nt.getValue()).entrySet().forEach(ntElement -> {
+                    if (ntElement.getKey().equalsIgnoreCase(ToscaSchemaConstants.PROPERTIES)) {
+                        JSONArray rootNodeArray = new JSONArray();
+                        if (ntElement.getValue() instanceof Map) {
+                            ((LinkedHashMap<String, Object>) ntElement.getValue()).entrySet()
+                                .forEach((ntPropertiesElement) -> {
+                                    boolean isListNode = false;
+                                    parseDescription((LinkedHashMap<String, Object>) ntPropertiesElement.getValue(),
+                                        jsonParentObject);
+                                    LinkedHashMap<String, Object> parentPropertiesMap = (LinkedHashMap<String, Object>) ntPropertiesElement
+                                        .getValue();
+                                    if (parentPropertiesMap.containsKey(ToscaSchemaConstants.TYPE)
+                                        && ((String) parentPropertiesMap.get(ToscaSchemaConstants.TYPE))
+                                            .contains(ToscaSchemaConstants.TYPE_LIST)
+                                        && parentPropertiesMap.containsKey(ToscaSchemaConstants.ENTRY_SCHEMA)) {
+                                        parentPropertiesMap = (LinkedHashMap<String, Object>) parentPropertiesMap
+                                            .get(ToscaSchemaConstants.ENTRY_SCHEMA);
+                                        isListNode = true;
+                                    }
+                                    if (parentPropertiesMap.containsKey(ToscaSchemaConstants.TYPE)
+                                        && ((String) parentPropertiesMap.get(ToscaSchemaConstants.TYPE))
+                                            .contains(ToscaSchemaConstants.POLICY_DATA)) {
+                                        ((LinkedHashMap<String, Object>) dataNodes
+                                            .get(parentPropertiesMap.get(ToscaSchemaConstants.TYPE))).entrySet()
+                                                .stream().forEach(pmap -> {
+                                                    if (pmap.getKey()
+                                                        .equalsIgnoreCase(ToscaSchemaConstants.PROPERTIES)) {
+                                                        parseToscaProperties(ToscaSchemaConstants.POLICY_NODE,
+                                                            (LinkedHashMap<String, Object>) pmap.getValue(),
+                                                            jsonParentObject, rootNodeArray, jsonEntrySchema, dataNodes,
+                                                            incrementSimpleTypeOrder());
+                                                    }
+
+                                                });
+
+                                    }
+                                    if (isListNode) {
+                                        jsonTempObject.put(JsonEditorSchemaConstants.TYPE,
+                                            JsonEditorSchemaConstants.TYPE_ARRAY);
+                                        parseDescription((LinkedHashMap<String, Object>) ntPropertiesElement.getValue(),
+                                            jsonTempObject);
+                                        jsonTempObject.put(JsonEditorSchemaConstants.ITEMS, jsonParentObject);
+                                        jsonTempObject.put(JsonEditorSchemaConstants.FORMAT,
+                                            JsonEditorSchemaConstants.CUSTOM_KEY_FORMAT_TABS_TOP);
+                                        jsonTempObject.put(JsonEditorSchemaConstants.UNIQUE_ITEMS,
+                                            JsonEditorSchemaConstants.TRUE);
+                                    }
+                                });
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    @SuppressWarnings("unchecked")
+    private void parseToscaProperties(String parentKey, LinkedHashMap<String, Object> propertiesMap,
+        JSONObject jsonDataNode, JSONArray array, Map<String, JSONObject> jsonEntrySchema,
+        LinkedHashMap<String, Object> dataNodes, final int order) {
+        JSONObject jsonPropertyNode = new JSONObject();
+        propertiesMap.entrySet().stream().forEach(p -> {
+            // Populate JSON Array for "required" key
+
+            if (p.getValue() instanceof Map) {
+                LinkedHashMap<String, Object> nodeMap = (LinkedHashMap<String, Object>) p.getValue();
+                if (nodeMap.containsKey(ToscaSchemaConstants.REQUIRED)
+                    && ((boolean) nodeMap.get(ToscaSchemaConstants.REQUIRED))) {
+                    array.put(p.getKey());
+                }
+                // if(nodeMap.containsKey(ToscaSchemaConstants.CONSTRAINTS))
+                parseToscaChildNodeMap(p.getKey(), nodeMap, jsonPropertyNode, jsonEntrySchema, dataNodes, array,
+                    incrementSimpleTypeOrder());
+            }
+        });
+        jsonDataNode.put(JsonEditorSchemaConstants.REQUIRED, array);
+        jsonDataNode.put(JsonEditorSchemaConstants.PROPERTIES, jsonPropertyNode);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void parseToscaPropertiesForType(String parentKey, LinkedHashMap<String, Object> propertiesMap,
+        JSONObject jsonDataNode, JSONArray array, Map<String, JSONObject> jsonEntrySchema,
+        LinkedHashMap<String, Object> dataNodes, boolean isType, int order) {
+        JSONObject jsonPropertyNode = new JSONObject();
+
+        propertiesMap.entrySet().stream().forEach(p -> {
+            // array.put(p.getKey());
+            boolean overWriteArray = false;
+            if (p.getValue() instanceof Map) {
+                LinkedHashMap<String, Object> nodeMap = (LinkedHashMap<String, Object>) p.getValue();
+                if (!(parentKey.contains(ToscaSchemaConstants.ENTRY_SCHEMA)
+                    || parentKey.contains(ToscaSchemaConstants.POLICY_NODE))
+                    && nodeMap.containsKey(ToscaSchemaConstants.TYPE)
+                    && (((String) nodeMap.get(ToscaSchemaConstants.TYPE)).contains(ToscaSchemaConstants.POLICY_DATA))) {
+                    overWriteArray = true;
+                }
+                if (nodeMap.containsKey(ToscaSchemaConstants.REQUIRED)
+                    && ((boolean) nodeMap.get(ToscaSchemaConstants.REQUIRED))) {
+                    array.put(p.getKey());
+                }
+                parseToscaChildNodeMap(p.getKey(), nodeMap, jsonPropertyNode, jsonEntrySchema, dataNodes, array, order);
+            }
+        });
+        jsonDataNode.put(JsonEditorSchemaConstants.REQUIRED, array);
+        jsonDataNode.put(JsonEditorSchemaConstants.PROPERTIES, jsonPropertyNode);
+    }
+
+    private void parseToscaChildNodeMap(String childObjectKey, LinkedHashMap<String, Object> childNodeMap,
+        JSONObject jsonPropertyNode, Map<String, JSONObject> jsonEntrySchema, LinkedHashMap<String, Object> dataNodes,
+        JSONArray array, int order) {
+        JSONObject childObject = new JSONObject();
+        // JSONArray childArray = new JSONArray();
+        parseDescription(childNodeMap, childObject);
+        parseTypes(childObjectKey, childNodeMap, childObject, jsonEntrySchema, dataNodes, array, order);
+        parseConstraints(childNodeMap, childObject);
+        parseEntrySchema(childNodeMap, childObject, jsonPropertyNode, jsonEntrySchema, dataNodes);
+
+        jsonPropertyNode.put(childObjectKey, childObject);
+        order++;
+
+    }
+
+    private void parseEntrySchema(LinkedHashMap<String, Object> childNodeMap, JSONObject childObject,
+        JSONObject jsonPropertyNode, Map<String, JSONObject> jsonEntrySchema, LinkedHashMap<String, Object> dataNodes) {
+        if (childNodeMap.get(ToscaSchemaConstants.ENTRY_SCHEMA) != null) {
+            if (childNodeMap.get(ToscaSchemaConstants.ENTRY_SCHEMA) instanceof Map) {
+                LinkedHashMap<String, Object> entrySchemaMap = (LinkedHashMap<String, Object>) childNodeMap
+                    .get(ToscaSchemaConstants.ENTRY_SCHEMA);
+                entrySchemaMap.entrySet().stream().forEach(entry -> {
+                    if (entry.getKey().equalsIgnoreCase(ToscaSchemaConstants.TYPE) && entry.getValue() != null) {
+                        String entrySchemaType = (String) entry.getValue();
+                        if (entrySchemaType.contains(ToscaSchemaConstants.POLICY_DATA)) {
+                            JSONArray array = new JSONArray();
+                            if (jsonEntrySchema.get(entrySchemaType) != null) {
+                                // Already traversed
+                                JSONObject entrySchemaObject = jsonEntrySchema.get(entrySchemaType);
+                                attachEntrySchemaJsonObject(childObject, entrySchemaObject,
+                                    JsonEditorSchemaConstants.TYPE_OBJECT);
+                            } else if (dataNodes.containsKey(entrySchemaType)) {
+
+                                JSONObject entrySchemaObject = new JSONObject();
+                                // Need to traverse
+                                ((LinkedHashMap<String, Object>) dataNodes.get(entrySchemaType)).entrySet().stream()
+                                    .forEach(pmap -> {
+                                        if (pmap.getKey().equalsIgnoreCase(ToscaSchemaConstants.PROPERTIES)) {
+                                            parseToscaProperties(ToscaSchemaConstants.ENTRY_SCHEMA,
+                                                (LinkedHashMap<String, Object>) pmap.getValue(), entrySchemaObject,
+                                                array, jsonEntrySchema, dataNodes, incrementComplexTypeOrder());
+                                            jsonEntrySchema.put(entrySchemaType, entrySchemaObject);
+                                            dataNodes.remove(entrySchemaType);
+                                            attachEntrySchemaJsonObject(childObject, entrySchemaObject,
+                                                JsonEditorSchemaConstants.TYPE_OBJECT);
+                                        }
+
+                                    });
+                            }
+                        } else if (entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING)
+                            || entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_INTEGER)
+                            || entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_FLOAT)) {
+                            JSONObject entrySchemaObject = new JSONObject();
+                            parseConstraints(entrySchemaMap, entrySchemaObject);
+                            String jsontype = JsonEditorSchemaConstants.TYPE_STRING;
+                            if (entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_INTEGER)
+                                || entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_FLOAT)) {
+                                jsontype = JsonEditorSchemaConstants.TYPE_INTEGER;
+                            }
+                            if (childNodeMap.get(ToscaSchemaConstants.TYPE) != null) {
+                                // Only known value of type is String for now
+                                if (childNodeMap.get(ToscaSchemaConstants.TYPE) instanceof String) {
+                                    String typeValue = (String) childNodeMap.get(ToscaSchemaConstants.TYPE);
+                                    if (typeValue.equalsIgnoreCase(ToscaSchemaConstants.TYPE_LIST)) {
+                                        // Custom key for JSON Editor and UI rendering
+                                        childObject.put(JsonEditorSchemaConstants.CUSTOM_KEY_FORMAT,
+                                            JsonEditorSchemaConstants.FORMAT_SELECT);
+                                        // childObject.put(JsonEditorSchemaConstants.UNIQUE_ITEMS,
+                                        // JsonEditorSchemaConstants.TRUE);
+                                    }
+                                }
+                            }
+                            attachEntrySchemaJsonObject(childObject, entrySchemaObject, jsontype);
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    private void attachEntrySchemaJsonObject(JSONObject childObject, JSONObject entrySchemaObject, String dataType) {
+
+        entrySchemaObject.put(JsonEditorSchemaConstants.TYPE, dataType);
+        childObject.put(JsonEditorSchemaConstants.ITEMS, entrySchemaObject);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void attachTypeJsonObject(JSONObject childObject, JSONObject typeObject) {
+        Iterator<String> keys = typeObject.keys();
+        while (keys.hasNext()) {
+            String key = keys.next();
+            childObject.put(key, typeObject.get(key));
+        }
+    }
+
+    /*
+     * private String parseKey(String toscaKey, String lookupString) { return
+     * toscaKey.substring(toscaKey.indexOf(lookupString) + lookupString.length(),
+     * toscaKey.length()); }
+     */
+
+    private void parseDescription(LinkedHashMap<String, Object> childNodeMap, JSONObject childObject) {
+        if (childNodeMap.get(ToscaSchemaConstants.DESCRIPTION) != null) {
+            childObject.put(JsonEditorSchemaConstants.TITLE, childNodeMap.get(ToscaSchemaConstants.DESCRIPTION));
+        }
+    }
+
+    private void parseTypes(String childObjectKey, LinkedHashMap<String, Object> childNodeMap, JSONObject childObject,
+        Map<String, JSONObject> jsonEntrySchema, LinkedHashMap<String, Object> dataNodes, JSONArray array, int order) {
+        if (childNodeMap.get(ToscaSchemaConstants.TYPE) != null) {
+            // Only known value of type is String for now
+            if (childNodeMap.get(ToscaSchemaConstants.TYPE) instanceof String) {
+                childObject.put(JsonEditorSchemaConstants.PROPERTY_ORDER, order);
+                String typeValue = (String) childNodeMap.get(ToscaSchemaConstants.TYPE);
+                if (typeValue.equalsIgnoreCase(ToscaSchemaConstants.TYPE_INTEGER)) {
+                    childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_INTEGER);
+
+                } else if (typeValue.equalsIgnoreCase(ToscaSchemaConstants.TYPE_FLOAT)) {
+                    childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_INTEGER);
+                } else if (typeValue.equalsIgnoreCase(ToscaSchemaConstants.TYPE_LIST)) {
+                    childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_ARRAY);
+                    // Custom key for JSON Editor and UI rendering
+                    childObject.put(JsonEditorSchemaConstants.CUSTOM_KEY_FORMAT,
+                        JsonEditorSchemaConstants.CUSTOM_KEY_FORMAT_TABS_TOP);
+                    childObject.put(JsonEditorSchemaConstants.UNIQUE_ITEMS, JsonEditorSchemaConstants.TRUE);
+                } else if (typeValue.equalsIgnoreCase(ToscaSchemaConstants.TYPE_MAP)) {
+                    childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_OBJECT);
+                } else if (typeValue.contains(ToscaSchemaConstants.POLICY_DATA)) {
+                    JSONArray childArray = new JSONArray();
+
+                    if (jsonEntrySchema.get(typeValue) != null) {
+                        // Already traversed
+                        JSONObject entrySchemaObject = jsonEntrySchema.get(typeValue);
+                        attachTypeJsonObject(childObject, entrySchemaObject);
+                    } else if (dataNodes.containsKey(typeValue)) {
+                        JSONObject entrySchemaObject = new JSONObject();
+                        // Need to traverse
+                        JSONArray jsonArray = new JSONArray();
+                        ((LinkedHashMap<String, Object>) dataNodes.get(typeValue)).entrySet().stream().forEach(pmap -> {
+                            if (pmap.getKey().equalsIgnoreCase(ToscaSchemaConstants.PROPERTIES)) {
+
+                                ((LinkedHashMap<String, Object>) pmap.getValue()).entrySet().stream().forEach(p -> {
+                                    if (p.getValue() instanceof Map) {
+                                        LinkedHashMap<String, Object> childNodeMap2 = (LinkedHashMap<String, Object>) p
+                                            .getValue();
+                                        if (childNodeMap2.containsKey(ToscaSchemaConstants.TYPE)
+                                            && (((String) childNodeMap2.get(ToscaSchemaConstants.TYPE))
+                                                .contains(ToscaSchemaConstants.POLICY_DATA))) {
+                                        }
+                                    }
+                                });
+                            }
+                        });
+                        ((LinkedHashMap<String, Object>) dataNodes.get(typeValue)).entrySet().stream().forEach(pmap -> {
+                            if (pmap.getKey().equalsIgnoreCase(ToscaSchemaConstants.PROPERTIES)) {
+                                parseToscaPropertiesForType(childObjectKey,
+                                    (LinkedHashMap<String, Object>) pmap.getValue(), entrySchemaObject, childArray,
+                                    jsonEntrySchema, dataNodes, true, incrementComplexSimpleTypeOrder());
+                                jsonEntrySchema.put(typeValue, entrySchemaObject);
+                                dataNodes.remove(typeValue);
+                                attachTypeJsonObject(childObject, entrySchemaObject);
+                            }
+                        });
+                    }
+                } else {
+                    childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_STRING);
+                }
+            }
+            if (childNodeMap.get(ToscaSchemaConstants.DEFAULT) != null) {
+                childObject.put(JsonEditorSchemaConstants.DEFAULT, childNodeMap.get(ToscaSchemaConstants.DEFAULT));
+            }
+        }
+    }
+
+    private void parseConstraints(LinkedHashMap<String, Object> childNodeMap, JSONObject childObject) {
+        if (childNodeMap.containsKey(ToscaSchemaConstants.CONSTRAINTS)
+            && childNodeMap.get(ToscaSchemaConstants.CONSTRAINTS) != null) {
+            List<LinkedHashMap<String, Object>> constraintsList = (List<LinkedHashMap<String, Object>>) childNodeMap
+                .get(ToscaSchemaConstants.CONSTRAINTS);
+            constraintsList.stream().forEach(c -> {
+                if (c instanceof Map) {
+                    c.entrySet().stream().forEach(constraint -> {
+                        if (constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.MIN_LENGTH)
+                            || constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.GREATER_OR_EQUAL)) {
+                            // For String min_lenghth is minimum length whereas for number, it will be
+                            // minimum or greater than to the defined value
+                            if (childNodeMap.containsKey(ToscaSchemaConstants.TYPE)
+                                && (childNodeMap.get(ToscaSchemaConstants.TYPE) instanceof String)
+                                && ((String) childNodeMap.get(ToscaSchemaConstants.TYPE))
+                                    .equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING)) {
+                                childObject.put(JsonEditorSchemaConstants.MIN_LENGTH, constraint.getValue());
+                            } else {
+                                childObject.put(JsonEditorSchemaConstants.MINIMUM, constraint.getValue());
+                            }
+                        } else if (constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.MAX_LENGTH)
+                            || constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.LESS_OR_EQUAL)) {
+                            // For String max_lenghth is maximum length whereas for number, it will be
+                            // maximum or less than the defined value
+                            if (childNodeMap.containsKey(ToscaSchemaConstants.TYPE)
+                                && (childNodeMap.get(ToscaSchemaConstants.TYPE) instanceof String)
+                                && ((String) childNodeMap.get(ToscaSchemaConstants.TYPE))
+                                    .equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING)) {
+                                childObject.put(JsonEditorSchemaConstants.MAX_LENGTH, constraint.getValue());
+                            } else {
+                                childObject.put(JsonEditorSchemaConstants.MAXIMUM, constraint.getValue());
+                            }
+                        } else if (constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.LESS_THAN)) {
+                            childObject.put(JsonEditorSchemaConstants.EXCLUSIVE_MAXIMUM, constraint.getValue());
+                        } else if (constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.GREATER_THAN)) {
+                            childObject.put(JsonEditorSchemaConstants.EXCLUSIVE_MINIMUM, constraint.getValue());
+                        } else if (constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.IN_RANGE)) {
+                            if (constraint.getValue() instanceof ArrayList<?>) {
+                                if (childNodeMap.containsKey(ToscaSchemaConstants.TYPE)
+                                    && (childNodeMap.get(ToscaSchemaConstants.TYPE) instanceof String)
+                                    && ((String) childNodeMap.get(ToscaSchemaConstants.TYPE))
+                                        .equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING)) {
+                                    childObject.put(JsonEditorSchemaConstants.MIN_LENGTH,
+                                        ((ArrayList) constraint.getValue()).get(0));
+                                    childObject.put(JsonEditorSchemaConstants.MAX_LENGTH,
+                                        ((ArrayList) constraint.getValue()).get(1));
+                                } else {
+                                    childObject.put(JsonEditorSchemaConstants.MINIMUM,
+                                        ((ArrayList) constraint.getValue()).get(0));
+                                    childObject.put(JsonEditorSchemaConstants.MAXIMUM,
+                                        ((ArrayList) constraint.getValue()).get(1));
+                                }
+
+                            }
+                        } else if (constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.VALID_VALUES)) {
+                            JSONArray validValuesArray = new JSONArray();
+
+                            if (constraint.getValue() instanceof ArrayList<?>) {
+                                boolean processDictionary = ((ArrayList<?>) constraint.getValue()).stream()
+                                    .anyMatch(value -> (value instanceof String
+                                        && ((String) value).contains(ToscaSchemaConstants.DICTIONARY)));
+                                if (!processDictionary) {
+                                    ((ArrayList<?>) constraint.getValue()).stream().forEach(value -> {
+                                        validValuesArray.put(value);
+                                    });
+                                    childObject.put(JsonEditorSchemaConstants.ENUM, validValuesArray);
+                                } else {
+                                    ((ArrayList<?>) constraint.getValue()).stream().forEach(value -> {
+                                        if ((value instanceof String
+                                            && ((String) value).contains(ToscaSchemaConstants.DICTIONARY))) {
+                                            processDictionaryElements(childObject, (String) value);
+                                        }
+
+                                    });
+
+                                }
+                            }
+
+                        }
+                    });
+                }
+            });
+        }
+    }
+
+    private void processDictionaryElements(JSONObject childObject, String dictionaryReference) {
+
+        if (dictionaryReference.contains("#")) {
+            String[] dictionaryKeyArray = dictionaryReference
+                .substring(dictionaryReference.indexOf(ToscaSchemaConstants.DICTIONARY) + 11,
+                    dictionaryReference.length())
+                .split("#");
+            // We support only one # as of now.
+            List<CldsDictionaryItem> cldsDictionaryElements = null;
+            List<CldsDictionaryItem> subDictionaryElements = null;
+            if (dictionaryKeyArray != null && dictionaryKeyArray.length == 2) {
+                cldsDictionaryElements = getCldsDao().getDictionaryElements(dictionaryKeyArray[0], null, null);
+                subDictionaryElements = getCldsDao().getDictionaryElements(dictionaryKeyArray[1], null, null);
+
+                if (cldsDictionaryElements != null) {
+                    List<String> subCldsDictionaryNames = subDictionaryElements.stream()
+                        .map(CldsDictionaryItem::getDictElementShortName).collect(Collectors.toList());
+                    JSONArray jsonArray = new JSONArray();
+
+                    Optional.ofNullable(cldsDictionaryElements).get().stream().forEach(c -> {
+                        JSONObject jsonObject = new JSONObject();
+                        jsonObject.put(JsonEditorSchemaConstants.TYPE, getJsonType(c.getDictElementType()));
+                        if (c.getDictElementType() != null
+                            && c.getDictElementType().equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING)) {
+                            jsonObject.put(JsonEditorSchemaConstants.MIN_LENGTH, 1);
+                        }
+                        jsonObject.put(JsonEditorSchemaConstants.ID, c.getDictElementName());
+                        jsonObject.put(JsonEditorSchemaConstants.LABEL, c.getDictElementShortName());
+                        jsonObject.put(JsonEditorSchemaConstants.OPERATORS, subCldsDictionaryNames);
+                        jsonArray.put(jsonObject);
+                    });
+                    ;
+                    JSONObject filterObject = new JSONObject();
+                    filterObject.put(JsonEditorSchemaConstants.FILTERS, jsonArray);
+
+                    childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_QBLDR);
+                    // TO invoke validation on such parameters
+                    childObject.put(JsonEditorSchemaConstants.MIN_LENGTH, 1);
+                    childObject.put(JsonEditorSchemaConstants.QSSCHEMA, filterObject);
+
+                }
+            }
+        } else {
+            String dictionaryKey = dictionaryReference.substring(
+                dictionaryReference.indexOf(ToscaSchemaConstants.DICTIONARY) + 11, dictionaryReference.length());
+            if (dictionaryKey != null) {
+                List<CldsDictionaryItem> cldsDictionaryElements = getCldsDao().getDictionaryElements(dictionaryKey,
+                    null, null);
+                if (cldsDictionaryElements != null) {
+                    List<String> cldsDictionaryNames = new ArrayList<>();
+                    List<String> cldsDictionaryFullNames = new ArrayList<>();
+                    cldsDictionaryElements.stream().forEach(c -> {
+                        // Json type will be translated before Policy creation
+                        if (c.getDictElementType() != null && !c.getDictElementType().equalsIgnoreCase("json")) {
+                            cldsDictionaryFullNames.add(c.getDictElementName());
+                        }
+                        cldsDictionaryNames.add(c.getDictElementShortName());
+                    });
+
+                    if (cldsDictionaryFullNames.size() > 0) {
+                        childObject.put(JsonEditorSchemaConstants.ENUM, cldsDictionaryFullNames);
+                        // Add Enum titles for generated translated values during JSON instance
+                        // generation
+                        JSONObject enumTitles = new JSONObject();
+                        enumTitles.put(JsonEditorSchemaConstants.ENUM_TITLES, cldsDictionaryNames);
+                        childObject.put(JsonEditorSchemaConstants.OPTIONS, enumTitles);
+                    } else {
+                        childObject.put(JsonEditorSchemaConstants.ENUM, cldsDictionaryNames);
+                    }
+
+                }
+            }
+        }
+    }
+
+    private String getJsonType(String toscaType) {
+        String jsonType = null;
+        if (toscaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_INTEGER)) {
+            jsonType = JsonEditorSchemaConstants.TYPE_INTEGER;
+        } else if (toscaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_LIST)) {
+            jsonType = JsonEditorSchemaConstants.TYPE_ARRAY;
+        } else {
+            jsonType = JsonEditorSchemaConstants.TYPE_STRING;
+        }
+        return jsonType;
+    }
+
+}
\ No newline at end of file
index a6a209a..293f0e6 100644 (file)
@@ -77,7 +77,7 @@ public class OperationalPolicyAttributesConstructorTest {
         // then
         Assertions.assertThat(requestAttributes).containsKeys(AttributeType.MATCHING, AttributeType.RULE);
         Assertions.assertThat(requestAttributes.get(AttributeType.MATCHING))
-        .contains(Assertions.entry(OperationalPolicyAttributesConstructor.CONTROLLER, "amsterdam"));
+            .contains(Assertions.entry(OperationalPolicyAttributesConstructor.CONTROLLER, "amsterdam"));
 
         Map<String, String> ruleParameters = requestAttributes.get(AttributeType.RULE);
         Assertions.assertThat(ruleParameters).containsExactly(
@@ -97,8 +97,8 @@ public class OperationalPolicyAttributesConstructorTest {
         // given
         ClampProperties mockClampProperties = createMockClampProperties(
             ImmutableMap.<String, String>builder().put("op.templateName", "ClosedLoopControlName")
-            .put("op.operationTopic", "APPP-CL").put("op.notificationTopic", "POLICY-CL-MGT")
-            .put("op.controller", "amsterdam").put("op.recipeTopic", "APPC").build());
+                .put("op.operationTopic", "APPP-CL").put("op.notificationTopic", "POLICY-CL-MGT")
+                .put("op.controller", "amsterdam").put("op.recipeTopic", "APPC").build());
 
         Policy expectedPolicy = new Policy("6f76ad0b-ea9d-4a92-8d7d-6a6367ce2c77", "healthCheck Policy",
             "healthCheck Policy - the trigger (no parent) policy - created by CLDS", "APPC", null,
@@ -112,7 +112,7 @@ public class OperationalPolicyAttributesConstructorTest {
         // then
         Assertions.assertThat(requestAttributes).containsKeys(AttributeType.MATCHING, AttributeType.RULE);
         Assertions.assertThat(requestAttributes.get(AttributeType.MATCHING))
-        .contains(Assertions.entry("controller", "amsterdam"));
+            .contains(Assertions.entry("controller", "amsterdam"));
 
         Map<String, String> ruleParameters = requestAttributes.get(AttributeType.RULE);
         Assertions.assertThat(ruleParameters).contains(
@@ -127,7 +127,7 @@ public class OperationalPolicyAttributesConstructorTest {
 
         Assertions.assertThat(controlLoopPolicy.getControlLoop().getControlLoopName()).isEqualTo(CONTROL_NAME);
         Assertions.assertThat(controlLoopPolicy.getPolicies()).usingElementComparatorIgnoringFields("id")
-        .containsExactly(expectedPolicy);
+            .containsExactly(expectedPolicy);
     }
 
     private ClampProperties createMockClampProperties(ImmutableMap<String, String> propertiesMap) {
diff --git a/src/test/java/org/onap/clamp/clds/it/CldsDictionaryServiceItCase.java b/src/test/java/org/onap/clamp/clds/it/CldsDictionaryServiceItCase.java
new file mode 100644 (file)
index 0000000..d31d5a0
--- /dev/null
@@ -0,0 +1,161 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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.
+ * 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.it;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.onap.clamp.clds.model.CldsDictionary;
+import org.onap.clamp.clds.model.CldsDictionaryItem;
+import org.onap.clamp.clds.service.CldsDictionaryService;
+import org.onap.clamp.clds.util.LoggingUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * Test CLDS Dictionary Service APIs.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class CldsDictionaryServiceItCase {
+
+    protected static final EELFLogger logger = EELFManager.getInstance().getLogger(CldsDictionaryServiceItCase.class);
+    @Autowired
+    private CldsDictionaryService cldsDictionaryService;
+    private Authentication authentication;
+    private CldsDictionary cldsDictionary;
+    private CldsDictionaryItem cldsDictionaryItem;
+    private List<GrantedAuthority> authList = new LinkedList<GrantedAuthority>();
+    private LoggingUtils util;
+
+    /**
+     * Setup the variable before the tests execution.
+     *
+     * @throws IOException
+     *         In case of issues when opening the files
+     */
+    @Before
+    public void setupBefore() throws IOException {
+        authList.add(new SimpleGrantedAuthority("permission-type-cl|dev|read"));
+        authList.add(new SimpleGrantedAuthority("permission-type-cl|dev|update"));
+        authList.add(new SimpleGrantedAuthority("permission-type-template|dev|read"));
+        authList.add(new SimpleGrantedAuthority("permission-type-template|dev|update"));
+        authList.add(new SimpleGrantedAuthority("permission-type-filter-vf|dev|*"));
+        authList.add(new SimpleGrantedAuthority("permission-type-tosca|dev|read"));
+        authList.add(new SimpleGrantedAuthority("permission-type-tosca|dev|update"));
+        authentication = new UsernamePasswordAuthenticationToken(new User("admin", "", authList), "", authList);
+
+        SecurityContext securityContext = Mockito.mock(SecurityContext.class);
+        Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
+
+        util = Mockito.mock(LoggingUtils.class);
+        Mockito.doNothing().when(util).entering(Matchers.any(HttpServletRequest.class), Matchers.any(String.class));
+        cldsDictionaryService.setLoggingUtil(util);
+
+        cldsDictionaryService.setSecurityContext(securityContext);
+
+        cldsDictionary = new CldsDictionary();
+
+        cldsDictionary.setDictionaryName("TestDictionary");
+        ResponseEntity entity = cldsDictionaryService.createOrUpdateDictionary("TestDictionary", cldsDictionary);
+        cldsDictionary = (CldsDictionary) entity.getBody();
+
+        cldsDictionaryItem = new CldsDictionaryItem();
+        cldsDictionaryItem.setDictElementShortName("TestDictionaryItemShortName");
+        cldsDictionaryItem.setDictElementName("TestDictionaryItemName");
+        cldsDictionaryItem.setDictElementType("string");
+        cldsDictionaryItem.setDictionaryId(cldsDictionary.getDictionaryId());
+        cldsDictionaryItem.setDictElementDesc("TestDictionaryItemDesc");
+        cldsDictionaryService.createOrUpdateDictionaryElements("TestDictionary", cldsDictionaryItem);
+
+        logger.info("Initial Clds Dictionary uploaded in DB:" + cldsDictionaryItem);
+    }
+
+    @Test
+    public void testCreateOrUpdateDictionary() throws Exception {
+        ResponseEntity<CldsDictionary> responseEntity = cldsDictionaryService.createOrUpdateDictionary("TestDictionary",
+            cldsDictionary);
+        CldsDictionary dictionary = responseEntity.getBody();
+        assertNotNull(dictionary);
+        logger.info("CLDS Dictionary is:" + dictionary);
+        assertEquals("TestDictionary", dictionary.getDictionaryName());
+    }
+
+    @Test
+    public void testCreateOrUpdateDictionaryElements() throws Exception {
+        cldsDictionaryItem = new CldsDictionaryItem();
+        cldsDictionaryItem.setDictElementShortName("TestDictionaryItemShortName1");
+        cldsDictionaryItem.setDictElementName("TestDictionaryItemName1");
+        cldsDictionaryItem.setDictElementType("string");
+        cldsDictionaryItem.setDictionaryId(cldsDictionary.getDictionaryId());
+        cldsDictionaryItem.setDictElementDesc("TestDictionaryItemDesc1");
+
+        ResponseEntity<CldsDictionaryItem> responseEntity = cldsDictionaryService
+            .createOrUpdateDictionaryElements("TestDictionary", cldsDictionaryItem);
+        CldsDictionaryItem dictionaryItem = responseEntity.getBody();
+        assertNotNull(dictionaryItem);
+        logger.info("CLDS Dictionary Item is:" + dictionaryItem);
+        assertEquals("TestDictionaryItemName1", dictionaryItem.getDictElementName());
+    }
+
+    @Test
+    public void testGetAllDictionaryNames() throws Exception {
+        ResponseEntity<List<CldsDictionary>> responseEntity = cldsDictionaryService.getAllDictionaryNames();
+        List<CldsDictionary> dictionaries = responseEntity.getBody();
+        assertNotNull(dictionaries);
+        logger.info("CLDS Dictionary List is:" + dictionaries);
+    }
+
+    @Test
+    public void testGetDictionaryElementsByName() throws Exception {
+        ResponseEntity<List<CldsDictionaryItem>> responseEntity = cldsDictionaryService
+            .getDictionaryElementsByName("TestDictionary");
+        List<CldsDictionaryItem> dictionaryItems = responseEntity.getBody();
+        assertNotNull(dictionaryItems);
+        logger.info("CLDS Dictionary Item LIst is:" + dictionaryItems);
+    }
+}
index e8d52c0..ff65f42 100644 (file)
@@ -54,6 +54,7 @@ import org.onap.clamp.clds.dao.CldsDao;
 import org.onap.clamp.clds.model.CldsEvent;
 import org.onap.clamp.clds.model.CldsInfo;
 import org.onap.clamp.clds.model.CldsModel;
+import org.onap.clamp.clds.model.CldsMonitoringDetails;
 import org.onap.clamp.clds.model.CldsServiceData;
 import org.onap.clamp.clds.model.CldsTemplate;
 import org.onap.clamp.clds.model.DcaeEvent;
@@ -120,6 +121,7 @@ public class CldsServiceItCase {
         util = Mockito.mock(LoggingUtils.class);
         Mockito.doNothing().when(util).entering(Matchers.any(HttpServletRequest.class), Matchers.any(String.class));
         cldsService.setLoggingUtil(util);
+
     }
 
     @Test
@@ -158,6 +160,12 @@ public class CldsServiceItCase {
         assertEquals(cldsInfo.getUserName(), "admin");
     }
 
+    @Test
+    public void testGetCLDSDetails() throws IOException {
+        List<CldsMonitoringDetails> cldsMonitoringDetailsList = cldsService.getCLDSDetails();
+        assertNotNull(cldsMonitoringDetailsList);
+    }
+
     @Test
     public void testCompleteFlow() throws TransformerException, ParseException {
         SecurityContext securityContext = Mockito.mock(SecurityContext.class);
@@ -190,6 +198,10 @@ public class CldsServiceItCase {
         // Test the PutModel method
 
         cldsService.putModel(randomNameModel, newModel);
+
+        assertEquals(bpmnText, cldsService.getBpmnXml(randomNameModel));
+        assertEquals(imageText, cldsService.getImageXml(randomNameModel));
+
         // Verify whether it has been added properly or not
         assertNotNull(cldsDao.getModel(randomNameModel));
 
diff --git a/src/test/java/org/onap/clamp/clds/it/CldsToscaServiceItCase.java b/src/test/java/org/onap/clamp/clds/it/CldsToscaServiceItCase.java
new file mode 100644 (file)
index 0000000..407e0c5
--- /dev/null
@@ -0,0 +1,141 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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.
+ * 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.it;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.model.CldsToscaModel;
+import org.onap.clamp.clds.service.CldsToscaService;
+import org.onap.clamp.clds.util.LoggingUtils;
+import org.onap.clamp.clds.util.ResourceFileUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+/**
+ * Test CLDS Tosca Service APIs.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class CldsToscaServiceItCase {
+    
+    protected static final EELFLogger logger = EELFManager.getInstance().getLogger(CldsToscaServiceItCase.class);
+    @Autowired
+    private CldsToscaService cldsToscaService;
+    @Autowired
+    private CldsDao cldsDao;
+    private String toscaModelYaml;
+    private Authentication authentication;
+    private CldsToscaModel cldsToscaModel;
+    private List<GrantedAuthority> authList =  new LinkedList<GrantedAuthority>();
+    private LoggingUtils util;
+    
+    /**
+     * Setup the variable before the tests execution.
+     * 
+     * @throws IOException
+     *             In case of issues when opening the files
+     */
+    @Before
+    public void setupBefore() throws IOException {
+        authList.add(new SimpleGrantedAuthority("permission-type-cl|dev|read"));
+        authList.add(new SimpleGrantedAuthority("permission-type-cl|dev|update"));
+        authList.add(new SimpleGrantedAuthority("permission-type-template|dev|read"));
+        authList.add(new SimpleGrantedAuthority("permission-type-template|dev|update"));
+        authList.add(new SimpleGrantedAuthority("permission-type-filter-vf|dev|*"));
+        authList.add(new SimpleGrantedAuthority("permission-type-tosca|dev|read"));
+        authList.add(new SimpleGrantedAuthority("permission-type-tosca|dev|update"));
+        authentication =  new UsernamePasswordAuthenticationToken(new User("admin", "", authList), "", authList);
+
+        SecurityContext securityContext = Mockito.mock(SecurityContext.class);
+        Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
+
+        util = Mockito.mock(LoggingUtils.class);
+        Mockito.doNothing().when(util).entering(Matchers.any(HttpServletRequest.class), Matchers.any(String.class));
+        cldsToscaService.setLoggingUtil(util);
+
+        cldsToscaService.setSecurityContext(securityContext);
+        
+        toscaModelYaml = ResourceFileUtil.getResourceAsString("tosca/tca-policy-test.yaml");
+        
+        cldsToscaModel = new CldsToscaModel();
+        cldsToscaModel.setToscaModelName("tca-policy-test");
+        cldsToscaModel.setToscaModelYaml(toscaModelYaml);
+        cldsToscaModel.setUserId("admin");
+        cldsToscaModel.setPolicyType("tca");
+        cldsToscaService.parseToscaModelAndSave("tca-policy-test", cldsToscaModel);
+        logger.info("Initial Tosca Model uploaded in DB:" + cldsToscaModel);
+    }
+    
+    @Test
+    public void testParseToscaModelAndSave() throws Exception {
+        ResponseEntity responseEntity = cldsToscaService.parseToscaModelAndSave("tca-policy-test", cldsToscaModel);
+        CldsToscaModel savedModel = (CldsToscaModel) responseEntity.getBody();
+        assertNotNull(savedModel);
+        logger.info("Parsed Tosca Model is:" + savedModel);
+        assertEquals("tca-policy-test", savedModel.getToscaModelName());
+    }
+
+    @Test
+    public void testGetToscaModel() throws Exception {
+        ResponseEntity<CldsToscaModel> responseEntity = cldsToscaService.getToscaModel("tca-policy-test");
+        CldsToscaModel savedModel = responseEntity.getBody();
+        assertNotNull(savedModel);
+        assertEquals("tca-policy-test", savedModel.getToscaModelName());
+    }
+    
+    @Test
+    public void testGetToscaModelsByPolicyType() throws Exception {
+        ResponseEntity<CldsToscaModel> responseEntity = cldsToscaService.getToscaModelsByPolicyType("tca");
+        CldsToscaModel savedModel = responseEntity.getBody();
+        assertNotNull(savedModel);
+        assertEquals("tca-policy-test", savedModel.getToscaModelName());
+        assertEquals("tca", savedModel.getPolicyType());
+    }
+    
+}
index 95e29c0..37eb6ae 100644 (file)
@@ -18,7 +18,7 @@
  * limitations under the License.
  * ============LICENSE_END============================================
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.it.config;
@@ -26,10 +26,12 @@ package org.onap.clamp.clds.it.config;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import java.io.IOException;
+import java.util.List;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -64,7 +66,7 @@ public class CldsReferencePropertiesItCase {
      * Test getting prop value as a JSON Node / template.
      *
      * @throws IOException
-     *             when JSON parsing fails
+     *         when JSON parsing fails
      */
     @Test
     public void testGetJsonTemplate() throws IOException {
@@ -85,7 +87,7 @@ public class CldsReferencePropertiesItCase {
      * Test getting prop value as a JSON Node / template.
      *
      * @throws IOException
-     *             when JSON parsing fails
+     *         when JSON parsing fails
      */
     @Test
     public void testGetFileContent() throws IOException {
@@ -95,4 +97,13 @@ public class CldsReferencePropertiesItCase {
         content = refProp.getFileContent("sdc.decode", "service_ids");
         assertEquals("{}", content);
     }
+
+    @Test
+    public void testGetStringList() {
+        List<String> profileList = refProp.getStringList("policy.pdpUrl1", ",");
+        assertTrue(profileList.size() == 3);
+        assertTrue(profileList.get(0).trim().equals("http://localhost:8085/pdp/"));
+        assertTrue(profileList.get(1).trim().equals("testpdp"));
+        assertTrue(profileList.get(2).trim().equals("alpha123"));
+    }
 }
diff --git a/src/test/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertorTest.java b/src/test/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertorTest.java
new file mode 100644 (file)
index 0000000..d94ffab
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 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.
+ * 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.tosca;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.onap.clamp.clds.util.ResourceFileUtil;
+import org.skyscreamer.jsonassert.JSONAssert;
+
+public class ToscaYamlToJsonConvertorTest {
+
+    /**
+     * This Test validates TOSCA yaml to JSON Schema conversion based on JSON Editor
+     * Schema.
+     *
+     * @throws IOException
+     *
+     */
+    @Test
+    public final void testParseToscaYaml() throws IOException {
+        String toscaModelYaml = ResourceFileUtil.getResourceAsString("tosca/tosca_example.yaml");
+        ToscaYamlToJsonConvertor convertor = new ToscaYamlToJsonConvertor(null);
+
+        String parsedJsonSchema = convertor.parseToscaYaml(toscaModelYaml);
+        assertNotNull(parsedJsonSchema);
+        JSONAssert.assertEquals(
+            ResourceFileUtil.getResourceAsString("example/json-editor-schema/tca-policy-json-editor-schema.json"),
+            parsedJsonSchema, true);
+    }
+}
index e482d68..1d9e4e7 100644 (file)
@@ -5,20 +5,20 @@
  * Copyright (C) 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.util;
@@ -73,21 +73,22 @@ public class JacksonUtilsTest {
     /**
      * This method test that the security hole in Jackson is not enabled in the
      * default ObjectMapper.
-     * 
+     *
      * @throws JsonParseException
-     *             In case of issues
+     *         In case of issues
      * @throws JsonMappingException
-     *             In case of issues
+     *         In case of issues
      * @throws IOException
-     *             In case of issues
+     *         In case of issues
      */
     @Test
     public void testCreateBeanDeserializer() throws JsonParseException, JsonMappingException, IOException {
         TestClass test = new TestClass("value1", "value2");
         test.setObject2(new TestObject2("test3"));
-        Object testObject = JacksonUtils.getObjectMapperInstance().readValue(
-                "[\"org.onap.clamp.clds.util.JacksonUtilsTest$TestClass\",{\"test\":\"value1\",\"test2\":\"value2\",\"object2\":[\"org.onap.clamp.clds.util.TestObject2\",{\"test3\":\"test3\"}]}]",
-                Object.class);
+        Object testObject = JacksonUtils.getObjectMapperInstance()
+            .readValue("[\"org.onap.clamp.clds.util.JacksonUtilsTest$TestClass\""
+                + ",{\"test\":\"value1\",\"test2\":\"value2\",\"object2\":[\"org.onap.clamp.clds.util.TestObject2\","
+                + "{\"test3\":\"test3\"}]}]", Object.class);
         assertNotNull(testObject);
         assertFalse(testObject instanceof TestObject);
         assertFalse(testObject instanceof TestClass);
diff --git a/src/test/resources/clds/camel/routes/flexible-flow.xml b/src/test/resources/clds/camel/routes/flexible-flow.xml
new file mode 100644 (file)
index 0000000..8305c2e
--- /dev/null
@@ -0,0 +1,50 @@
+<routes xmlns="http://camel.apache.org/schema/spring">
+               <route id="submit">
+                               <from uri="direct:processSubmit" />
+                               <choice>
+                                               <when>
+                                                               <simple> ${exchangeProperty.actionCd} == 'SUBMIT' || ${exchangeProperty.actionCd} == 'RESUBMIT'</simple>
+                                                               <to uri="bean:org.onap.clamp.clds.client.TcaPolicyDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.HolmesPolicyDelegate" />
+                                                               <delay>
+                                                                               <constant>30000</constant>
+                                                               </delay>
+                                                               <to uri="bean:org.onap.clamp.clds.client.OperationalPolicyDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.CldsEventDelegate" />
+                                               </when>
+                                               <when>
+                                                               <simple> ${exchangeProperty.actionCd} == 'DELETE'</simple>
+                                                               <to uri="bean:org.onap.clamp.clds.client.TcaPolicyDeleteDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.HolmesPolicyDeleteDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.ModelDeleteDelegate" />
+                                                               <delay>
+                                                                               <constant>30000</constant>
+                                                               </delay>
+                                                               <to
+                                                                               uri="bean:org.onap.clamp.clds.client.OperationalPolicyDeleteDelegate" />
+                                               </when>
+                                               <when>
+                                                               <simple> ${exchangeProperty.actionCd} == 'UPDATE'</simple>
+                                                               <to uri="bean:org.onap.clamp.clds.client.TcaPolicyDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.HolmesPolicyDelegate" />
+                                                               <delay>
+                                                                               <constant>30000</constant>
+                                                               </delay>
+                                                               <to uri="bean:org.onap.clamp.clds.client.OperationalPolicyDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.CldsEventDelegate" />
+                                               </when>
+                                               <when>
+                                                               <simple> ${exchangeProperty.actionCd} == 'STOP'</simple>
+                                                               <to
+                                                                               uri="bean:org.onap.clamp.clds.client.OperationalPolicyDeleteDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.CldsEventDelegate" />
+                                               </when>
+                                               <when>
+                                                               <simple> ${exchangeProperty.actionCd} == 'RESTART'</simple>
+                                                               <to uri="bean:org.onap.clamp.clds.client.OperationalPolicyDelegate" />
+                                                               <to uri="bean:org.onap.clamp.clds.client.CldsEventDelegate" />
+                                               </when>
+                               </choice>
+               </route>
+
+</routes>
\ No newline at end of file
diff --git a/src/test/resources/example/json-editor-schema/tca-policy-json-editor-schema.json b/src/test/resources/example/json-editor-schema/tca-policy-json-editor-schema.json
new file mode 100644 (file)
index 0000000..11b91df
--- /dev/null
@@ -0,0 +1,115 @@
+{
+       "schema": {
+               "uniqueItems": "true",
+               "format": "tabs-top",
+               "type": "array",
+               "title": "Thresholds",
+               "items": {
+                       "type": "object",
+                       "title": "Thresholds",
+                       "required": [
+                               "dummySignatures"
+                       ],
+                       "properties": {
+                               "severity": {
+                                       "propertyOrder": 1004,
+                                       "title": "event severity or priority",
+                                       "type": "string",
+                                       "enum": [
+                                               "CRITICAL",
+                                               "MAJOR",
+                                               "MINOR",
+                                               "WARNING",
+                                               "NORMAL"
+                                       ]
+                               },
+                               "fieldPath": {
+                                       "propertyOrder": 1003,
+                                       "title": "Field Path",
+                                       "type": "string"
+                               },
+                               "thresholdValue": {
+                                       "propertyOrder": 1005,
+                                       "default": 0,
+                                       "maximum": 65535,
+                                       "title": "ThresholdValue",
+                                       "type": "integer",
+                                       "minimum": 0
+                               },
+                               "dummySignatures": {
+                                       "propertyOrder": 1007,
+                                       "uniqueItems": "true",
+                                       "format": "tabs-top",
+                                       "title": "dummy Signatures",
+                                       "type": "array",
+                                       "items": {
+                                               "type": "object",
+                                               "required": [
+                                                       "signature",
+                                                       "traversal"
+                                               ],
+                                               "properties": {
+                                                       "signature": {
+                                                               "propertyOrder": 1008,
+                                                               "required": [
+                                                                       "filter_clause"
+                                                               ],
+                                                               "properties": {
+                                                                       "filter_clause": {
+                                                                               "propertyOrder": 20002,
+                                                                               "title": "Filter Clause",
+                                                                               "type": "string",
+                                                                               "enum": [
+                                                                                       "OR",
+                                                                                       "AND",
+                                                                                       "NOT"
+                                                                               ]
+                                                                       }
+                                                               }
+                                                       },
+                                                       "traversal": {
+                                                               "propertyOrder": 1009,
+                                                               "required": [
+                                                                       "traversal"
+                                                               ],
+                                                               "properties": {
+                                                                       "traversal": {
+                                                                               "propertyOrder": 20003,
+                                                                               "title": "Dummy Traverse",
+                                                                               "type": "string",
+                                                                               "enum": [
+                                                                                       "ONE",
+                                                                                       "TWO",
+                                                                                       "THREE"
+                                                                               ]
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "closedLoopControlName": {
+                                       "propertyOrder": 1001,
+                                       "title": "A UNIQUE string identifying the Closed Loop ID this event is for.",
+                                       "type": "string"
+                               },
+                               "version": {
+                                       "propertyOrder": 1006,
+                                       "minLength": 1,
+                                       "title": "Version for the closed loop message",
+                                       "type": "string"
+                               },
+                               "direction": {
+                                       "propertyOrder": 1002,
+                                       "type": "string",
+                                       "enum": [
+                                               "LESS",
+                                               "LESS_OR_EQUAL",
+                                               "GREATER",
+                                               "GREATER_OR_EQUAL"
+                                       ]
+                               }
+                       }
+               }
+       }
+}
\ No newline at end of file
index a8ff96a..178ac80 100755 (executable)
@@ -49,4 +49,4 @@ done
 echo 'Installing requests packages for Python'
 pip install requests
 echo 'Executing the Http proxy in Cache mode only'
-python third_party_proxy.py --port 8080 --root /usr/src/http-cache-app/data-cache $python_proxyaddress
+python -u third_party_proxy.py --port 8080 --root /usr/src/http-cache-app/data-cache $python_proxyaddress
index fdc4fab..a109241 100755 (executable)
@@ -25,6 +25,7 @@
 import json
 import requests
 import os
+import errno
 import sys
 import SimpleHTTPServer
 import SocketServer
@@ -37,7 +38,8 @@ import shutil
 parser = argparse.ArgumentParser(description="3rd party Cache & Replay")
 parser.add_argument("--username", "-u", type=str, help="Set the username for contacting 3rd party - only used for GET")
 parser.add_argument("--password", "-p", type=str, help="Set the password for contacting 3rd party - only used for GET")
-parser.add_argument("--root",     "-r", default=tempfile.mkdtemp, type=str, help="Root folder for the proxy cache")
+parser.add_argument("--root",     "-r", default=tempfile.mkdtemp(), type=str, help="Root folder for the proxy cache")
+parser.add_argument("--temp",     "-t", default=tempfile.mkdtemp(), type=str, help="Temp folder for the generated content")
 parser.add_argument("--proxy"         , type=str, help="Url of the  Act as a proxy. If not set, this script only uses the cache and will return a 404 if files aren't found")
 parser.add_argument("--port",     "-P", type=int, default="8081", help="Port on which the proxy should listen to")
 parser.add_argument("--verbose",  "-v", type=bool, help="Print more information in case of error")
@@ -49,8 +51,9 @@ PORT = options.port
 HOST = options.proxy
 AUTH = (options.username, options.password)
 HEADERS = {'X-ECOMP-InstanceID':'CLAMP'}
-CACHE_ROOT = options.root
-PROXY_ADDRESS=options.proxyaddress
+CACHE_ROOT = str(options.root)
+TMP_ROOT = str(options.temp)
+PROXY_ADDRESS=str(options.proxyaddress)
 
 def signal_handler(signal_sent, frame):
     global httpd
@@ -61,7 +64,6 @@ def signal_handler(signal_sent, frame):
         httpd.server_close()
 
 class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
-
     def print_headers(self):
         for header,value in self.headers.items():
             print("header: %s : %s" % (header, value))
@@ -82,238 +84,286 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
             fc = f.read()
             self.wfile.write(fc)
 
-    def _write_cache(self,cached_file, header_file, content_file, response):
-        os.makedirs(cached_file, True)
+    def _write_cache(self,cached_file_folder, header_file, content_file, response):
+        os.makedirs(cached_file_folder, 0777)
         with open(content_file, 'w') as f:
             f.write(response.raw.read())
         with open(header_file, 'w') as f:
             json.dump(dict(response.raw.headers), f)
     # Entry point of the code
+    def _get_cached_file_folder_name(self,folder):
+        cached_file_folder = '%s/%s' % (folder, self.path,)
+        print("Cached file name before escaping : %s" % cached_file_folder)
+        cached_file_folder = cached_file_folder.replace('<','&#60;').replace('>','&#62;').replace('?','&#63;').replace('*','&#42;').replace('\\','&#42;').replace(':','&#58;').replace('|','&#124;')
+        print("Cached file name after escaping (used for cache storage) : %s" % cached_file_folder)
+        return cached_file_folder
+    
+    def _get_cached_content_file_name(self,cached_file_folder):
+        return "%s/.file" % (cached_file_folder,)
+    
+    def _get_cached_header_file_name(self,cached_file_folder):
+        return "%s/.header" % (cached_file_folder,)
+    
+    def _execute_content_generated_cases(self,http_type):
+     print("Testing special cases, cache files will be sent to :" +TMP_ROOT)
+     cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
+     cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+     cached_file_header = self._get_cached_header_file_name(cached_file_folder)
+     _file_available = os.path.exists(cached_file_content)
+    
+     if self.path.startswith("/dcae-service-types?asdcResourceId=") and http_type == "GET":
+        if not _file_available:
+            print "self.path start with /dcae-service-types?asdcResourceId=, generating response json..."
+            uuidGenerated = str(uuid.uuid4())
+            typeId = "typeId-" + uuidGenerated
+            typeName = "typeName-" + uuidGenerated
+            print "typeId generated: " + typeName + " and typeName: "+ typeId
+            jsonGenerated = "{\"totalCount\":1, \"items\":[{\"typeId\":\"" + typeId + "\", \"typeName\":\"" + typeName +"\"}]}"
+            print "jsonGenerated: " + jsonGenerated
+    
+            os.makedirs(cached_file_folder, 0777)
+            with open(cached_file_header, 'w') as f:
+                f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
+            with open(cached_file_content, 'w') as f:
+                f.write(jsonGenerated)
+        return True
+     elif self.path.startswith("/dcae-operationstatus") and http_type == "GET":
+        if not _file_available:
+            print "self.path start with /dcae-operationstatus, generating response json..."
+            jsonGenerated =  "{\"operationType\": \"operationType1\", \"status\": \"succeeded\"}"
+            print "jsonGenerated: " + jsonGenerated
+    
+            try:
+                os.makedirs(cached_file_folder, 0777)
+            except OSError as e:
+                if e.errno != errno.EEXIST:
+                    raise
+                print(cached_file_folder+" already exists")
+    
+            with open(cached_file_header, 'w') as f:
+                f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
+            with open(cached_file_content, 'w') as f:
+                f.write(jsonGenerated)
+        return True
+     elif self.path.startswith("/sdc/v1/catalog/services/") and http_type == "POST":
+        if not _file_available:
+            print "self.path start with /sdc/v1/catalog/services/, generating response json..."
+            jsondata = json.loads(self.data_string)
+            jsonGenerated = "{\"artifactName\":\"" + jsondata['artifactName'] + "\",\"artifactType\":\"" + jsondata['artifactType'] + "\",\"artifactURL\":\"" + self.path + "\",\"artifactDescription\":\"" + jsondata['description'] + "\",\"artifactChecksum\":\"ZjJlMjVmMWE2M2M1OTM2MDZlODlmNTVmZmYzNjViYzM=\",\"artifactUUID\":\"" + str(uuid.uuid4()) + "\",\"artifactVersion\":\"1\"}"
+            print "jsonGenerated: " + jsonGenerated
+    
+            os.makedirs(cached_file_folder, 0777)
+            with open(cached_file_header, 'w') as f:
+                f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
+            with open(cached_file_content, 'w') as f:
+                f.write(jsonGenerated)
+        return True;
+     elif self.path.startswith("/dcae-deployments/") and (http_type == "PUT" or http_type == "DELETE"):
+        if not _file_available:
+            print "self.path start with /dcae-deployments/, generating response json..."
+            #jsondata = json.loads(self.data_string)
+            jsonGenerated = "{\"links\":{\"status\":\"http:\/\/" + PROXY_ADDRESS + "\/dcae-operationstatus\",\"test2\":\"test2\"}}"
+            print "jsonGenerated: " + jsonGenerated
+    
+            os.makedirs(cached_file_folder, 0777)
+            with open(cached_file_header, 'w') as f:
+                f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
+            with open(cached_file_content, 'w') as f:
+                f.write(jsonGenerated)
+        return True
+     else:
+        return False
+
+    
     def do_GET(self):
+        cached_file_folder = ""
+        cached_file_content =""
+        cached_file_header=""
         print("\n\n\nGot a GET request for %s " % self.path)
 
         self.print_headers()
         self.check_credentials()
-
-        cached_file = '%s/%s' % (CACHE_ROOT, self.path,)
-        print("Cached file name before escaping : %s" % cached_file)
-        cached_file = cached_file.replace('<','&#60;').replace('>','&#62;').replace('?','&#63;').replace('*','&#42;').replace('\\','&#42;').replace(':','&#58;').replace('|','&#124;')
-        print("Cached file name after escaping (used for cache storage) : %s" % cached_file)
-        cached_file_content = "%s/.file" % (cached_file,)
-        cached_file_header = "%s/.header" % (cached_file,)
+        # Verify if it's a special case
+        is_special = self._execute_content_generated_cases("GET")
+        if is_special:
+            cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
+        else:
+            cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
 
         _file_available = os.path.exists(cached_file_content)
 
         if not _file_available:
-            print("Request for data currently not present in cache: %s" % (cached_file,))
-
-            if self.path.startswith("/dcae-service-types?asdcResourceId="):
-                print "self.path start with /dcae-service-types?asdcResourceId=, generating response json..."
-                uuidGenerated = str(uuid.uuid4())
-                typeId = "typeId-" + uuidGenerated
-                typeName = "typeName-" + uuidGenerated
-                print "typeId generated: " + typeName + " and typeName: "+ typeId
-                jsonGenerated = "{\"totalCount\":1, \"items\":[{\"typeId\":\"" + typeId + "\", \"typeName\":\"" + typeName +"\"}]}"
-                print "jsonGenerated: " + jsonGenerated
-
-                os.makedirs(cached_file, True)
-                with open(cached_file_header, 'w') as f:
-                    f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
-                with open(cached_file_content, 'w') as f:
-                    f.write(jsonGenerated)
-            elif self.path.startswith("/dcae-operationstatus"):
-                print "self.path start with /dcae-operationstatus, generating response json..."
-                jsonGenerated =  "{\"operationType\": \"operationType1\", \"status\": \"succeeded\"}"
-                print "jsonGenerated: " + jsonGenerated
-
-                os.makedirs(cached_file, True)
-                with open(cached_file_header, 'w') as f:
-                    f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
-                with open(cached_file_content, 'w') as f:
-                    f.write(jsonGenerated)
+            print("Request for data currently not present in cache: %s" % (cached_file_folder,))
+
+            if not HOST:
+                self.send_response(404)
+                return "404 Not found"
+
+            url = '%s%s' % (HOST, self.path)
+            response = requests.get(url, auth=AUTH, headers=HEADERS, stream=True)
+
+            if response.status_code == 200:
+                self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
             else:
-                if not HOST:
-                    self.send_response(404)
-                    return "404 Not found"
-
-                url = '%s%s' % (HOST, self.path)
-                response = requests.get(url, auth=AUTH, headers=HEADERS, stream=True)
-
-                if response.status_code == 200:
-                    self._write_cache(cached_file, cached_file_header, cached_file_content, response)
-                else:
-                    print('Error when requesting file :')
-                    print('Requested url : %s' % (url,))
-                    print('Status code : %s' % (response.status_code,))
-                    print('Content : %s' % (response.content,))
-                    self.send_response(response.status_code)
-                    return response.content
+                print('Error when requesting file :')
+                print('Requested url : %s' % (url,))
+                print('Status code : %s' % (response.status_code,))
+                print('Content : %s' % (response.content,))
+                self.send_response(response.status_code)
+                return response.content
         else:
-            print("Request for data currently present in cache: %s" % (cached_file,))
+            print("Request for data currently present in cache: %s" % (cached_file_folder,))
 
         self._send_content(cached_file_header, cached_file_content)
 
         if self.path.startswith("/dcae-service-types?asdcResourceId="):
-            print "DCAE case deleting folder created " + cached_file
-            shutil.rmtree(cached_file, ignore_errors=False, onerror=None)
+            print "DCAE case deleting folder created " + cached_file_folder
+            shutil.rmtree(cached_file_folder, ignore_errors=False, onerror=None)
         else:
-            print "NOT in DCAE case deleting folder created " + cached_file
+            print "NOT in DCAE case deleting folder created " + cached_file_folder
 
     def do_POST(self):
+        cached_file_folder = ""
+        cached_file_content =""
+        cached_file_header=""
         print("\n\n\nGot a POST for %s" % self.path)
         self.check_credentials()
         self.data_string = self.rfile.read(int(self.headers['Content-Length']))
         print("data-string:\n %s" % self.data_string)
         print("self.headers:\n %s" % self.headers)
 
-        cached_file = '%s/%s' % (CACHE_ROOT, self.path,)
-        print("Cached file name before escaping : %s" % cached_file)
-        cached_file = cached_file.replace('<','&#60;').replace('>','&#62;').replace('?','&#63;').replace('*','&#42;').replace('\\','&#42;').replace(':','&#58;').replace('|','&#124;')
-        print("Cached file name after escaping (used for cache storage) : %s" % cached_file)
-        cached_file_content = "%s/.file" % (cached_file,)
-        cached_file_header = "%s/.header" % (cached_file,)
+        is_special = self._execute_content_generated_cases("POST")
+        if is_special:
+            cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
+        else:
+            cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
 
         _file_available = os.path.exists(cached_file_content)
 
         if not _file_available:
-            if self.path.startswith("/sdc/v1/catalog/services/"):
-                print "self.path start with /sdc/v1/catalog/services/, generating response json..."
-                jsondata = json.loads(self.data_string)
-                jsonGenerated = "{\"artifactName\":\"" + jsondata['artifactName'] + "\",\"artifactType\":\"" + jsondata['artifactType'] + "\",\"artifactURL\":\"" + self.path + "\",\"artifactDescription\":\"" + jsondata['description'] + "\",\"artifactChecksum\":\"ZjJlMjVmMWE2M2M1OTM2MDZlODlmNTVmZmYzNjViYzM=\",\"artifactUUID\":\"" + str(uuid.uuid4()) + "\",\"artifactVersion\":\"1\"}"
-                print "jsonGenerated: " + jsonGenerated
-
-                os.makedirs(cached_file, True)
-                with open(cached_file_header, 'w') as f:
-                    f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
-                with open(cached_file_content, 'w') as f:
-                    f.write(jsonGenerated)
+        
+            if not HOST:
+                self.send_response(404)
+                return "404 Not found"
+
+            print("Request for data currently not present in cache: %s" % (cached_file_folder,))
+
+            url = '%s%s' % (HOST, self.path)
+            print("url: %s" % (url,))
+            response = requests.post(url, data=self.data_string, headers=self.headers, stream=True)
+
+            if response.status_code == 200:
+                self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
             else:
-                if not HOST:
-                    self.send_response(404)
-                    return "404 Not found"
-
-                print("Request for data currently not present in cache: %s" % (cached_file,))
-
-                url = '%s%s' % (HOST, self.path)
-                print("url: %s" % (url,))
-                response = requests.post(url, data=self.data_string, headers=self.headers, stream=True)
-
-                if response.status_code == 200:
-                    self._write_cache(cached_file, cached_file_header, cached_file_content, response)
-                else:
-                    print('Error when requesting file :')
-                    print('Requested url : %s' % (url,))
-                    print('Status code : %s' % (response.status_code,))
-                    print('Content : %s' % (response.content,))
-                    self.send_response(response.status_code)
-                    return response.content
+                print('Error when requesting file :')
+                print('Requested url : %s' % (url,))
+                print('Status code : %s' % (response.status_code,))
+                print('Content : %s' % (response.content,))
+                self.send_response(response.status_code)
+                return response.content
         else:
-            print("Request for data present in cache: %s" % (cached_file,))
+            print("Request for data present in cache: %s" % (cached_file_folder,))
 
         self._send_content(cached_file_header, cached_file_content)
 
     def do_PUT(self):
+        cached_file_folder = ""
+        cached_file_content =""
+        cached_file_header=""
         print("\n\n\nGot a PUT for %s " % self.path)
         self.check_credentials()
         self.data_string = self.rfile.read(int(self.headers['Content-Length']))
         print("data-string:\n %s" % self.data_string)
         print("self.headers:\n %s" % self.headers)
 
-        cached_file = '%s/%s' % (CACHE_ROOT, self.path,)
-        print("Cached file name before escaping : %s" % cached_file)
-        cached_file = cached_file.replace('<','&#60;').replace('>','&#62;').replace('?','&#63;').replace('*','&#42;').replace('\\','&#42;').replace(':','&#58;').replace('|','&#124;')
-        print("Cached file name after escaping (used for cache storage) : %s" % cached_file)
-        cached_file_content = "%s/.file" % (cached_file,)
-        cached_file_header = "%s/.header" % (cached_file,)
+        is_special = self._execute_content_generated_cases("PUT")
+        if is_special:
+            cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
+        else:
+            cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
 
         _file_available = os.path.exists(cached_file_content)
 
         if not _file_available:
-            if self.path.startswith("/dcae-deployments/"):
-                print "self.path start with /dcae-deployments/, generating response json..."
-                #jsondata = json.loads(self.data_string)
-                jsonGenerated = "{\"links\":{\"status\":\"http:\/\/" + PROXY_ADDRESS + "\/dcae-operationstatus\",\"test2\":\"test2\"}}"
-                print "jsonGenerated: " + jsonGenerated
-
-                os.makedirs(cached_file, True)
-                with open(cached_file_header, 'w') as f:
-                    f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
-                with open(cached_file_content, 'w') as f:
-                    f.write(jsonGenerated)
+            if not HOST:
+                self.send_response(404)
+                return "404 Not found"
+
+            print("Request for data currently not present in cache: %s" % (cached_file_folder,))
+
+            url = '%s%s' % (HOST, self.path)
+            print("url: %s" % (url,))
+            response = requests.put(url, data=self.data_string, headers=self.headers, stream=True)
+
+            if response.status_code == 200:
+                self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
             else:
-                if not HOST:
-                    self.send_response(404)
-                    return "404 Not found"
-
-                print("Request for data currently not present in cache: %s" % (cached_file,))
-
-                url = '%s%s' % (HOST, self.path)
-                print("url: %s" % (url,))
-                response = requests.put(url, data=self.data_string, headers=self.headers, stream=True)
-
-                if response.status_code == 200:
-                    self._write_cache(cached_file, cached_file_header, cached_file_content, response)
-                else:
-                    print('Error when requesting file :')
-                    print('Requested url : %s' % (url,))
-                    print('Status code : %s' % (response.status_code,))
-                    print('Content : %s' % (response.content,))
-                    self.send_response(response.status_code)
-                    return response.content
+                print('Error when requesting file :')
+                print('Requested url : %s' % (url,))
+                print('Status code : %s' % (response.status_code,))
+                print('Content : %s' % (response.content,))
+                self.send_response(response.status_code)
+                return response.content
         else:
-            print("Request for data present in cache: %s" % (cached_file,))
+            print("Request for data present in cache: %s" % (cached_file_folder,))
 
         self._send_content(cached_file_header, cached_file_content)
 
 
     def do_DELETE(self):
+        cached_file_folder = ""
+        cached_file_content =""
+        cached_file_header=""
         print("\n\n\nGot a DELETE for %s " % self.path)
         self.check_credentials()
         print("self.headers:\n %s" % self.headers)
 
-        cached_file = '%s/%s' % (CACHE_ROOT, self.path,)
-        print("Cached file name before escaping : %s" % cached_file)
-        cached_file = cached_file.replace('<','&#60;').replace('>','&#62;').replace('?','&#63;').replace('*','&#42;').replace('\\','&#42;').replace(':','&#58;').replace('|','&#124;')
-        print("Cached file name after escaping (used for cache storage) : %s" % cached_file)
-        cached_file_content = "%s/.file" % (cached_file,)
-        cached_file_header = "%s/.header" % (cached_file,)
+        is_special = self._execute_content_generated_cases("DELETE")
+        if is_special:
+            cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
+        else:
+            cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
+            cached_file_content = self._get_cached_content_file_name(cached_file_folder)
+            cached_file_header = self._get_cached_header_file_name(cached_file_folder)
 
         _file_available = os.path.exists(cached_file_content)
 
         if not _file_available:
-            if self.path.startswith("/dcae-deployments/"):
-                print "self.path start with /dcae-deployments/, generating response json..."
-                #jsondata = json.loads(self.data_string)
-                jsonGenerated = "{\"links\":{\"status\":\"http:\/\/" + PROXY_ADDRESS + "\/dcae-operationstatus\",\"test2\":\"test2\"}}"
-                print "jsonGenerated: " + jsonGenerated
-
-                os.makedirs(cached_file, True)
-                with open(cached_file_header, 'w') as f:
-                    f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
-                with open(cached_file_content, 'w') as f:
-                    f.write(jsonGenerated)
+            if not HOST:
+                self.send_response(404)
+                return "404 Not found"
+
+            print("Request for data currently not present in cache: %s" % (cached_file_folder,))
+
+            url = '%s%s' % (HOST, self.path)
+            print("url: %s" % (url,))
+            response = requests.put(url, data=self.data_string, headers=self.headers, stream=True)
+
+            if response.status_code == 200:
+                self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
             else:
-                if not HOST:
-                    self.send_response(404)
-                    return "404 Not found"
-
-                print("Request for data currently not present in cache: %s" % (cached_file,))
-
-                url = '%s%s' % (HOST, self.path)
-                print("url: %s" % (url,))
-                response = requests.put(url, data=self.data_string, headers=self.headers, stream=True)
-
-                if response.status_code == 200:
-                    self._write_cache(cached_file, cached_file_header, cached_file_content, response)
-                else:
-                    print('Error when requesting file :')
-                    print('Requested url : %s' % (url,))
-                    print('Status code : %s' % (response.status_code,))
-                    print('Content : %s' % (response.content,))
-                    self.send_response(response.status_code)
-                    return response.content
+                print('Error when requesting file :')
+                print('Requested url : %s' % (url,))
+                print('Status code : %s' % (response.status_code,))
+                print('Content : %s' % (response.content,))
+                self.send_response(response.status_code)
+                return response.content
         else:
-            print("Request for data present in cache: %s" % (cached_file,))
+            print("Request for data present in cache: %s" % (cached_file_folder,))
 
         self._send_content(cached_file_header, cached_file_content)
 
@@ -322,6 +372,7 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
 # Main code that start the HTTP server
 httpd = SocketServer.ForkingTCPServer(('', PORT), Proxy)
 httpd.allow_reuse_address = True
-print "Listening on port "+ str(PORT) + " and caching in " + CACHE_ROOT + "(Press Ctrl+C to stop HTTPD Caching script)"
+print "Listening on port "+ str(PORT) + "(Press Ctrl+C/Ctrl+Z to stop HTTPD Caching script)"
+print "Caching folder " + CACHE_ROOT + ", Tmp folder for generated files " + TMP_ROOT 
 signal.signal(signal.SIGINT, signal_handler)
 httpd.serve_forever()
\ No newline at end of file
diff --git a/src/test/resources/tosca/tca-policy-test.yaml b/src/test/resources/tosca/tca-policy-test.yaml
new file mode 100644 (file)
index 0000000..3c5afb0
--- /dev/null
@@ -0,0 +1,80 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+node_types:
+  policy.nodes.cdap.tca.hi.lo.app:
+    derived_from: policy.nodes.Root
+    properties:
+      domain:
+        type: string
+        description: Domain
+        constraints:
+        - equal: measurementsForVfScaling
+      functionalRole:
+        type: string
+        description: Function of the event source e.g., vnf1, vnf2, vnf3
+      thresholds:
+        type: list
+        description: Thresholds
+        entry_schema:
+          type: policy.data.thresholds
+data_types:
+  policy.data.thresholds:
+    properties:
+      closedLoopControlName:
+        type: string
+        description: A UNIQUE string identifying the Closed Loop ID this event is for.
+      direction:
+        type: string
+        constraints:
+        - valid_values: [ LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL]
+      fieldPath:
+        description: Field Path
+        type: string
+      severity:
+        type: string
+        description: event severity or priority
+        constraints:
+        - valid_values: [CRITICAL, MAJOR, MINOR, WARNING, NORMAL]
+      thresholdValue:
+        type: integer
+        description: ThresholdValue
+        default: 0
+        constraints:
+          - in_range: [ 0, 65535 ]
+      version:
+        type: string
+        description: Version for the closed loop message
+        constraints:
+          - min_length: 1
+      dummySignatures:
+        type: list
+        description: dummy Signatures
+        required: true
+        entry_schema:
+          type: policy.data.dummySignatureTraversal
+  policy.data.dummySignatureTraversal:
+    derived_from: tosca.nodes.Root
+    properties:
+      signature:
+        type: policy.data.DUMMY_Signature_FM
+        required: true
+      traversal:
+        type: policy.data.traverse
+        required: true
+  policy.data.traverse:
+    derived_from: tosca.nodes.Root
+    properties:
+      traversal:
+        type: string
+        description: Dummy Traverse
+        required: true
+        constraints:
+          - valid_values: [ ONE, TWO, THREE ]
+  policy.data.DUMMY_Signature_FM:
+    derived_from: tosca.nodes.Root
+    properties:
+      filter_clause:
+        type: string
+        description: Filter Clause
+        required: true
+        constraints:
+          - valid_values: [ OR, AND, NOT ]
diff --git a/src/test/resources/tosca/tosca_example.yaml b/src/test/resources/tosca/tosca_example.yaml
new file mode 100644 (file)
index 0000000..3c5afb0
--- /dev/null
@@ -0,0 +1,80 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+node_types:
+  policy.nodes.cdap.tca.hi.lo.app:
+    derived_from: policy.nodes.Root
+    properties:
+      domain:
+        type: string
+        description: Domain
+        constraints:
+        - equal: measurementsForVfScaling
+      functionalRole:
+        type: string
+        description: Function of the event source e.g., vnf1, vnf2, vnf3
+      thresholds:
+        type: list
+        description: Thresholds
+        entry_schema:
+          type: policy.data.thresholds
+data_types:
+  policy.data.thresholds:
+    properties:
+      closedLoopControlName:
+        type: string
+        description: A UNIQUE string identifying the Closed Loop ID this event is for.
+      direction:
+        type: string
+        constraints:
+        - valid_values: [ LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL]
+      fieldPath:
+        description: Field Path
+        type: string
+      severity:
+        type: string
+        description: event severity or priority
+        constraints:
+        - valid_values: [CRITICAL, MAJOR, MINOR, WARNING, NORMAL]
+      thresholdValue:
+        type: integer
+        description: ThresholdValue
+        default: 0
+        constraints:
+          - in_range: [ 0, 65535 ]
+      version:
+        type: string
+        description: Version for the closed loop message
+        constraints:
+          - min_length: 1
+      dummySignatures:
+        type: list
+        description: dummy Signatures
+        required: true
+        entry_schema:
+          type: policy.data.dummySignatureTraversal
+  policy.data.dummySignatureTraversal:
+    derived_from: tosca.nodes.Root
+    properties:
+      signature:
+        type: policy.data.DUMMY_Signature_FM
+        required: true
+      traversal:
+        type: policy.data.traverse
+        required: true
+  policy.data.traverse:
+    derived_from: tosca.nodes.Root
+    properties:
+      traversal:
+        type: string
+        description: Dummy Traverse
+        required: true
+        constraints:
+          - valid_values: [ ONE, TWO, THREE ]
+  policy.data.DUMMY_Signature_FM:
+    derived_from: tosca.nodes.Root
+    properties:
+      filter_clause:
+        type: string
+        description: Filter Clause
+        required: true
+        constraints:
+          - valid_values: [ OR, AND, NOT ]