aboutsummaryrefslogtreecommitdiffstats
path: root/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/SubstitutionMappings.java
diff options
context:
space:
mode:
Diffstat (limited to 'jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/SubstitutionMappings.java')
-rw-r--r--jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/SubstitutionMappings.java518
1 files changed, 518 insertions, 0 deletions
diff --git a/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/SubstitutionMappings.java b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/SubstitutionMappings.java
new file mode 100644
index 0000000..f02ec2a
--- /dev/null
+++ b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/SubstitutionMappings.java
@@ -0,0 +1,518 @@
+package org.openecomp.sdc.toscaparser.api;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+
+import org.openecomp.sdc.toscaparser.api.common.ExceptionCollector;
+import org.openecomp.sdc.toscaparser.api.elements.NodeType;
+import org.openecomp.sdc.toscaparser.api.elements.PropertyDef;
+import org.openecomp.sdc.toscaparser.api.parameters.Input;
+import org.openecomp.sdc.toscaparser.api.parameters.Output;
+
+
+public class SubstitutionMappings {
+ // SubstitutionMappings class declaration
+
+ // SubstitutionMappings exports the topology template as an
+ // implementation of a Node type.
+
+ private static final String NODE_TYPE = "node_type";
+ private static final String REQUIREMENTS = "requirements";
+ private static final String CAPABILITIES = "capabilities";
+
+ private static final String SECTIONS[] = {NODE_TYPE, REQUIREMENTS, CAPABILITIES};
+
+ private static final String OPTIONAL_OUTPUTS[] = {"tosca_id", "tosca_name", "state"};
+
+ private LinkedHashMap<String,Object> subMappingDef;
+ private ArrayList<NodeTemplate> nodetemplates;
+ private ArrayList<Input> inputs;
+ private ArrayList<Output> outputs;
+ private ArrayList<Group> groups;
+ private NodeTemplate subMappedNodeTemplate;
+ private LinkedHashMap<String,Object> customDefs;
+ private LinkedHashMap<String,Object> _capabilities;
+ private LinkedHashMap<String,Object> _requirements;
+
+ public SubstitutionMappings(LinkedHashMap<String,Object> smsubMappingDef,
+ ArrayList<NodeTemplate> smnodetemplates,
+ ArrayList<Input> sminputs,
+ ArrayList<Output> smoutputs,
+ ArrayList<Group> smgroups,
+ NodeTemplate smsubMappedNodeTemplate,
+ LinkedHashMap<String,Object> smcustomDefs) {
+
+ subMappingDef = smsubMappingDef;
+ nodetemplates = smnodetemplates;
+ inputs = sminputs != null ? sminputs : new ArrayList<Input>();
+ outputs = smoutputs != null ? smoutputs : new ArrayList<Output>();
+ groups = smgroups != null ? smgroups : new ArrayList<Group>();
+ subMappedNodeTemplate = smsubMappedNodeTemplate;
+ customDefs = smcustomDefs != null ? smcustomDefs : new LinkedHashMap<String,Object>();
+ _validate();
+
+ _capabilities = null;
+ _requirements = null;
+ }
+
+ public String getType() {
+ if(subMappingDef != null) {
+ return (String)subMappingDef.get(NODE_TYPE);
+ }
+ return null;
+ }
+
+ public ArrayList<NodeTemplate> getNodeTemplates() {
+ return nodetemplates;
+ }
+
+ /*
+ @classmethod
+ def get_node_type(cls, sub_mapping_def):
+ if isinstance(sub_mapping_def, dict):
+ return sub_mapping_def.get(cls.NODE_TYPE)
+ */
+
+ public static String stGetNodeType(LinkedHashMap<String,Object> _subMappingDef) {
+ if(_subMappingDef instanceof LinkedHashMap) {
+ return (String)_subMappingDef.get(NODE_TYPE);
+ }
+ return null;
+ }
+
+ public String getNodeType() {
+ return (String)subMappingDef.get(NODE_TYPE);
+ }
+
+ public ArrayList<Input> getInputs() {
+ return inputs;
+ }
+
+ public ArrayList<Group> getGroups() {
+ return groups;
+ }
+
+ public LinkedHashMap<String,Object> getCapabilities() {
+ return (LinkedHashMap<String,Object>)subMappingDef.get(CAPABILITIES);
+ }
+
+ public LinkedHashMap<String,Object> getRequirements() {
+ return (LinkedHashMap<String,Object>)subMappingDef.get(REQUIREMENTS);
+ }
+
+ public NodeType getNodeDefinition() {
+ return new NodeType(getNodeType(), customDefs);
+ }
+
+ private void _validate() {
+ // Basic validation
+ _validateKeys();
+ _validateType();
+
+ // SubstitutionMapping class syntax validation
+ _validateInputs();
+ _validateCapabilities();
+ _validateRequirements();
+ _validateOutputs();
+ }
+
+ private void _validateKeys() {
+ // validate the keys of substitution mappings
+ for(String key: subMappingDef.keySet()) {
+ boolean bFound = false;
+ for(String s: SECTIONS) {
+ if(s.equals(key)) {
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound) {
+ ExceptionCollector.appendException(String.format(
+ "UnknownFieldError: SubstitutionMappings contain unknown field \"%s\"",
+ key));
+ }
+ }
+ }
+
+ private void _validateType() {
+ // validate the node_type of substitution mappings
+ String nodeType = (String)subMappingDef.get(NODE_TYPE);
+ if(nodeType == null) {
+ ExceptionCollector.appendException(String.format(
+ "MissingRequiredFieldError: SubstitutionMappings used in topology_template is missing required field \"%s\"",
+ NODE_TYPE));
+ }
+ Object nodeTypeDef = customDefs.get(nodeType);
+ if(nodeTypeDef == null) {
+ ExceptionCollector.appendException(String.format(
+ "InvalidNodeTypeError: \"%s\" is invalid",nodeType));
+ }
+ }
+
+ private void _validateInputs() {
+ // validate the inputs of substitution mappings.
+
+ // The inputs defined by the topology template have to match the
+ // properties of the node type or the substituted node. If there are
+ // more inputs than the substituted node has properties, default values
+ //must be defined for those inputs.
+
+ HashSet<String> allInputs = new HashSet<>();
+ for(Input inp: inputs) {
+ allInputs.add(inp.getName());
+ }
+ HashSet<String> requiredProperties = new HashSet<>();
+ for(PropertyDef pd: getNodeDefinition().getPropertiesDefObjects()) {
+ if(pd.isRequired() && pd.getDefault() == null) {
+ requiredProperties.add(pd.getName());
+ }
+ }
+ // Must provide inputs for required properties of node type.
+ for(String property: requiredProperties) {
+ // Check property which is 'required' and has no 'default' value
+ if(!allInputs.contains(property)) {
+ ExceptionCollector.appendException(String.format(
+ "MissingRequiredInputError: SubstitutionMappings with node_type \"%s\" is missing required input \"%s\"",
+ getNodeType(),property));
+ }
+ }
+ // If the optional properties of node type need to be customized by
+ // substituted node, it also is necessary to define inputs for them,
+ // otherwise they are not mandatory to be defined.
+ HashSet<String> customizedParameters = new HashSet<>();
+ if(subMappedNodeTemplate != null) {
+ customizedParameters.addAll(subMappedNodeTemplate.getProperties().keySet());
+ }
+ HashSet<String> allProperties = new HashSet<String>(
+ getNodeDefinition().getPropertiesDef().keySet());
+ HashSet<String> diffset = customizedParameters;
+ diffset.removeAll(allInputs);
+ for(String parameter: diffset) {
+ if(allProperties.contains(parameter)) {
+ ExceptionCollector.appendException(String.format(
+ "MissingRequiredInputError: SubstitutionMappings with node_type \"%s\" is missing required input \"%s\"",
+ getNodeType(),parameter));
+ }
+ }
+ // Additional inputs are not in the properties of node type must
+ // provide default values. Currently the scenario may not happen
+ // because of parameters validation in nodetemplate, here is a
+ // guarantee.
+ for(Input inp: inputs) {
+ diffset = allInputs;
+ diffset.removeAll(allProperties);
+ if(diffset.contains(inp.getName()) && inp.getDefault() == null) {
+ ExceptionCollector.appendException(String.format(
+ "MissingRequiredInputError: SubstitutionMappings with node_type \"%s\" is missing rquired input \"%s\"",
+ getNodeType(),inp.getName()));
+ }
+ }
+ }
+
+ private void _validateCapabilities() {
+ // validate the capabilities of substitution mappings
+
+ // The capabilities must be in node template which be mapped.
+ LinkedHashMap<String,Object> tplsCapabilities =
+ (LinkedHashMap<String,Object>)subMappingDef.get(CAPABILITIES);
+ LinkedHashMap<String,Capability> nodeCapabilities = null;
+ if(subMappedNodeTemplate != null) {
+ nodeCapabilities = subMappedNodeTemplate.getCapabilities();
+ }
+ if(nodeCapabilities != null) {
+ for(String cap: nodeCapabilities.keySet()) {
+ if(tplsCapabilities != null && tplsCapabilities.get(cap) == null) {
+ ; //pass
+ // ExceptionCollector.appendException(
+ // UnknownFieldError(what='SubstitutionMappings',
+ // field=cap))
+ }
+ }
+ }
+ }
+
+ private void _validateRequirements() {
+ // validate the requirements of substitution mappings
+ //*****************************************************
+ //TO-DO - Different from Python code!! one is a bug...
+ //*****************************************************
+ // The requirements must be in node template which be mapped.
+ LinkedHashMap<String,Object> tplsRequirements =
+ (LinkedHashMap<String,Object>)subMappingDef.get(REQUIREMENTS);
+ ArrayList<Object> nodeRequirements = null;
+ if(subMappedNodeTemplate != null) {
+ nodeRequirements = subMappedNodeTemplate.getRequirements();
+ }
+ if(nodeRequirements != null) {
+ for(Object ro: nodeRequirements) {
+ ArrayList<String> al = new ArrayList<String>(
+ ((LinkedHashMap<String,Object>)ro).keySet());
+ String cap = al.get(0);
+ if(tplsRequirements != null && tplsRequirements.get(cap) == null) {
+ ; //pass
+ // ExceptionCollector.appendException(
+ // UnknownFieldError(what='SubstitutionMappings',
+ // field=cap))
+ }
+ }
+ }
+ }
+
+ private void _validateOutputs() {
+ // validate the outputs of substitution mappings.
+
+ // The outputs defined by the topology template have to match the
+ // attributes of the node type or the substituted node template,
+ // and the observable attributes of the substituted node template
+ // have to be defined as attributes of the node type or outputs in
+ // the topology template.
+
+ // The outputs defined by the topology template have to match the
+ // attributes of the node type according to the specification, but
+ // it's reasonable that there are more inputs than the node type
+ // has properties, the specification will be amended?
+
+ for(Output output: outputs) {
+ Object ado = getNodeDefinition().getAttributesDef();
+ if(ado != null && ((LinkedHashMap<String,Object>)ado).get(output.getName()) == null) {
+ ExceptionCollector.appendException(String.format(
+ "UnknownOutputError: Unknown output \"%s\" in SubstitutionMappings with node_type \"%s\"",
+ output.getName(),getNodeType()));
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "SubstitutionMappings{" +
+ "subMappingDef=" + subMappingDef +
+ ", nodetemplates=" + nodetemplates +
+ ", inputs=" + inputs +
+ ", outputs=" + outputs +
+ ", groups=" + groups +
+ ", subMappedNodeTemplate=" + subMappedNodeTemplate +
+ ", customDefs=" + customDefs +
+ ", _capabilities=" + _capabilities +
+ ", _requirements=" + _requirements +
+ '}';
+ }
+
+ public String toLimitedString() {
+ return "SubstitutionMappings{" +
+ "subMappingDef=" + subMappingDef +
+ ", nodetemplates=" + nodetemplates +
+ ", inputs=" + inputs +
+ ", outputs=" + outputs +
+ ", groups=" + groups +
+ ", subMappedNodeTemplate=" + subMappedNodeTemplate.getName() +
+ ", customDefs=" + customDefs +
+ ", _capabilities=" + _capabilities +
+ ", _requirements=" + _requirements +
+ '}';
+ }
+}
+
+
+/*python
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import InvalidNodeTypeError
+from toscaparser.common.exception import MissingDefaultValueError
+from toscaparser.common.exception import MissingRequiredFieldError
+from toscaparser.common.exception import MissingRequiredInputError
+from toscaparser.common.exception import UnknownFieldError
+from toscaparser.common.exception import UnknownOutputError
+from toscaparser.elements.nodetype import NodeType
+from toscaparser.utils.gettextutils import _
+
+log = logging.getLogger('tosca')
+
+
+class SubstitutionMappings(object):
+ '''SubstitutionMappings class declaration
+
+ SubstitutionMappings exports the topology template as an
+ implementation of a Node type.
+ '''
+
+ SECTIONS = (NODE_TYPE, REQUIREMENTS, CAPABILITIES) = \
+ ('node_type', 'requirements', 'capabilities')
+
+ OPTIONAL_OUTPUTS = ['tosca_id', 'tosca_name', 'state']
+
+ def __init__(self, sub_mapping_def, nodetemplates, inputs, outputs,
+ sub_mapped_node_template, custom_defs):
+ self.nodetemplates = nodetemplates
+ self.sub_mapping_def = sub_mapping_def
+ self.inputs = inputs or []
+ self.outputs = outputs or []
+ self.sub_mapped_node_template = sub_mapped_node_template
+ self.custom_defs = custom_defs or {}
+ self._validate()
+
+ self._capabilities = None
+ self._requirements = None
+
+ @property
+ def type(self):
+ if self.sub_mapping_def:
+ return self.sub_mapping_def.get(self.NODE_TYPE)
+
+ @classmethod
+ def get_node_type(cls, sub_mapping_def):
+ if isinstance(sub_mapping_def, dict):
+ return sub_mapping_def.get(cls.NODE_TYPE)
+
+ @property
+ def node_type(self):
+ return self.sub_mapping_def.get(self.NODE_TYPE)
+
+ @property
+ def capabilities(self):
+ return self.sub_mapping_def.get(self.CAPABILITIES)
+
+ @property
+ def requirements(self):
+ return self.sub_mapping_def.get(self.REQUIREMENTS)
+
+ @property
+ def node_definition(self):
+ return NodeType(self.node_type, self.custom_defs)
+
+ def _validate(self):
+ # Basic validation
+ self._validate_keys()
+ self._validate_type()
+
+ # SubstitutionMapping class syntax validation
+ self._validate_inputs()
+ self._validate_capabilities()
+ self._validate_requirements()
+ self._validate_outputs()
+
+ def _validate_keys(self):
+ """validate the keys of substitution mappings."""
+ for key in self.sub_mapping_def.keys():
+ if key not in self.SECTIONS:
+ ExceptionCollector.appendException(
+ UnknownFieldError(what=_('SubstitutionMappings'),
+ field=key))
+
+ def _validate_type(self):
+ """validate the node_type of substitution mappings."""
+ node_type = self.sub_mapping_def.get(self.NODE_TYPE)
+ if not node_type:
+ ExceptionCollector.appendException(
+ MissingRequiredFieldError(
+ what=_('SubstitutionMappings used in topology_template'),
+ required=self.NODE_TYPE))
+
+ node_type_def = self.custom_defs.get(node_type)
+ if not node_type_def:
+ ExceptionCollector.appendException(
+ InvalidNodeTypeError(what=node_type))
+
+ def _validate_inputs(self):
+ """validate the inputs of substitution mappings.
+
+ The inputs defined by the topology template have to match the
+ properties of the node type or the substituted node. If there are
+ more inputs than the substituted node has properties, default values
+ must be defined for those inputs.
+ """
+
+ all_inputs = set([input.name for input in self.inputs])
+ required_properties = set([p.name for p in
+ self.node_definition.
+ get_properties_def_objects()
+ if p.required and p.default is None])
+ # Must provide inputs for required properties of node type.
+ for property in required_properties:
+ # Check property which is 'required' and has no 'default' value
+ if property not in all_inputs:
+ ExceptionCollector.appendException(
+ MissingRequiredInputError(
+ what=_('SubstitutionMappings with node_type ')
+ + self.node_type,
+ input_name=property))
+
+ # If the optional properties of node type need to be customized by
+ # substituted node, it also is necessary to define inputs for them,
+ # otherwise they are not mandatory to be defined.
+ customized_parameters = set(self.sub_mapped_node_template
+ .get_properties().keys()
+ if self.sub_mapped_node_template else [])
+ all_properties = set(self.node_definition.get_properties_def())
+ for parameter in customized_parameters - all_inputs:
+ if parameter in all_properties:
+ ExceptionCollector.appendException(
+ MissingRequiredInputError(
+ what=_('SubstitutionMappings with node_type ')
+ + self.node_type,
+ input_name=parameter))
+
+ # Additional inputs are not in the properties of node type must
+ # provide default values. Currently the scenario may not happen
+ # because of parameters validation in nodetemplate, here is a
+ # guarantee.
+ for input in self.inputs:
+ if input.name in all_inputs - all_properties \
+ and input.default is None:
+ ExceptionCollector.appendException(
+ MissingDefaultValueError(
+ what=_('SubstitutionMappings with node_type ')
+ + self.node_type,
+ input_name=input.name))
+
+ def _validate_capabilities(self):
+ """validate the capabilities of substitution mappings."""
+
+ # The capabilites must be in node template wchich be mapped.
+ tpls_capabilities = self.sub_mapping_def.get(self.CAPABILITIES)
+ node_capabiliteys = self.sub_mapped_node_template.get_capabilities() \
+ if self.sub_mapped_node_template else None
+ for cap in node_capabiliteys.keys() if node_capabiliteys else []:
+ if (tpls_capabilities and
+ cap not in list(tpls_capabilities.keys())):
+ pass
+ # ExceptionCollector.appendException(
+ # UnknownFieldError(what='SubstitutionMappings',
+ # field=cap))
+
+ def _validate_requirements(self):
+ """validate the requirements of substitution mappings."""
+
+ # The requirements must be in node template wchich be mapped.
+ tpls_requirements = self.sub_mapping_def.get(self.REQUIREMENTS)
+ node_requirements = self.sub_mapped_node_template.requirements \
+ if self.sub_mapped_node_template else None
+ for req in node_requirements if node_requirements else []:
+ if (tpls_requirements and
+ req not in list(tpls_requirements.keys())):
+ pass
+ # ExceptionCollector.appendException(
+ # UnknownFieldError(what='SubstitutionMappings',
+ # field=req))
+
+ def _validate_outputs(self):
+ """validate the outputs of substitution mappings.
+
+ The outputs defined by the topology template have to match the
+ attributes of the node type or the substituted node template,
+ and the observable attributes of the substituted node template
+ have to be defined as attributes of the node type or outputs in
+ the topology template.
+ """
+
+ # The outputs defined by the topology template have to match the
+ # attributes of the node type according to the specification, but
+ # it's reasonable that there are more inputs than the node type
+ # has properties, the specification will be amended?
+ for output in self.outputs:
+ if output.name not in self.node_definition.get_attributes_def():
+ ExceptionCollector.appendException(
+ UnknownOutputError(
+ where=_('SubstitutionMappings with node_type ')
+ + self.node_type,
+ output_name=output.name))*/ \ No newline at end of file