diff options
author | ash74268 <ashwin.shyam.sharma@att.com> | 2020-01-31 15:40:15 +0000 |
---|---|---|
committer | sebdet <sebastien.determe@intl.att.com> | 2020-02-14 08:02:47 -0800 |
commit | 3a83e2a2ff88ef49535973df8dc77dc8015170da (patch) | |
tree | 7b1d9376a6a3967d9690bcc88487fb6bb7893167 /src/main/java/org | |
parent | 29e3cd1afbd3202a0c16ef6a4057662942ddefa2 (diff) |
Changes include Metadata support, Upload tosca policy model and Loop Template
CLAMP Metadata support to parse policy_model_type, acronym and clamp_possible_values from the Tosca Policy Model
UI and Backend changes to support Loop Template
Backend APIs for Dictionary referenced in the Tosca Policy Model.
Upload Tosca Model UI changes to allow user to upload policy models.
DB Schema changes for the Loop Element Model and updated schema for the Dictionary
Added Jest test cases and snapshots
checkstyle issues fix and Junits
Issue-ID: CLAMP-580
Signed-off-by: ash74268 <ashwin.shyam.sharma@att.com>
Change-Id: I57521bc1c3afaf4ca5a2acf4c59823df05fd4cd6
Signed-off-by: ash74268 <ashwin.shyam.sharma@att.com>
Diffstat (limited to 'src/main/java/org')
16 files changed, 1107 insertions, 348 deletions
diff --git a/src/main/java/org/onap/clamp/clds/tosca/ToscaSchemaConstants.java b/src/main/java/org/onap/clamp/clds/tosca/ToscaSchemaConstants.java index 595b1805e..9601649c9 100644 --- a/src/main/java/org/onap/clamp/clds/tosca/ToscaSchemaConstants.java +++ b/src/main/java/org/onap/clamp/clds/tosca/ToscaSchemaConstants.java @@ -42,6 +42,11 @@ public class ToscaSchemaConstants { public static final String PROPERTIES = "properties"; public static final String REQUIRED = "required"; public static final String ENTRY_SCHEMA = "entry_schema"; + + public static final String METADATA = "metadata"; + public static final String METADATA_POLICY_MODEL_TYPE = "policy_model_type"; + public static final String METADATA_ACRONYM = "acronym"; + public static final String METADATA_CLAMP_POSSIBLE_VALUES = "clamp_possible_values"; // Constraints public static final String CONSTRAINTS = "constraints"; diff --git a/src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java b/src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java index 232db48c4..666ca6702 100644 --- a/src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java +++ b/src/main/java/org/onap/clamp/clds/tosca/ToscaYamlToJsonConvertor.java @@ -23,15 +23,25 @@ package org.onap.clamp.clds.tosca; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; 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.Map.Entry; +import java.util.Optional; +import java.util.stream.Collectors; import org.json.JSONArray; import org.json.JSONObject; +import org.onap.clamp.clds.config.ClampProperties; +import org.onap.clamp.tosca.DictionaryElement; +import org.onap.clamp.tosca.DictionaryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import org.yaml.snakeyaml.Yaml; /** @@ -39,8 +49,15 @@ import org.yaml.snakeyaml.Yaml; * Editor. * */ +@Component public class ToscaYamlToJsonConvertor { + @Autowired + private DictionaryService dictionaryService; + + @Autowired + private ClampProperties refProp; + private int simpleTypeOrder = 1000; private int complexTypeOrder = 10000; private int complexSimpleTypeOrder = 1; @@ -59,11 +76,56 @@ public class ToscaYamlToJsonConvertor { } /** + * Parses Tosca YAML string and Converts to JsonObject. + * + * @param yamlString YAML string + * @return JsonObject + */ + public JsonObject validateAndConvertToJson(String yamlString) { + + Yaml yaml = new Yaml(); + LinkedHashMap<String, Object> loadedYaml = yaml.load(yamlString); + if (loadedYaml == null) { + return null; + } + + JSONObject jsonObject = new JSONObject(loadedYaml); + return new Gson().fromJson(jsonObject.toString(), JsonObject.class); + } + + /** + * return the values by looking up the key in the Toscsa JSON object. + * + * @param obj Tosca Json Object + * @param key the parameter key to look up + * @return the value for the provided key + */ + public String getValueFromMetadata(JsonObject obj, String key) { + JsonElement jsonElement = obj.get(ToscaSchemaConstants.NODE_TYPES); + if (jsonElement.isJsonObject()) { + Iterator<Entry<String, JsonElement>> itr = + jsonElement.getAsJsonObject().entrySet().iterator(); + while (itr.hasNext()) { + Entry<String, JsonElement> entry = itr.next(); + if (entry.getValue() != null && entry.getValue().isJsonObject() + && entry.getValue().getAsJsonObject().has(ToscaSchemaConstants.METADATA)) { + JsonObject metadatas = entry.getValue().getAsJsonObject() + .get(ToscaSchemaConstants.METADATA).getAsJsonObject(); + if (metadatas.has(key)) { + return metadatas.get(key).getAsString(); + } + } + } + } + return null; + } + + /** * Parses Tosca YAML string. * - * @param yamlString YAML string + * @param yamlString YAML string * @param modelTypeToUse The model type that must be used to obtain the Json - * Schema + * Schema * @return JSON string */ public String parseToscaYaml(String yamlString, String modelTypeToUse) { @@ -78,7 +140,8 @@ public class ToscaYamlToJsonConvertor { JSONObject jsonParentObject = new JSONObject(); JSONObject jsonTempObject = new JSONObject(); parseNodeAndDataType(loadedYaml, nodeTypes, dataNodes); - populateJsonEditorObject(loadedYaml, nodeTypes, dataNodes, jsonParentObject, jsonTempObject, modelTypeToUse); + populateJsonEditorObject(loadedYaml, nodeTypes, dataNodes, jsonParentObject, jsonTempObject, + modelTypeToUse); if (jsonTempObject.length() > 0) { jsonParentObject = jsonTempObject; } @@ -89,13 +152,17 @@ public class ToscaYamlToJsonConvertor { // Parse node_type and data_type @SuppressWarnings("unchecked") - private void parseNodeAndDataType(LinkedHashMap<String, Object> map, LinkedHashMap<String, Object> nodeTypes, - LinkedHashMap<String, Object> dataNodes) { + 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); + 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)) { @@ -105,83 +172,97 @@ public class ToscaYamlToJsonConvertor { } @SuppressWarnings("unchecked") - private void populateJsonEditorObject(LinkedHashMap<String, Object> map, LinkedHashMap<String, Object> nodeTypes, - LinkedHashMap<String, Object> dataNodes, JSONObject jsonParentObject, JSONObject jsonTempObject, - String modelTypeToUse) { + private void populateJsonEditorObject(LinkedHashMap<String, Object> map, + LinkedHashMap<String, Object> nodeTypes, LinkedHashMap<String, Object> dataNodes, + JSONObject jsonParentObject, JSONObject jsonTempObject, String modelTypeToUse) { Map<String, JSONObject> jsonEntrySchema = new HashMap<>(); jsonParentObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_OBJECT); if (nodeTypes.get(modelTypeToUse) instanceof Map) { - ((LinkedHashMap<String, Object>) nodeTypes.get(modelTypeToUse)).entrySet().forEach(ntElement -> { - if (ntElement.getKey().equalsIgnoreCase(ToscaSchemaConstants.PROPERTIES)) { - JSONArray rootNodeArray = new JSONArray(); - if (ntElement.getValue() instanceof Map) { - ((LinkedHashMap<String, Object>) ntElement.getValue()).entrySet() + ((LinkedHashMap<String, Object>) nodeTypes.get(modelTypeToUse)).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 + 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_MAP) - && parentPropertiesMap.containsKey(ToscaSchemaConstants.ENTRY_SCHEMA)) { - parentPropertiesMap = (LinkedHashMap<String, Object>) parentPropertiesMap + && ((String) parentPropertiesMap + .get(ToscaSchemaConstants.TYPE)) + .contains(ToscaSchemaConstants.TYPE_MAP) + && 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()); - } - }); + && ((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); + 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); + JsonEditorSchemaConstants.CUSTOM_KEY_FORMAT_TABS_TOP); jsonTempObject.put(JsonEditorSchemaConstants.UNIQUE_ITEMS, - JsonEditorSchemaConstants.TRUE); + 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 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(); + LinkedHashMap<String, Object> nodeMap = + (LinkedHashMap<String, Object>) p.getValue(); if (nodeMap.containsKey(ToscaSchemaConstants.REQUIRED) - && ((boolean) nodeMap.get(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()); + parseToscaChildNodeMap(p.getKey(), nodeMap, jsonPropertyNode, jsonEntrySchema, + dataNodes, array, incrementSimpleTypeOrder()); } }); jsonDataNode.put(JsonEditorSchemaConstants.REQUIRED, array); @@ -189,42 +270,48 @@ public class ToscaYamlToJsonConvertor { } @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) { + 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(); + 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))) { + || 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))) { + && ((boolean) nodeMap.get(ToscaSchemaConstants.REQUIRED))) { array.put(p.getKey()); } - parseToscaChildNodeMap(p.getKey(), nodeMap, jsonPropertyNode, jsonEntrySchema, dataNodes, array, order); + 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) { + 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); + parseTypes(childObjectKey, childNodeMap, childObject, jsonEntrySchema, dataNodes, array, + order); parseConstraints(childNodeMap, childObject); + parseMetadataPossibleValues(childNodeMap, childObject); parseEntrySchema(childNodeMap, childObject, jsonPropertyNode, jsonEntrySchema, dataNodes); jsonPropertyNode.put(childObjectKey, childObject); @@ -232,15 +319,17 @@ public class ToscaYamlToJsonConvertor { } - private void parseEntrySchema(LinkedHashMap<String, Object> childNodeMap, JSONObject childObject, - JSONObject jsonPropertyNode, Map<String, JSONObject> jsonEntrySchema, - LinkedHashMap<String, Object> dataNodes) { + 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 + 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) { + if (entry.getKey().equalsIgnoreCase(ToscaSchemaConstants.TYPE) + && entry.getValue() != null) { String entrySchemaType = (String) entry.getValue(); if (entrySchemaType.contains(ToscaSchemaConstants.POLICY_DATA)) { JSONArray array = new JSONArray(); @@ -248,44 +337,51 @@ public class ToscaYamlToJsonConvertor { // Already traversed JSONObject entrySchemaObject = jsonEntrySchema.get(entrySchemaType); attachEntrySchemaJsonObject(childObject, entrySchemaObject, - JsonEditorSchemaConstants.TYPE_OBJECT); + 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); - } + ((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)) { + } else if (entrySchemaType + .equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING) + || entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_INTEGER) + || entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_FLOAT)) { JSONObject entrySchemaObject = new JSONObject(); parseConstraints(entrySchemaMap, entrySchemaObject); + parseMetadataPossibleValues(entrySchemaMap, entrySchemaObject); String jsontype = JsonEditorSchemaConstants.TYPE_STRING; if (entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_INTEGER) - || entrySchemaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_FLOAT)) { + || 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)) { + 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); + JsonEditorSchemaConstants.FORMAT_SELECT); // childObject.put(JsonEditorSchemaConstants.UNIQUE_ITEMS, // JsonEditorSchemaConstants.TRUE); } @@ -299,7 +395,8 @@ public class ToscaYamlToJsonConvertor { } } - private void attachEntrySchemaJsonObject(JSONObject childObject, JSONObject entrySchemaObject, String dataType) { + private void attachEntrySchemaJsonObject(JSONObject childObject, JSONObject entrySchemaObject, + String dataType) { entrySchemaObject.put(JsonEditorSchemaConstants.TYPE, dataType); childObject.put(JsonEditorSchemaConstants.ITEMS, entrySchemaObject); @@ -320,33 +417,40 @@ public class ToscaYamlToJsonConvertor { * toscaKey.length()); } */ - private void parseDescription(LinkedHashMap<String, Object> childNodeMap, JSONObject childObject) { + private void parseDescription(LinkedHashMap<String, Object> childNodeMap, + JSONObject childObject) { if (childNodeMap.get(ToscaSchemaConstants.DESCRIPTION) != null) { - childObject.put(JsonEditorSchemaConstants.TITLE, childNodeMap.get(ToscaSchemaConstants.DESCRIPTION)); + 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) { + 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); + childObject.put(JsonEditorSchemaConstants.TYPE, + JsonEditorSchemaConstants.TYPE_INTEGER); } else if (typeValue.equalsIgnoreCase(ToscaSchemaConstants.TYPE_FLOAT)) { - childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_INTEGER); + childObject.put(JsonEditorSchemaConstants.TYPE, + JsonEditorSchemaConstants.TYPE_INTEGER); } else if (typeValue.equalsIgnoreCase(ToscaSchemaConstants.TYPE_LIST)) { - childObject.put(JsonEditorSchemaConstants.TYPE, JsonEditorSchemaConstants.TYPE_ARRAY); + 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); + 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); + childObject.put(JsonEditorSchemaConstants.TYPE, + JsonEditorSchemaConstants.TYPE_OBJECT); } else if (typeValue.contains(ToscaSchemaConstants.POLICY_DATA)) { JSONArray childArray = new JSONArray(); @@ -358,101 +462,129 @@ public class ToscaYamlToJsonConvertor { 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)) { - parseToscaPropertiesForType(childObjectKey, - (LinkedHashMap<String, Object>) pmap.getValue(), entrySchemaObject, childArray, - jsonEntrySchema, dataNodes, true, incrementComplexSimpleTypeOrder()); - jsonEntrySchema.put(typeValue, entrySchemaObject); - dataNodes.remove(typeValue); - attachTypeJsonObject(childObject, entrySchemaObject); - } - }); + ((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); + childObject.put(JsonEditorSchemaConstants.TYPE, + JsonEditorSchemaConstants.TYPE_STRING); } } if (childNodeMap.get(ToscaSchemaConstants.DEFAULT) != null) { - childObject.put(JsonEditorSchemaConstants.DEFAULT, childNodeMap.get(ToscaSchemaConstants.DEFAULT)); + childObject.put(JsonEditorSchemaConstants.DEFAULT, + childNodeMap.get(ToscaSchemaConstants.DEFAULT)); } } } - private void parseConstraints(LinkedHashMap<String, Object> childNodeMap, JSONObject childObject) { + 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 + && 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 + || 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()); + && (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()); + 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 + } 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()); + && (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()); + 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)) { + } 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)) { + && (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)); + ((ArrayList) constraint.getValue()).get(0)); childObject.put(JsonEditorSchemaConstants.MAX_LENGTH, - ((ArrayList) constraint.getValue()).get(1)); + ((ArrayList) constraint.getValue()).get(1)); } else { childObject.put(JsonEditorSchemaConstants.MINIMUM, - ((ArrayList) constraint.getValue()).get(0)); + ((ArrayList) constraint.getValue()).get(0)); childObject.put(JsonEditorSchemaConstants.MAXIMUM, - ((ArrayList) constraint.getValue()).get(1)); + ((ArrayList) constraint.getValue()).get(1)); } } - } else if (constraint.getKey().equalsIgnoreCase(ToscaSchemaConstants.VALID_VALUES)) { + } 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))); + 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); + ((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); - } + ((ArrayList<?>) constraint.getValue()).stream() + .forEach(value -> { + if ((value instanceof String && ((String) value) + .contains(ToscaSchemaConstants.DICTIONARY))) { + processDictionaryElements(childObject, + (String) value); + } - }); + }); } } @@ -464,8 +596,117 @@ public class ToscaYamlToJsonConvertor { } } + private void parseMetadataPossibleValues(LinkedHashMap<String, Object> childNodeMap, + JSONObject childObject) { + if (childNodeMap.containsKey(ToscaSchemaConstants.METADATA) + && childNodeMap.get(ToscaSchemaConstants.METADATA) != null) { + LinkedHashMap<String, Object> metadataMap = + (LinkedHashMap<String, Object>) childNodeMap.get(ToscaSchemaConstants.METADATA); + if (metadataMap instanceof Map) { + metadataMap.entrySet().stream().forEach(constraint -> { + if (constraint.getKey() + .equalsIgnoreCase(ToscaSchemaConstants.METADATA_CLAMP_POSSIBLE_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 -> { + 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<DictionaryElement> cldsDictionaryElements = null; + List<DictionaryElement> subDictionaryElements = null; + if (dictionaryKeyArray != null && dictionaryKeyArray.length == 2) { + cldsDictionaryElements = dictionaryService.getDictionary(dictionaryKeyArray[0]) + .getDictionaryElements().stream().collect(Collectors.toList()); + subDictionaryElements = dictionaryService.getDictionary(dictionaryKeyArray[1]) + .getDictionaryElements().stream().collect(Collectors.toList()); + + if (cldsDictionaryElements != null) { + List<String> subCldsDictionaryNames = subDictionaryElements.stream() + .map(DictionaryElement::getShortName).collect(Collectors.toList()); + JSONArray jsonArray = new JSONArray(); + + Optional.ofNullable(cldsDictionaryElements).get().stream().forEach(c -> { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(JsonEditorSchemaConstants.TYPE, getJsonType(c.getType())); + if (c.getType() != null + && c.getType().equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING)) { + jsonObject.put(JsonEditorSchemaConstants.MIN_LENGTH, 1); + } + jsonObject.put(JsonEditorSchemaConstants.ID, c.getName()); + jsonObject.put(JsonEditorSchemaConstants.LABEL, c.getShortName()); + 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<DictionaryElement> cldsDictionaryElements = + dictionaryService.getDictionary(dictionaryKey).getDictionaryElements().stream() + .collect(Collectors.toList()); + 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.getType() != null && !c.getType().equalsIgnoreCase("json")) { + cldsDictionaryFullNames.add(c.getName()); + } + cldsDictionaryNames.add(c.getShortName()); + }); + + if (!cldsDictionaryFullNames.isEmpty()) { + 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) { @@ -480,4 +721,4 @@ public class ToscaYamlToJsonConvertor { return jsonType; } -}
\ No newline at end of file +} diff --git a/src/main/java/org/onap/clamp/loop/template/LoopElementModel.java b/src/main/java/org/onap/clamp/loop/template/LoopElementModel.java index 0a0831bb7..e6ba98151 100644 --- a/src/main/java/org/onap/clamp/loop/template/LoopElementModel.java +++ b/src/main/java/org/onap/clamp/loop/template/LoopElementModel.java @@ -24,13 +24,11 @@ package org.onap.clamp.loop.template; import com.google.gson.annotations.Expose; - import java.io.Serializable; import java.util.HashSet; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; - import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -41,7 +39,6 @@ import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.Table; - import org.hibernate.annotations.SortNatural; import org.onap.clamp.loop.common.AuditEntity; @@ -80,15 +77,26 @@ public class LoopElementModel extends AuditEntity implements Serializable { private String loopElementType; /** + * This variable is used to display the micro-service name in the SVG. + */ + @Expose + @Column(name = "short_name") + private String shortName; + + /** * This variable is used to store the type mentioned in the micro-service * blueprint. */ @Expose - @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }) - @JoinTable(name = "loopelementmodels_to_policymodels", - joinColumns = @JoinColumn(name = "loop_element_name", referencedColumnName = "name"), - inverseJoinColumns = { @JoinColumn(name = "policy_model_type", referencedColumnName = "policy_model_type"), - @JoinColumn(name = "policy_model_version", referencedColumnName = "version") }) + @ManyToMany( + fetch = FetchType.EAGER, + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) + @JoinTable( + name = "loopelementmodels_to_policymodels", + joinColumns = @JoinColumn(name = "loop_element_name", referencedColumnName = "name"), + inverseJoinColumns = { + @JoinColumn(name = "policy_model_type", referencedColumnName = "policy_model_type"), + @JoinColumn(name = "policy_model_version", referencedColumnName = "version")}) @SortNatural private SortedSet<PolicyModel> policyModels = new TreeSet<>(); @@ -97,7 +105,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * policyModels getter. - * + * * @return the policyModel */ public SortedSet<PolicyModel> getPolicyModels() { @@ -106,7 +114,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * Method to add a new policyModel to the list. - * + * * @param policyModel The policy model */ public void addPolicyModel(PolicyModel policyModel) { @@ -116,7 +124,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * name getter. - * + * * @return the name */ public String getName() { @@ -125,7 +133,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * name setter. - * + * * @param name the name to set */ public void setName(String name) { @@ -134,7 +142,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * blueprint getter. - * + * * @return the blueprint */ public String getBlueprint() { @@ -143,7 +151,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * blueprint setter. - * + * * @param blueprint the blueprint to set */ public void setBlueprint(String blueprint) { @@ -151,10 +159,8 @@ public class LoopElementModel extends AuditEntity implements Serializable { } /** - * loopElementType getter. - * * dcaeBlueprintId getter. - * + * * @return the dcaeBlueprintId */ public String getDcaeBlueprintId() { @@ -163,7 +169,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * dcaeBlueprintId setter. - * + * * @param dcaeBlueprintId the dcaeBlueprintId to set */ public void setDcaeBlueprintId(String dcaeBlueprintId) { @@ -171,6 +177,8 @@ public class LoopElementModel extends AuditEntity implements Serializable { } /** + * loopElementType getter. + * * @return the loopElementType */ public String getLoopElementType() { @@ -179,7 +187,7 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * loopElementType setter. - * + * * @param loopElementType the loopElementType to set */ public void setLoopElementType(String loopElementType) { @@ -187,8 +195,24 @@ public class LoopElementModel extends AuditEntity implements Serializable { } /** + * shortName getter. + * + * @return the shortName + */ + public String getShortName() { + return shortName; + } + + /** + * @param shortName the shortName to set. + */ + public void setShortName(String shortName) { + this.shortName = shortName; + } + + /** * usedByLoopTemplates getter. - * + * * @return the usedByLoopTemplates */ public Set<LoopTemplateLoopElementModel> getUsedByLoopTemplates() { @@ -203,11 +227,11 @@ public class LoopElementModel extends AuditEntity implements Serializable { /** * Constructor. - * - * @param name The name id + * + * @param name The name id * @param loopElementType The type of loop element - * @param blueprint The blueprint defined for dcae that contains the - * policy type to use + * @param blueprint The blueprint defined for dcae that contains the + * policy type to use */ public LoopElementModel(String name, String loopElementType, String blueprint) { this.name = name; diff --git a/src/main/java/org/onap/clamp/loop/template/LoopTemplate.java b/src/main/java/org/onap/clamp/loop/template/LoopTemplate.java index 3e90c1e5b..54096cb8f 100644 --- a/src/main/java/org/onap/clamp/loop/template/LoopTemplate.java +++ b/src/main/java/org/onap/clamp/loop/template/LoopTemplate.java @@ -24,14 +24,13 @@ package org.onap.clamp.loop.template; import com.google.gson.annotations.Expose; - import java.io.Serializable; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; - import javax.persistence.CascadeType; import javax.persistence.Column; +import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; @@ -39,7 +38,6 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; - import org.hibernate.annotations.SortNatural; import org.onap.clamp.loop.common.AuditEntity; import org.onap.clamp.loop.service.Service; @@ -74,12 +72,18 @@ public class LoopTemplate extends AuditEntity implements Serializable { private String svgRepresentation; @Expose - @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "loopTemplate", orphanRemoval = true) + @OneToMany( + cascade = CascadeType.ALL, + fetch = FetchType.EAGER, + mappedBy = "loopTemplate", + orphanRemoval = true) @SortNatural private SortedSet<LoopTemplateLoopElementModel> loopElementModelsUsed = new TreeSet<>(); @Expose - @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }) + @ManyToOne( + fetch = FetchType.EAGER, + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) @JoinColumn(name = "service_uuid") private Service modelService; @@ -92,8 +96,16 @@ public class LoopTemplate extends AuditEntity implements Serializable { private boolean uniqueBlueprint; /** + * Type of Loop allowed to be created. + */ + @Expose + @Column(name = "allowed_loop_type") + @Convert(converter = LoopTypeConvertor.class) + private LoopType allowedLoopType = LoopType.CLOSED; + + /** * name getter. - * + * * @return the name */ public String getName() { @@ -102,7 +114,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * name setter. - * + * * @param name the name to set */ public void setName(String name) { @@ -111,7 +123,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * blueprint getter. - * + * * @return the blueprint */ public String getBlueprint() { @@ -120,7 +132,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * dcaeBlueprintId getter. - * + * * @return the dcaeBlueprintId */ public String getDcaeBlueprintId() { @@ -129,7 +141,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * dcaeBlueprintId setter. - * + * * @param dcaeBlueprintId the dcaeBlueprintId to set */ public void setDcaeBlueprintId(String dcaeBlueprintId) { @@ -138,7 +150,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * blueprint setter. - * + * * @param blueprint the blueprint to set */ public void setBlueprint(String blueprint) { @@ -152,7 +164,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * svgRepresentation getter. - * + * * @return the svgRepresentation */ public String getSvgRepresentation() { @@ -161,7 +173,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * svgRepresentation setter. - * + * * @param svgRepresentation the svgRepresentation to set */ public void setSvgRepresentation(String svgRepresentation) { @@ -170,7 +182,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * loopElementModelsUsed getter. - * + * * @return the loopElementModelsUsed */ public SortedSet<LoopTemplateLoopElementModel> getLoopElementModelsUsed() { @@ -179,7 +191,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * maximumInstancesAllowed getter. - * + * * @return the maximumInstancesAllowed */ public Integer getMaximumInstancesAllowed() { @@ -188,7 +200,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * maximumInstancesAllowed setter. - * + * * @param maximumInstancesAllowed the maximumInstancesAllowed to set */ public void setMaximumInstancesAllowed(Integer maximumInstancesAllowed) { @@ -196,9 +208,27 @@ public class LoopTemplate extends AuditEntity implements Serializable { } /** + * allowedLoopType getter. + * + * @return the allowedLoopType Type of Loop allowed to be created + */ + public LoopType getAllowedLoopType() { + return allowedLoopType; + } + + /** + * allowedLoopType setter. + * + * @param allowedLoopType the allowedLoopType to set + */ + public void setAllowedLoopType(LoopType allowedLoopType) { + this.allowedLoopType = allowedLoopType; + } + + /** * Add list of loopElements to the current template, each loopElementModel is * added at the end of the list so the flowOrder is computed automatically. - * + * * @param loopElementModels The loopElementModel set to add */ public void addLoopElementModels(Set<LoopElementModel> loopElementModels) { @@ -210,12 +240,12 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * Add a loopElement to the current template, the loopElementModel is added at * the end of the list so the flowOrder is computed automatically. - * + * * @param loopElementModel The loopElementModel to add */ public void addLoopElementModel(LoopElementModel loopElementModel) { - LoopTemplateLoopElementModel jointEntry = new LoopTemplateLoopElementModel(this, loopElementModel, - this.loopElementModelsUsed.size()); + LoopTemplateLoopElementModel jointEntry = new LoopTemplateLoopElementModel(this, + loopElementModel, this.loopElementModelsUsed.size()); this.loopElementModelsUsed.add(jointEntry); loopElementModel.getUsedByLoopTemplates().add(jointEntry); } @@ -223,20 +253,20 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * Add a loopElement model to the current template, the flow order must be * specified manually. - * + * * @param loopElementModel The loopElementModel to add - * @param listPosition The position in the flow + * @param listPosition The position in the flow */ public void addLoopElementModel(LoopElementModel loopElementModel, Integer listPosition) { - LoopTemplateLoopElementModel jointEntry = new LoopTemplateLoopElementModel(this, loopElementModel, - listPosition); + LoopTemplateLoopElementModel jointEntry = + new LoopTemplateLoopElementModel(this, loopElementModel, listPosition); this.loopElementModelsUsed.add(jointEntry); loopElementModel.getUsedByLoopTemplates().add(jointEntry); } /** * modelService getter. - * + * * @return the modelService */ public Service getModelService() { @@ -245,7 +275,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * modelService setter. - * + * * @param modelService the modelService to set */ public void setModelService(Service modelService) { @@ -254,7 +284,7 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * uniqueBlueprint getter. - * + * * @return the uniqueBlueprint */ public boolean getUniqueBlueprint() { @@ -270,17 +300,17 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * Constructor. - * - * @param name The loop template name id - * @param blueprint The blueprint containing all microservices (legacy - * case) - * @param svgRepresentation The svg representation of that loop template + * + * @param name The loop template name id + * @param blueprint The blueprint containing all microservices (legacy + * case) + * @param svgRepresentation The svg representation of that loop template * @param maxInstancesAllowed The maximum number of instances that can be - * created from that template - * @param service The service associated to that loop template + * created from that template + * @param service The service associated to that loop template */ - public LoopTemplate(String name, String blueprint, String svgRepresentation, Integer maxInstancesAllowed, - Service service) { + public LoopTemplate(String name, String blueprint, String svgRepresentation, + Integer maxInstancesAllowed, Service service) { this.name = name; this.setBlueprint(blueprint); this.svgRepresentation = svgRepresentation; @@ -322,17 +352,17 @@ public class LoopTemplate extends AuditEntity implements Serializable { /** * Generate the loop template name. * - * @param serviceName The service name - * @param serviceVersion The service version - * @param resourceName The resource name + * @param serviceName The service name + * @param serviceVersion The service version + * @param resourceName The resource name * @param blueprintFileName The blueprint file name * @return The generated loop template name */ - public static String generateLoopTemplateName(String serviceName, String serviceVersion, String resourceName, - String blueprintFileName) { + public static String generateLoopTemplateName(String serviceName, String serviceVersion, + String resourceName, String blueprintFileName) { StringBuilder buffer = new StringBuilder("LOOP_TEMPLATE_").append(serviceName).append("_v") - .append(serviceVersion).append("_").append(resourceName).append("_") - .append(blueprintFileName.replaceAll(".yaml", "")); + .append(serviceVersion).append("_").append(resourceName).append("_") + .append(blueprintFileName.replaceAll(".yaml", "")); return buffer.toString().replace('.', '_').replaceAll(" ", ""); } } diff --git a/src/main/java/org/onap/clamp/loop/template/LoopTemplateLoopElementModelId.java b/src/main/java/org/onap/clamp/loop/template/LoopTemplateLoopElementModelId.java index 3e2f8ad42..cac5f088a 100644 --- a/src/main/java/org/onap/clamp/loop/template/LoopTemplateLoopElementModelId.java +++ b/src/main/java/org/onap/clamp/loop/template/LoopTemplateLoopElementModelId.java @@ -24,9 +24,7 @@ package org.onap.clamp.loop.template; import com.google.gson.annotations.Expose; - import java.io.Serializable; - import javax.persistence.Column; import javax.persistence.Embeddable; @@ -55,8 +53,8 @@ public class LoopTemplateLoopElementModelId implements Serializable { /** * Constructor. - * - * @param loopTemplateName The loop template name id + * + * @param loopTemplateName The loop template name id * @param microServiceModelName THe micro Service name id */ public LoopTemplateLoopElementModelId(String loopTemplateName, String microServiceModelName) { @@ -66,7 +64,7 @@ public class LoopTemplateLoopElementModelId implements Serializable { /** * loopTemplateName getter. - * + * * @return the loopTemplateName */ public String getLoopTemplateName() { @@ -75,7 +73,7 @@ public class LoopTemplateLoopElementModelId implements Serializable { /** * loopTemplateName setter. - * + * * @param loopTemplateName the loopTemplateName to set */ public void setLoopTemplateName(String loopTemplateName) { @@ -84,7 +82,7 @@ public class LoopTemplateLoopElementModelId implements Serializable { /** * microServiceModelName getter. - * + * * @return the microServiceModelName */ public String getLoopElementModelName() { @@ -93,7 +91,7 @@ public class LoopTemplateLoopElementModelId implements Serializable { /** * loopElementModelName setter. - * + * * @param loopElementModelName the loopElementModelName to set */ public void setLoopElementModelName(String loopElementModelName) { diff --git a/src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java b/src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java new file mode 100644 index 000000000..279d602c8 --- /dev/null +++ b/src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.clamp.loop.template; + +import java.util.List; +import org.onap.clamp.clds.exception.sdc.controller.BlueprintParserException; +import org.onap.clamp.clds.sdc.controller.installer.BlueprintMicroService; +import org.onap.clamp.clds.sdc.controller.installer.BlueprintParser; +import org.onap.clamp.clds.sdc.controller.installer.ChainGenerator; +import org.onap.clamp.clds.util.drawing.SvgFacade; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class LoopTemplatesService { + + private final LoopTemplatesRepository loopTemplatesRepository; + + @Autowired + ChainGenerator chainGenerator; + + @Autowired + private SvgFacade svgFacade; + + /** + * Constructor. + */ + @Autowired + public LoopTemplatesService(LoopTemplatesRepository loopTemplatesRepository) { + this.loopTemplatesRepository = loopTemplatesRepository; + + } + + public LoopTemplate saveOrUpdateLoopTemplate(LoopTemplate loopTemplate) { + return loopTemplatesRepository.save(loopTemplate); + } + + /** + * Saves or updates loop template Object. + * + * @param templateName the loop template name + * @param loopTemplate the loop template object + * @return the loop template + * @throws BlueprintParserException In case of issues with the blueprint + * parsing + */ + public LoopTemplate saveOrUpdateLoopTemplateByName(String templateName, + LoopTemplate loopTemplate) throws BlueprintParserException { + + if (getLoopTemplate(templateName) != null) { + loopTemplate.setName(getLoopTemplate(templateName).getName()); + } + return saveOrUpdateLoopTemplate(createTemplateFromBlueprint(templateName, loopTemplate)); + } + + public List<String> getLoopTemplateNames() { + return loopTemplatesRepository.getAllLoopTemplateNames(); + } + + public List<LoopTemplate> getAllLoopTemplates() { + return loopTemplatesRepository.findAll(); + } + + public LoopTemplate getLoopTemplate(String name) { + return loopTemplatesRepository.findById(name).orElse(null); + } + + public void deleteLoopTemplate(String name) { + loopTemplatesRepository.deleteById(name); + } + + private LoopTemplate createTemplateFromBlueprint(String templateName, LoopTemplate loopTemplate) + throws BlueprintParserException { + + String blueprintYaml = loopTemplate.getBlueprint(); + List<BlueprintMicroService> microServicesChain = + chainGenerator.getChainOfMicroServices(BlueprintParser.getMicroServices(blueprintYaml)); + if (microServicesChain.isEmpty()) { + microServicesChain = BlueprintParser.fallbackToOneMicroService(); + } + loopTemplate.setSvgRepresentation(svgFacade.getSvgImage(microServicesChain)); + loopTemplate.setName(templateName); + + LoopTemplate existingTemplate = getLoopTemplate(templateName); + if (existingTemplate != null) { + loopTemplate.setName(existingTemplate.getName()); + } + return loopTemplate; + } +} diff --git a/src/main/java/org/onap/clamp/loop/template/LoopType.java b/src/main/java/org/onap/clamp/loop/template/LoopType.java new file mode 100644 index 000000000..ccbc62a83 --- /dev/null +++ b/src/main/java/org/onap/clamp/loop/template/LoopType.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.clamp.loop.template; + +/** + * Enums for AllowedLoopType in LoopTemplate enity. + * + */ +public enum LoopType { + OPEN("OPEN"), CLOSED("CLOSED"), HYBRID("HYBRID"); + + private String value; + + private LoopType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/org/onap/clamp/loop/template/LoopTypeConvertor.java b/src/main/java/org/onap/clamp/loop/template/LoopTypeConvertor.java new file mode 100644 index 000000000..0b05613cb --- /dev/null +++ b/src/main/java/org/onap/clamp/loop/template/LoopTypeConvertor.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.clamp.loop.template; + +import java.util.stream.Stream; +import javax.persistence.AttributeConverter; + +/** + * Attribute Converter to allow using LoopType Enum values in DB and Java classes. + * + */ +public class LoopTypeConvertor implements AttributeConverter<LoopType, String> { + + @Override + public String convertToDatabaseColumn(LoopType loopType) { + if (loopType == null) { + return null; + } + return loopType.getValue(); + } + + @Override + public LoopType convertToEntityAttribute(String value) { + if (value == null) { + return null; + } + + return Stream.of(LoopType.values()).filter(c -> c.getValue().equals(value)).findFirst() + .orElseThrow(IllegalArgumentException::new); + } +} diff --git a/src/main/java/org/onap/clamp/loop/template/PolicyModel.java b/src/main/java/org/onap/clamp/loop/template/PolicyModel.java index 52f662bb4..d06cb8cff 100644 --- a/src/main/java/org/onap/clamp/loop/template/PolicyModel.java +++ b/src/main/java/org/onap/clamp/loop/template/PolicyModel.java @@ -24,11 +24,9 @@ package org.onap.clamp.loop.template; import com.google.gson.annotations.Expose; - import java.io.Serializable; import java.util.HashSet; import java.util.Set; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -36,7 +34,6 @@ import javax.persistence.Id; import javax.persistence.IdClass; import javax.persistence.ManyToMany; import javax.persistence.Table; - import org.onap.clamp.loop.common.AuditEntity; import org.onap.clamp.util.SemanticVersioning; @@ -83,7 +80,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * usedByElementModels getter. - * + * * @return the usedByElementModels */ public Set<LoopElementModel> getUsedByElementModels() { @@ -92,7 +89,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * policyModelTosca getter. - * + * * @return the policyModelTosca */ public String getPolicyModelTosca() { @@ -101,7 +98,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * policyModelTosca setter. - * + * * @param policyModelTosca the policyModelTosca to set */ public void setPolicyModelTosca(String policyModelTosca) { @@ -110,7 +107,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * policyModelType getter. - * + * * @return the modelType */ public String getPolicyModelType() { @@ -119,7 +116,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * policyModelType setter. - * + * * @param modelType the modelType to set */ public void setPolicyModelType(String modelType) { @@ -128,7 +125,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * version getter. - * + * * @return the version */ public String getVersion() { @@ -137,7 +134,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * version setter. - * + * * @param version the version to set */ public void setVersion(String version) { @@ -147,7 +144,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * policyAcronym getter. - * + * * @return the policyAcronym value */ public String getPolicyAcronym() { @@ -156,7 +153,7 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * policyAcronym setter. - * + * * @param policyAcronym The policyAcronym to set */ public void setPolicyAcronym(String policyAcronym) { @@ -171,13 +168,14 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable /** * Constructor. - * - * @param policyType The policyType (referenced in the blueprint + * + * @param policyType The policyType (referenced in the blueprint * @param policyModelTosca The policy tosca model in yaml - * @param version the version like 1.0.0 - * @param policyAcronym Subtype for policy if it exists (could be used by UI) + * @param version the version like 1.0.0 + * @param policyAcronym Subtype for policy if it exists (could be used by UI) */ - public PolicyModel(String policyType, String policyModelTosca, String version, String policyAcronym) { + public PolicyModel(String policyType, String policyModelTosca, String version, + String policyAcronym) { this.policyModelType = policyType; this.policyModelTosca = policyModelTosca; this.version = version; diff --git a/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java b/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java index 8e22852a9..0a09dd8d7 100644 --- a/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java +++ b/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP CLAMP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights + * Copyright (C) 2020 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,24 +23,62 @@ package org.onap.clamp.loop.template; +import com.google.gson.JsonObject; import java.util.List; - +import org.onap.clamp.clds.tosca.ToscaSchemaConstants; +import org.onap.clamp.clds.tosca.ToscaYamlToJsonConvertor; +import org.onap.clamp.util.SemanticVersioning; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PolicyModelsService { private final PolicyModelsRepository policyModelsRepository; + private ToscaYamlToJsonConvertor toscaYamlToJsonConvertor; @Autowired - public PolicyModelsService(PolicyModelsRepository policyModelrepo) { + public PolicyModelsService(PolicyModelsRepository policyModelrepo, + ToscaYamlToJsonConvertor convertor) { policyModelsRepository = policyModelrepo; + toscaYamlToJsonConvertor = convertor; } public PolicyModel saveOrUpdatePolicyModel(PolicyModel policyModel) { return policyModelsRepository.save(policyModel); } + /** + * Creates or updates the Tosca Policy Model. + * + * @param policyModelType + * The policyModeltype in Tosca yaml + * @param policyModel + * The Policymodel object + * @return The Policy Model + */ + public PolicyModel saveOrUpdateByPolicyModelType(String policyModelType, + String policyModelTosca) { + JsonObject jsonObject = toscaYamlToJsonConvertor.validateAndConvertToJson(policyModelTosca); + + String policyModelTypeName = toscaYamlToJsonConvertor.getValueFromMetadata(jsonObject, + ToscaSchemaConstants.METADATA_POLICY_MODEL_TYPE); + String acronym = toscaYamlToJsonConvertor.getValueFromMetadata(jsonObject, + ToscaSchemaConstants.METADATA_ACRONYM); + PolicyModel model = getPolicyModelByType( + policyModelTypeName != null ? policyModelTypeName : policyModelType); + + if (model == null) { + model = new PolicyModel(policyModelTypeName, policyModelTosca, + SemanticVersioning.incrementMajorVersion(null), acronym); + } else { + model.setVersion(SemanticVersioning + .incrementMajorVersion(model.getVersion() != null ? model.getVersion() : null)); + model.setPolicyModelType(policyModelTypeName); + model.setPolicyAcronym(acronym); + } + return saveOrUpdatePolicyModel(model); + } + public List<String> getAllPolicyModelTypes() { return policyModelsRepository.getAllPolicyModelType(); } @@ -56,4 +94,20 @@ public class PolicyModelsService { public Iterable<PolicyModel> getAllPolicyModelsByType(String type) { return policyModelsRepository.findByPolicyModelType(type); } + + public PolicyModel getPolicyModelByType(String type) { + List<PolicyModel> list = policyModelsRepository.findByPolicyModelType(type); + return list.stream().sorted().findFirst().orElse(null); + } + + /** + * Retrieves the Tosca model Yaml string. + * + * @param type The PolicyModelType + * @return The Tosca model Yaml string + */ + public String getPolicyModelTosca(String type) { + PolicyModel policyModel = getPolicyModelByType(type); + return policyModel != null ? policyModel.getPolicyModelTosca() : null; + } } diff --git a/src/main/java/org/onap/clamp/tosca/Dictionary.java b/src/main/java/org/onap/clamp/tosca/Dictionary.java index 7b4e513a2..44b5b6f68 100644 --- a/src/main/java/org/onap/clamp/tosca/Dictionary.java +++ b/src/main/java/org/onap/clamp/tosca/Dictionary.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP CLAMP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights + * Copyright (C) 2020 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,19 +24,18 @@ package org.onap.clamp.tosca; import com.google.gson.annotations.Expose; - import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - +import java.util.HashSet; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; -import javax.persistence.OneToMany; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; import javax.persistence.Table; - import org.onap.clamp.loop.common.AuditEntity; /** @@ -59,19 +58,27 @@ public class Dictionary extends AuditEntity implements Serializable { @Expose @Column(name = "dictionary_second_level") - private int secondLevelDictionary; + private int secondLevelDictionary = 0; @Expose @Column(name = "dictionary_type") private String subDictionaryType; @Expose - @OneToMany(mappedBy = "dictionary", cascade = CascadeType.ALL, fetch = FetchType.EAGER) - private List<DictionaryElement> dictionaryElements = new ArrayList<>(); + @ManyToMany( + fetch = FetchType.EAGER, + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) + @JoinTable( + name = "dictionary_to_dictionaryelements", + joinColumns = @JoinColumn(name = "dictionary_name", referencedColumnName = "name"), + inverseJoinColumns = {@JoinColumn( + name = "dictionary_element_short_name", + referencedColumnName = "short_name")}) + private Set<DictionaryElement> dictionaryElements = new HashSet<>(); /** * name getter. - * + * * @return the name */ public String getName() { @@ -80,7 +87,7 @@ public class Dictionary extends AuditEntity implements Serializable { /** * name setter. - * + * * @param name the name to set */ public void setName(String name) { @@ -89,7 +96,7 @@ public class Dictionary extends AuditEntity implements Serializable { /** * secondLevelDictionary getter. - * + * * @return the secondLevelDictionary */ public int getSecondLevelDictionary() { @@ -98,7 +105,7 @@ public class Dictionary extends AuditEntity implements Serializable { /** * secondLevelDictionary setter. - * + * * @param secondLevelDictionary the secondLevelDictionary to set */ public void setSecondLevelDictionary(int secondLevelDictionary) { @@ -107,7 +114,7 @@ public class Dictionary extends AuditEntity implements Serializable { /** * subDictionaryType getter. - * + * * @return the subDictionaryType */ public String getSubDictionaryType() { @@ -116,7 +123,7 @@ public class Dictionary extends AuditEntity implements Serializable { /** * subDictionaryType setter. - * + * * @param subDictionaryType the subDictionaryType to set */ public void setSubDictionaryType(String subDictionaryType) { @@ -125,20 +132,51 @@ public class Dictionary extends AuditEntity implements Serializable { /** * dictionaryElements getter. - * - * @return the dictionaryElements + * + * @return the dictionaryElements List of dictionary element */ - public List<DictionaryElement> getDictionaryElements() { + public Set<DictionaryElement> getDictionaryElements() { return dictionaryElements; } /** - * dictionaryElements setter. - * - * @param dictionaryElements the dictionaryElements to set + * Method to add a new dictionaryElement to the list. + * + * @param dictionaryElement The dictionary element + */ + public void addDictionaryElements(DictionaryElement dictionaryElement) { + dictionaryElements.add(dictionaryElement); + dictionaryElement.getUsedByDictionaries().add(this); + } + + /** + * Method to delete a dictionaryElement from the list. + * + * @param dictionaryElement The dictionary element */ - public void setDictionaryElements(List<DictionaryElement> dictionaryElements) { - this.dictionaryElements = dictionaryElements; + public void removeDictionaryElement(DictionaryElement dictionaryElement) { + dictionaryElements.remove(dictionaryElement); + dictionaryElement.getUsedByDictionaries().remove(this); + } + + /** + * Default Constructor. + */ + public Dictionary() { + + } + + /** + * Constructor. + * + * @param name The Dictionary name + * @param secondLevelDictionary defines if dictionary is a secondary level + * @param subDictionaryType defines the type of secondary level dictionary + */ + public Dictionary(String name, int secondLevelDictionary, String subDictionaryType) { + this.name = name; + this.secondLevelDictionary = secondLevelDictionary; + this.subDictionaryType = subDictionaryType; } @Override diff --git a/src/main/java/org/onap/clamp/tosca/DictionaryElement.java b/src/main/java/org/onap/clamp/tosca/DictionaryElement.java index e81885f3e..43a3106f5 100644 --- a/src/main/java/org/onap/clamp/tosca/DictionaryElement.java +++ b/src/main/java/org/onap/clamp/tosca/DictionaryElement.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP CLAMP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights + * Copyright (C) 2020 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,17 +24,15 @@ package org.onap.clamp.tosca; import com.google.gson.annotations.Expose; - import java.io.Serializable; - -import javax.persistence.CascadeType; +import java.util.HashSet; +import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; +import javax.persistence.ManyToMany; import javax.persistence.Table; - import org.onap.clamp.loop.common.AuditEntity; /** @@ -51,32 +49,31 @@ public class DictionaryElement extends AuditEntity implements Serializable { @Id @Expose - @Column(nullable = false, name = "name", unique = true) - private String name; + @Column(nullable = false, name = "short_name") + private String shortName; @Expose - @Column(nullable = false, name = "short_name", unique = true) - private String shortName; + @Column(nullable = false, name = "name") + private String name; @Expose - @Column(name = "description") + @Column(nullable = false, name = "description") private String description; @Expose @Column(nullable = false, name = "type") private String type; - @Column(name = "subdictionary_id", nullable = false) @Expose + @Column(nullable = true, name = "subdictionary_name") private String subDictionary; - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "dictionary_id") - private Dictionary dictionary; + @ManyToMany(mappedBy = "dictionaryElements", fetch = FetchType.EAGER) + private Set<Dictionary> usedByDictionaries = new HashSet<>(); /** * name getter. - * + * * @return the name */ public String getName() { @@ -85,7 +82,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * name setter. - * + * * @param name the name to set */ public void setName(String name) { @@ -94,7 +91,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * shortName getter. - * + * * @return the shortName */ public String getShortName() { @@ -103,7 +100,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * shortName setter. - * + * * @param shortName the shortName to set */ public void setShortName(String shortName) { @@ -112,7 +109,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * description getter. - * + * * @return the description */ public String getDescription() { @@ -121,7 +118,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * description setter. - * + * * @param description the description to set */ public void setDescription(String description) { @@ -130,7 +127,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * type getter. - * + * * @return the type */ public String getType() { @@ -139,7 +136,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * type setter. - * + * * @param type the type to set */ public void setType(String type) { @@ -148,7 +145,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * subDictionary getter. - * + * * @return the subDictionary */ public String getSubDictionary() { @@ -157,7 +154,7 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * subDictionary setter. - * + * * @param subDictionary the subDictionary to set */ public void setSubDictionary(String subDictionary) { @@ -165,21 +162,21 @@ public class DictionaryElement extends AuditEntity implements Serializable { } /** - * dictionary getter. - * - * @return the dictionary + * usedByDictionaries getter. + * + * @return the usedByDictionaries */ - public Dictionary getDictionary() { - return dictionary; + public Set<Dictionary> getUsedByDictionaries() { + return usedByDictionaries; } /** - * dictionary setter. - * - * @param dictionary the dictionary to set + * usedByDictionaries setter. + * + * @param usedByDictionaries the usedByDictionaries to set */ - public void setDictionary(Dictionary dictionary) { - this.dictionary = dictionary; + public void setUsedByDictionaries(Set<Dictionary> usedByDictionaries) { + this.usedByDictionaries = usedByDictionaries; } /** @@ -190,30 +187,46 @@ public class DictionaryElement extends AuditEntity implements Serializable { /** * Constructor. - * - * @param name The Dictionary element name - * @param shortName The short name - * @param description The description - * @param type The type of element + * + * @param name The Dictionary element name + * @param shortName The short name + * @param description The description + * @param type The type of element * @param subDictionary The sub type - * @param dictionary The parent dictionary */ - public DictionaryElement(String name, String shortName, String description, String type, String subDictionary, - Dictionary dictionary) { + public DictionaryElement(String name, String shortName, String description, String type, + String subDictionary) { this.name = name; this.shortName = shortName; this.description = description; this.type = type; this.subDictionary = subDictionary; - this.dictionary = dictionary; + } + + /** + * Constructor. + * + * @param name The Dictionary element name + * @param shortName The short name + * @param description The description + * @param type The type of element + * @param subDictionary The sub type + */ + public DictionaryElement(String name, String shortName, String description, String type, + String subDictionary, Set<Dictionary> usedByDictionaries) { + this.name = name; + this.shortName = shortName; + this.description = description; + this.type = type; + this.subDictionary = subDictionary; + this.usedByDictionaries = usedByDictionaries; } @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((dictionary == null) ? 0 : dictionary.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((shortName == null) ? 0 : shortName.hashCode()); return result; } @@ -229,21 +242,13 @@ public class DictionaryElement extends AuditEntity implements Serializable { return false; } DictionaryElement other = (DictionaryElement) obj; - if (dictionary == null) { - if (other.dictionary != null) { + if (shortName == null) { + if (other.shortName != null) { return false; } - } else if (!dictionary.equals(other.dictionary)) { - return false; - } - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { + } else if (!shortName.equals(other.shortName)) { return false; } return true; } - } diff --git a/src/main/java/org/onap/clamp/tosca/DictionaryElementsRepository.java b/src/main/java/org/onap/clamp/tosca/DictionaryElementsRepository.java index 96cb2e35e..43f6f1d40 100644 --- a/src/main/java/org/onap/clamp/tosca/DictionaryElementsRepository.java +++ b/src/main/java/org/onap/clamp/tosca/DictionaryElementsRepository.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP CLAMP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights + * Copyright (C) 2020 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/main/java/org/onap/clamp/tosca/DictionaryRepository.java b/src/main/java/org/onap/clamp/tosca/DictionaryRepository.java index 2a087b6d9..ae8430d93 100644 --- a/src/main/java/org/onap/clamp/tosca/DictionaryRepository.java +++ b/src/main/java/org/onap/clamp/tosca/DictionaryRepository.java @@ -24,7 +24,6 @@ package org.onap.clamp.tosca; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @@ -35,4 +34,7 @@ public interface DictionaryRepository extends JpaRepository<Dictionary, String> @Query("SELECT dict.name FROM Dictionary as dict") List<String> getAllDictionaryNames(); + @Query("SELECT dict.name FROM Dictionary as dict where dict.secondLevelDictionary = 1") + List<String> getAllSecondaryLevelDictionaryNames(); + } diff --git a/src/main/java/org/onap/clamp/tosca/DictionaryService.java b/src/main/java/org/onap/clamp/tosca/DictionaryService.java new file mode 100644 index 000000000..21ca1f7f7 --- /dev/null +++ b/src/main/java/org/onap/clamp/tosca/DictionaryService.java @@ -0,0 +1,142 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2020 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.tosca; + +import com.google.common.collect.Sets; +import java.util.List; +import java.util.Set; +import javax.persistence.EntityNotFoundException; +import org.onap.clamp.clds.service.SecureServiceBase; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DictionaryService extends SecureServiceBase { + + private final DictionaryRepository dictionaryRepository; + private final DictionaryElementsRepository dictionaryElementsRepository; + + /** + * Constructor. + */ + @Autowired + public DictionaryService(DictionaryRepository dictionaryRepository, + DictionaryElementsRepository dictionaryElementsRepository) { + this.dictionaryRepository = dictionaryRepository; + this.dictionaryElementsRepository = dictionaryElementsRepository; + + } + + public Dictionary saveOrUpdateDictionary(Dictionary dictionary) { + return dictionaryRepository.save(dictionary); + } + + /** + * Creates or Updates Dictionary Element. + * + * @param dictionaryName The Dictionary name + * @param dictionary The Dictionary object with dictionary elements + * @return updated Dictionary object with all dictionary elements + */ + public Dictionary saveOrUpdateDictionaryElement(String dictionaryName, Dictionary dictionary) { + Dictionary dict = getDictionary(dictionaryName); + + Set<DictionaryElement> newDictionaryElements = dictionary.getDictionaryElements(); + + for (DictionaryElement dictionaryElement : newDictionaryElements) { + if (dict.getDictionaryElements().contains(dictionaryElement)) { + // Update the Dictionary Element + getAndUpdateDictionaryElement(dict, dictionaryElement); + } else { + // Create the Dictionary Element + dict.addDictionaryElements(getAndUpdateDictionaryElement(dict, dictionaryElement)); + dictionaryRepository.save(dict); + } + } + + // Fetch again to get Dictionary with most recent updates. + return dictionaryRepository.findById(dictionaryName).orElseThrow( + () -> new EntityNotFoundException("Couldn't find Dictionary named: " + dictionaryName)); + + } + + private DictionaryElement getAndUpdateDictionaryElement(Dictionary dictionary, + DictionaryElement element) { + return dictionaryElementsRepository + .save(dictionaryElementsRepository.findById(element.getShortName()) + .map(p -> updateDictionaryElement(p, element, dictionary)) + .orElse(new DictionaryElement(element.getName(), element.getShortName(), + element.getDescription(), element.getType(), element.getSubDictionary(), + Sets.newHashSet(dictionary)))); + } + + public void deleteDictionary(Dictionary dictionary) { + dictionaryRepository.delete(dictionary); + } + + public void deleteDictionary(String dictionaryName) { + dictionaryRepository.deleteById(dictionaryName); + } + + public List<Dictionary> getAllDictionaries() { + return dictionaryRepository.findAll(); + } + + public List<String> getAllSecondaryLevelDictionaryNames() { + return dictionaryRepository.getAllSecondaryLevelDictionaryNames(); + } + + public Dictionary getDictionary(String dictionaryName) { + return dictionaryRepository.findById(dictionaryName).orElseThrow( + () -> new EntityNotFoundException("Couldn't find Dictionary named: " + dictionaryName)); + } + + /** + * Deletes a dictionary element from Dictionary by shortName. + * + * @param dictionaryName The dictionary name + * @param dictionaryElementShortName the dictionary Element Short name + */ + public void deleteDictionaryElement(String dictionaryName, String dictionaryElementShortName) { + if (dictionaryRepository.existsById(dictionaryName)) { + DictionaryElement element = + dictionaryElementsRepository.findById(dictionaryElementShortName).orElse(null); + if (element != null) { + Dictionary dict = getDictionary(dictionaryName); + dict.removeDictionaryElement(element); + dictionaryRepository.save(dict); + } + } + } + + private DictionaryElement updateDictionaryElement(DictionaryElement oldDictionaryElement, + DictionaryElement newDictionaryElement, Dictionary dictionary) { + oldDictionaryElement.setName(newDictionaryElement.getName()); + oldDictionaryElement.setDescription(newDictionaryElement.getDescription()); + oldDictionaryElement.setType(newDictionaryElement.getType()); + oldDictionaryElement.setSubDictionary(newDictionaryElement.getSubDictionary()); + oldDictionaryElement.getUsedByDictionaries().add(dictionary); + return oldDictionaryElement; + } +} diff --git a/src/main/java/org/onap/clamp/util/SemanticVersioning.java b/src/main/java/org/onap/clamp/util/SemanticVersioning.java index bf1529c2c..102284494 100644 --- a/src/main/java/org/onap/clamp/util/SemanticVersioning.java +++ b/src/main/java/org/onap/clamp/util/SemanticVersioning.java @@ -33,12 +33,13 @@ public class SemanticVersioning { public static final int BEFORE = -1; public static final int EQUAL = 0; public static final int AFTER = 1; + public static final String DEFAULT_VERSION = "1.0.0"; /** * The compare method that compare arg0 to arg1. - * - * @param arg0 A version in string for semantice versioning (a.b.c.d...) - * @param arg1 A version in string for semantice versioning (a.b.c.d...) + * + * @param arg0 A version in string for semantic versioning (a.b.c.d...) + * @param arg1 A version in string for semantic versioning (a.b.c.d...) * @return objects (arg0, arg1) given as parameters. It returns the value: 0: if * (arg0==arg1) -1: if (arg0 < arg1) 1: if (arg0 > arg1) */ @@ -58,11 +59,13 @@ public class SemanticVersioning { int smalestStringLength = Math.min(arg0Array.length, arg1Array.length); - for (int currentVersionIndex = 0; currentVersionIndex < smalestStringLength; ++currentVersionIndex) { - if (Integer.parseInt(arg0Array[currentVersionIndex]) < Integer.parseInt(arg1Array[currentVersionIndex])) { + for (int currentVersionIndex = + 0; currentVersionIndex < smalestStringLength; ++currentVersionIndex) { + if (Integer.parseInt(arg0Array[currentVersionIndex]) < Integer + .parseInt(arg1Array[currentVersionIndex])) { return BEFORE; } else if (Integer.parseInt(arg0Array[currentVersionIndex]) > Integer - .parseInt(arg1Array[currentVersionIndex])) { + .parseInt(arg1Array[currentVersionIndex])) { return AFTER; } // equals, so do not return anything, continue @@ -73,4 +76,18 @@ public class SemanticVersioning { return Integer.compare(arg0Array.length, arg1Array.length); } } -}
\ No newline at end of file + + /** + * Method to increment a version from its current version. + * + * @param currentVersion The current Version + * @return the increment version string + */ + public static String incrementMajorVersion(String currentVersion) { + if (currentVersion == null || currentVersion.isEmpty()) { + return DEFAULT_VERSION; + } + String[] versionArray = currentVersion.split("\\."); + return String.valueOf(Integer.parseInt(versionArray[0]) + 1)+".0.0"; + } +} |