diff options
Diffstat (limited to 'src/main/java')
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"; + } +} |