From 6d7284b5bcbbf6f57b843c5f30a50e9387b5ece8 Mon Sep 17 00:00:00 2001 From: shiria Date: Mon, 2 Jul 2018 11:10:56 +0300 Subject: Fix getFlat for datatype Fix getFlat when we driven from primitive type like string Adding support for service filter as tosca extension Issue-ID: SDC-1455 Change-Id: I57f05af13b394239ca55b71a946d69f56675bf19 Signed-off-by: shiria --- .../onap/sdc/tosca/datatypes/model/NodeFilter.java | 89 ++++++--- .../model/extension/RequirementAssignment.java | 31 ++++ .../datatypes/model/extension/ServiceFilter.java | 34 ++++ .../sdc/tosca/error/ToscaRuntimeException.java | 32 ++++ .../sdc/tosca/services/ToscaExtensionYamlUtil.java | 112 +++++++----- .../sdc/tosca/services/DataModelUtil.java | 83 +++------ .../services/impl/ToscaAnalyzerServiceImpl.java | 56 ++---- .../sdc/tosca/datatypes/ToscaModelTest.java | 37 +++- .../impl/ToscaAnalyzerServiceImplTest.java | 71 ++++---- .../ServiceTemplateDatatypeFlatTest.yaml | 200 +++++++++++++++++++++ .../model/serviceTemplateWithServiceFilter.yaml | 95 ++++++++++ 11 files changed, 633 insertions(+), 207 deletions(-) create mode 100644 common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/RequirementAssignment.java create mode 100644 common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/ServiceFilter.java create mode 100644 common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/error/ToscaRuntimeException.java create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/analyzerService/ServiceTemplateDatatypeFlatTest.yaml create mode 100644 openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/model/serviceTemplateWithServiceFilter.yaml diff --git a/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/NodeFilter.java b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/NodeFilter.java index d1d07b56e6..5f3d46504d 100644 --- a/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/NodeFilter.java +++ b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/NodeFilter.java @@ -1,9 +1,6 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ +/* + * Copyright © 2016-2018 European Support Limited + * * 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 @@ -15,33 +12,83 @@ * 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.sdc.tosca.datatypes.model; +import org.apache.commons.collections4.CollectionUtils; +import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil; + +import java.util.Iterator; import java.util.List; import java.util.Map; public class NodeFilter { - List>> properties; - List> capabilities; + private List>> properties; + private List> capabilities; + + //can't not be removed, in used in snake yaml + public List> getCapabilities() { + return capabilities; + } + + public void setCapabilities(List> capabilities) { + this.capabilities = capabilities; + } + + //can't not be removed, in used in snake yaml + public List>> getProperties() { + return properties; + } + - public List> getCapabilities() { - return capabilities; - } + //use this function in order to get node filter properties instead of getProperties function + public List>> getNormalizeProperties() { + return getNormalizeProperties(properties); + } - public void setCapabilities(List> capabilities) { - this.capabilities = capabilities; - } + private List>> getNormalizeProperties(List>> properties) { + ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); + if (CollectionUtils.isEmpty(properties)) { + return properties; + } + for (Map> propertyConstraintsEntity : properties) { + String propertyKey = propertyConstraintsEntity.keySet().iterator().next(); + List constraints = propertyConstraintsEntity.get(propertyKey); + Iterator iterator = constraints.iterator(); + while (iterator.hasNext()) { + Constraint constraintObj = iterator.next(); + Constraint constraint = toscaExtensionYamlUtil + .yamlToObject(toscaExtensionYamlUtil.objectToYaml(constraintObj), + Constraint.class); + constraints.remove(constraintObj); + constraints.add(constraint); + } + } + return properties; + } - public List>> getProperties() { - return properties; - } + //use this function in order to get node filter capabilities instead of getCapabilities function + public List> getNormalizeCapabilities() { + ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); + if (CollectionUtils.isEmpty(capabilities)) { + return capabilities; + } + for (Map capabilityEntry : capabilities) { + String capabilityKey = capabilityEntry.keySet().iterator().next(); + Object capabilityFilterObj = capabilityEntry.get(capabilityKey); + CapabilityFilter capabilityFilter = toscaExtensionYamlUtil.yamlToObject( + toscaExtensionYamlUtil.objectToYaml(capabilityFilterObj), CapabilityFilter.class); + capabilityFilter.setProperties(getNormalizeProperties(capabilityFilter.getProperties())); + capabilityEntry.remove(capabilityKey); + capabilityEntry.put(capabilityKey, capabilityFilter); + } + return capabilities; + } - public void setProperties(List>> properties) { - this.properties = properties; - } + public void setProperties(List>> properties) { + this.properties = properties; + } } diff --git a/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/RequirementAssignment.java b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/RequirementAssignment.java new file mode 100644 index 0000000000..07aed2b466 --- /dev/null +++ b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/RequirementAssignment.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * 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. + */ + +package org.onap.sdc.tosca.datatypes.model.extension; + + +public class RequirementAssignment extends org.onap.sdc.tosca.datatypes.model.RequirementAssignment{ + private ServiceFilter service_filter; + + + public ServiceFilter getService_filter() { + return service_filter; + } + + public void setService_filter(ServiceFilter servicefilter) { + this.service_filter = servicefilter; + } +} diff --git a/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/ServiceFilter.java b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/ServiceFilter.java new file mode 100644 index 0000000000..8423d5e293 --- /dev/null +++ b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/datatypes/model/extension/ServiceFilter.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * 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. + */ + +package org.onap.sdc.tosca.datatypes.model.extension; + +import org.onap.sdc.tosca.datatypes.model.NodeFilter; + + +public class ServiceFilter extends NodeFilter { + + Object tosca_id; + + public Object getTosca_id() { + return tosca_id; + } + + public void setTosca_id(Object toscaId) { + this.tosca_id = toscaId; + } + +} diff --git a/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/error/ToscaRuntimeException.java b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/error/ToscaRuntimeException.java new file mode 100644 index 0000000000..10c67bc4df --- /dev/null +++ b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/error/ToscaRuntimeException.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * 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. + */ + +package org.onap.sdc.tosca.error; + +public class ToscaRuntimeException extends RuntimeException { + + public ToscaRuntimeException(String message) { + super(message); + } + + public ToscaRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ToscaRuntimeException(Throwable cause) { + super(cause); + } +} diff --git a/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/services/ToscaExtensionYamlUtil.java b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/services/ToscaExtensionYamlUtil.java index efd4982541..4b8436197d 100644 --- a/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/services/ToscaExtensionYamlUtil.java +++ b/common/onap-tosca-datatype/src/main/java/org/onap/sdc/tosca/services/ToscaExtensionYamlUtil.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2017 European Support Limited + * Copyright © 2016-2018 European Support Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.onap.sdc.tosca.services; +import org.onap.sdc.tosca.error.ToscaRuntimeException; import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.introspector.Property; import org.yaml.snakeyaml.introspector.PropertyUtils; @@ -27,60 +28,75 @@ import java.beans.IntrospectionException; public class ToscaExtensionYamlUtil extends YamlUtil { - @Override - public Constructor getConstructor(Class typClass) { - return new ToscaWithHeatExtensionConstructor(typClass); - } + public static final String TOSCA_MODEL_PARAMETER_DEFINITION = + "org.onap.sdc.tosca.datatypes.model.ParameterDefinition"; + public static final String TOSCA_MODEL_EXT_PARAMETER_DEFINITION = + "org.onap.sdc.tosca.datatypes.model.heatextend.ParameterDefinitionExt"; + public static final String TOSCA_MODEL_REQUIREMENT_ASSIGNMENT = + "org.onap.sdc.tosca.datatypes.model.RequirementAssignment"; + public static final String TOSCA_MODEL_EXT_REQUIREMENT_ASSIGNMENT = + "org.onap.sdc.tosca.datatypes.model.extension.RequirementAssignment"; - @Override - protected PropertyUtils getPropertyUtils() { - return new ToscaPropertyUtilsWithHeatExtension(); - } + @Override + public Constructor getConstructor(Class typClass) { + return new ToscaWithHeatExtensionConstructor(typClass); + } - public class ToscaPropertyUtilsWithHeatExtension extends MyPropertyUtils { @Override - public Property getProperty(Class type, String name) - throws IntrospectionException { - Class classType = type; - try { - if (type - .equals(Class.forName("org.onap.sdc.tosca.datatypes.model.ParameterDefinition"))) { - classType = Class - .forName("org.onap.sdc.tosca.datatypes.model.heatextend.ParameterDefinitionExt"); - } - } catch (ClassNotFoundException ex) { - throw new RuntimeException(ex); - } - return super.getProperty(classType, name); + protected PropertyUtils getPropertyUtils() { + return new ToscaPropertyUtilsWithHeatExtension(); } - } - protected class ToscaWithHeatExtensionConstructor extends StrictMapAppenderConstructor { - public ToscaWithHeatExtensionConstructor(Class theRoot) { - super(theRoot); - yamlClassConstructors.put(NodeId.mapping, new MyPersistentObjectConstruct()); + public class ToscaPropertyUtilsWithHeatExtension extends MyPropertyUtils { + + @Override + public Property getProperty(Class type, String name) throws IntrospectionException { + Class classType = type; + try { + if (type.equals(Class.forName(TOSCA_MODEL_PARAMETER_DEFINITION))) { + classType = Class.forName(TOSCA_MODEL_EXT_PARAMETER_DEFINITION); + } + if (type.equals(Class.forName(TOSCA_MODEL_REQUIREMENT_ASSIGNMENT))) { + classType = Class.forName(TOSCA_MODEL_EXT_REQUIREMENT_ASSIGNMENT); + } + } catch (ClassNotFoundException ex) { + throw new ToscaRuntimeException(ex); + } + return super.getProperty(classType, name); + } } - class MyPersistentObjectConstruct extends Constructor.ConstructMapping { - @Override - protected Object constructJavaBean2ndStep(MappingNode node, Object object) { - Class type = node.getType(); - try { - if (type.equals( - Class.forName("org.onap.sdc.tosca.datatypes.model.ParameterDefinition"))) { - Class extendHeatClass = Class.forName( - "org.onap.sdc.tosca.datatypes.model.heatextend.ParameterDefinitionExt"); - Object extendHeatObject = extendHeatClass.newInstance(); - // create JavaBean - return super.constructJavaBean2ndStep(node, extendHeatObject); - } else { - // create JavaBean - return super.constructJavaBean2ndStep(node, object); - } - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { - throw new RuntimeException(ex); + protected class ToscaWithHeatExtensionConstructor extends StrictMapAppenderConstructor { + + public ToscaWithHeatExtensionConstructor(Class theRoot) { + super(theRoot); + yamlClassConstructors.put(NodeId.mapping, new MyPersistentObjectConstruct()); + } + + class MyPersistentObjectConstruct extends Constructor.ConstructMapping { + + @Override + protected Object constructJavaBean2ndStep(MappingNode node, Object object) { + Class type = node.getType(); + try { + if (type.equals(Class.forName(TOSCA_MODEL_PARAMETER_DEFINITION))) { + Class extendHeatClass = Class.forName(TOSCA_MODEL_EXT_PARAMETER_DEFINITION); + Object extendHeatObject = extendHeatClass.newInstance(); + // create JavaBean + return super.constructJavaBean2ndStep(node, extendHeatObject); + } else if (type.equals(Class.forName(TOSCA_MODEL_REQUIREMENT_ASSIGNMENT))) { + Class extendHeatClass = Class.forName(TOSCA_MODEL_EXT_REQUIREMENT_ASSIGNMENT); + Object extendHeatObject = extendHeatClass.newInstance(); + // create JavaBean + return super.constructJavaBean2ndStep(node, extendHeatObject); + } else { + // create JavaBean + return super.constructJavaBean2ndStep(node, object); + } + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { + throw new ToscaRuntimeException(ex); + } + } } - } } - } } diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java index fc411bf009..ac2f5da44a 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java @@ -18,49 +18,9 @@ package org.openecomp.sdc.tosca.services; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; - import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; -import org.onap.sdc.tosca.datatypes.model.AttributeDefinition; -import org.onap.sdc.tosca.datatypes.model.CapabilityAssignment; -import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition; -import org.onap.sdc.tosca.datatypes.model.Constraint; -import org.onap.sdc.tosca.datatypes.model.EntrySchema; -import org.onap.sdc.tosca.datatypes.model.GroupDefinition; -import org.onap.sdc.tosca.datatypes.model.Import; -import org.onap.sdc.tosca.datatypes.model.InterfaceDefinition; -import org.onap.sdc.tosca.datatypes.model.InterfaceDefinitionType; -import org.onap.sdc.tosca.datatypes.model.InterfaceType; -import org.onap.sdc.tosca.datatypes.model.NodeTemplate; -import org.onap.sdc.tosca.datatypes.model.NodeType; -import org.onap.sdc.tosca.datatypes.model.OperationDefinition; -import org.onap.sdc.tosca.datatypes.model.OperationDefinitionTemplate; -import org.onap.sdc.tosca.datatypes.model.OperationDefinitionType; -import org.onap.sdc.tosca.datatypes.model.ParameterDefinition; -import org.onap.sdc.tosca.datatypes.model.PolicyDefinition; -import org.onap.sdc.tosca.datatypes.model.PropertyDefinition; -import org.onap.sdc.tosca.datatypes.model.RelationshipTemplate; -import org.onap.sdc.tosca.datatypes.model.RequirementAssignment; -import org.onap.sdc.tosca.datatypes.model.RequirementDefinition; -import org.onap.sdc.tosca.datatypes.model.ServiceTemplate; -import org.onap.sdc.tosca.datatypes.model.SubstitutionMapping; -import org.onap.sdc.tosca.datatypes.model.TopologyTemplate; +import org.onap.sdc.tosca.datatypes.model.*; import org.onap.sdc.tosca.datatypes.model.heatextend.ParameterDefinitionExt; import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil; import org.onap.sdc.tosca.services.YamlUtil; @@ -72,13 +32,12 @@ import org.openecomp.sdc.logging.api.LoggerFactory; import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType; import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType; -import org.openecomp.sdc.tosca.errors.CreateInterfaceObjectErrorBuilder; -import org.openecomp.sdc.tosca.errors.CreateInterfaceOperationObjectErrorBuilder; -import org.openecomp.sdc.tosca.errors.InvalidAddActionNullEntityErrorBuilder; -import org.openecomp.sdc.tosca.errors.InvalidRequirementAssignmentErrorBuilder; -import org.openecomp.sdc.tosca.errors.ToscaInvalidInterfaceValueErrorBuilder; +import org.openecomp.sdc.tosca.errors.*; import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl; +import java.io.*; +import java.util.*; + /** * The type Data model util. */ @@ -723,11 +682,11 @@ public class DataModelUtil { if (CollectionUtils.isEmpty(templateRequirements)) { return nodeTemplateRequirementsAssignment; } - YamlUtil yamlUtil = new YamlUtil(); + ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); for (Map requirementAssignmentMap : templateRequirements) { for (Map.Entry requirementEntry : requirementAssignmentMap.entrySet()) { RequirementAssignment requirementAssignment = - (yamlUtil.yamlToObject(yamlUtil.objectToYaml(requirementEntry.getValue()), + (toscaExtensionYamlUtil.yamlToObject(toscaExtensionYamlUtil.objectToYaml(requirementEntry.getValue()), RequirementAssignment.class)); nodeTemplateRequirementsAssignment.put(requirementEntry.getKey(), requirementAssignment); } @@ -782,10 +741,10 @@ public class DataModelUtil { List matchRequirementAssignmentList = new ArrayList<>(); for (Map requirementMap : requirementsAssignmentList) { if (requirementMap.containsKey(requirementKey)) { - YamlUtil yamlUtil = new YamlUtil(); - RequirementAssignment requirementAssignment = - (yamlUtil.yamlToObject(yamlUtil.objectToYaml(requirementMap.get(requirementKey)), - RequirementAssignment.class)); + ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); + RequirementAssignment requirementAssignment = (toscaExtensionYamlUtil.yamlToObject( + toscaExtensionYamlUtil.objectToYaml(requirementMap.get(requirementKey)), + RequirementAssignment.class)); matchRequirementAssignmentList.add(requirementAssignment); } } @@ -1311,17 +1270,17 @@ public class DataModelUtil { private static void updateInterfaceDefinitionOperations(Map interfaceAsMap, InterfaceDefinition interfaceDefinition) { - { - Set fieldNames = CommonUtil.getClassFieldNames(InterfaceDefinitionType.class); - Optional operationDefinition; - - for (Map.Entry entry : interfaceAsMap.entrySet()) { - operationDefinition = createOperation(entry.getKey(), entry.getValue(), fieldNames, - interfaceDefinition instanceof InterfaceDefinitionType ? OperationDefinitionType.class : - OperationDefinitionTemplate.class); - operationDefinition.ifPresent(operation -> interfaceDefinition.addOperation(entry.getKey(), operation)); - } + + Set fieldNames = CommonUtil.getClassFieldNames(InterfaceDefinitionType.class); + Optional operationDefinition; + + for (Map.Entry entry : interfaceAsMap.entrySet()) { + operationDefinition = createOperation(entry.getKey(), entry.getValue(), fieldNames, + interfaceDefinition instanceof InterfaceDefinitionType ? OperationDefinitionType.class : + OperationDefinitionTemplate.class); + operationDefinition.ifPresent(operation -> interfaceDefinition.addOperation(entry.getKey(), operation)); } + } diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java index 46e58bdc81..5e0f2f2e41 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java @@ -19,50 +19,22 @@ package org.openecomp.sdc.tosca.services.impl; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.tosca.datatypes.model.*; +import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil; import org.openecomp.core.utilities.CommonMethods; import org.openecomp.sdc.common.errors.CoreException; +import org.openecomp.sdc.common.errors.SdcRuntimeException; import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes; import org.openecomp.sdc.tosca.datatypes.ToscaFlatData; -import org.onap.sdc.tosca.datatypes.model.AttributeDefinition; -import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition; -import org.onap.sdc.tosca.datatypes.model.CapabilityType; -import org.onap.sdc.tosca.datatypes.model.DefinitionOfDataType; -import org.onap.sdc.tosca.datatypes.model.DataType; -import org.onap.sdc.tosca.datatypes.model.Import; -import org.onap.sdc.tosca.datatypes.model.InterfaceDefinitionType; -import org.onap.sdc.tosca.datatypes.model.NodeTemplate; -import org.onap.sdc.tosca.datatypes.model.NodeType; -import org.onap.sdc.tosca.datatypes.model.ParameterDefinition; -import org.onap.sdc.tosca.datatypes.model.PropertyDefinition; -import org.onap.sdc.tosca.datatypes.model.PropertyType; -import org.onap.sdc.tosca.datatypes.model.RequirementAssignment; -import org.onap.sdc.tosca.datatypes.model.RequirementDefinition; -import org.onap.sdc.tosca.datatypes.model.ServiceTemplate; import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel; -import org.openecomp.sdc.tosca.errors.CreateInterfaceObjectErrorBuilder; -import org.openecomp.sdc.tosca.errors.ToscaElementTypeNotFoundErrorBuilder; -import org.openecomp.sdc.tosca.errors.ToscaFileNotFoundErrorBuilder; -import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder; -import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder; -import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder; +import org.openecomp.sdc.tosca.errors.*; import org.openecomp.sdc.tosca.services.DataModelUtil; -import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil; import org.openecomp.sdc.tosca.services.ToscaAnalyzerService; import org.openecomp.sdc.tosca.services.ToscaConstants; +import org.openecomp.sdc.tosca.services.ToscaUtil; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; import java.lang.reflect.InvocationTargetException; - -import org.openecomp.sdc.tosca.services.ToscaUtil; +import java.util.*; public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { @@ -272,7 +244,7 @@ public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { != null) { Object serviceTemplateFilter = substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME); - if (serviceTemplateFilter != null && serviceTemplateFilter instanceof Map) { + if (serviceTemplateFilter instanceof Map) { Object substituteServiceTemplate = ((Map) serviceTemplateFilter).get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME); handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate); @@ -660,7 +632,7 @@ public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { DataType targetDataType = (DataType) flatData.getFlatEntity(); DataType sourceDataType = serviceTemplate.getData_types().get(typeId); derivedFrom = sourceDataType.getDerived_from(); - if (derivedFrom != null) { + if (derivedFrom != null && !isPrimitiveType(derivedFrom)) { boolean isEntityFound = scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned, rootScanStartInx); @@ -675,6 +647,12 @@ public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { return false; } + private static boolean isPrimitiveType(String toscaType) { + return (toscaType.equals(PropertyType.STRING.getDisplayName()) || toscaType.equals(PropertyType.INTEGER + .getDisplayName()) + || toscaType.equals(PropertyType.FLOAT.getDisplayName())); + } + private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List filesScanned, int rootScanStartInx) { @@ -789,7 +767,11 @@ public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { combineInterface.setOperations( CommonMethods.mergeMaps(targetInterface.getOperations(), sourceInterface.getOperations())); - return DataModelUtil.convertInterfaceDefinitionTypeToObj(combineInterface).get(); + Optional interfaceDefObject = DataModelUtil.convertInterfaceDefinitionTypeToObj(combineInterface); + if( !interfaceDefObject.isPresent()){ + throw new SdcRuntimeException("Illegal Statement"); + } + return interfaceDefObject.get(); } private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) { diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/datatypes/ToscaModelTest.java b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/datatypes/ToscaModelTest.java index 6fb10ac1e0..3938d8f427 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/datatypes/ToscaModelTest.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/datatypes/ToscaModelTest.java @@ -60,7 +60,11 @@ import org.openecomp.sdc.tosca.services.ToscaConstants; public class ToscaModelTest { + public static final String FIRST_NODE_TEMPLATE = "firstNodeTemplate"; + public static final String REQ1 = "req1"; + public static final String REQ2 = "req2"; private YamlUtil yamlUtil = new YamlUtil(); + private ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); private static final String INTERFACE_ID = "inter_1"; private static final String NODE_TEMPLATE_ID = "firstNodeTemplate"; private static final String NODE_TYPE_ID = "compute_node_type"; @@ -77,6 +81,7 @@ public class ToscaModelTest { private static final String PRIMARY_IMPL = "myImpl.yaml"; private static final String DEPENDENCY_NAME = "script1.sh"; private static final String STRING_TYPE = "string"; + private static final String ST_WITH_SERVICE_FILTER = "/serviceTemplateWithServiceFilter.yaml"; @Test public void testServiceTemplateJavaToYaml() { @@ -254,8 +259,8 @@ public class ToscaModelTest { reqAssignment2.setRelationship("relationB"); Map nodeTemplateRequirement1 = new HashMap<>(); Map nodeTemplateRequirement2 = new HashMap<>(); - nodeTemplateRequirement1.put("req1", reqAssignment1); - nodeTemplateRequirement2.put("req2", reqAssignment2); + nodeTemplateRequirement1.put(REQ1, reqAssignment1); + nodeTemplateRequirement2.put(REQ2, reqAssignment2); nodeTemplate.setRequirements(new ArrayList<>()); nodeTemplate.getRequirements().add(nodeTemplateRequirement1); nodeTemplate.getRequirements().add(nodeTemplateRequirement2); @@ -419,12 +424,40 @@ public class ToscaModelTest { } } + @Test + public void testServiceFilter() throws IOException { + ServiceTemplate serviceTemplateWithServiceFilter = getServiceTemplateExt(BASE_DIR + ST_WITH_SERVICE_FILTER); + + NodeTemplate firstNodeTemplate = + DataModelUtil.getNodeTemplate(serviceTemplateWithServiceFilter, FIRST_NODE_TEMPLATE); + Map nodeTemplateRequirements = + DataModelUtil.getNodeTemplateRequirements(firstNodeTemplate); + + Object req1 = nodeTemplateRequirements.get(REQ1); + Assert.assertEquals(true, req1 instanceof org.onap.sdc.tosca.datatypes.model.extension.RequirementAssignment); + Assert.assertNotNull(((org.onap.sdc.tosca.datatypes.model.extension.RequirementAssignment)req1).getService_filter()); + + Object req2 = nodeTemplateRequirements.get(REQ2); + Assert.assertEquals(true, req2 instanceof org.onap.sdc.tosca.datatypes.model.extension.RequirementAssignment); + Assert.assertNotNull(((org.onap.sdc.tosca.datatypes.model.extension.RequirementAssignment)req2).getService_filter()); + + String serviceTemplateYaml = toscaExtensionYamlUtil.objectToYaml(serviceTemplateWithServiceFilter); + Assert.assertNotNull(serviceTemplateYaml); + + } + private ServiceTemplate getServiceTemplate(String inputPath) throws IOException { try (InputStream yamlFile = yamlUtil.loadYamlFileIs(inputPath)) { return yamlUtil.yamlToObject(yamlFile, ServiceTemplate.class); } } + private ServiceTemplate getServiceTemplateExt(String inputPath) throws IOException { + try (InputStream yamlFile = toscaExtensionYamlUtil.loadYamlFileIs(inputPath)) { + return toscaExtensionYamlUtil.yamlToObject(yamlFile, ServiceTemplate.class); + } + } + private InterfaceType createInterfaceType() { OperationDefinition operationDefinition = createOperationDefinition(); InterfaceType interfaceType = new InterfaceType(); diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImplTest.java b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImplTest.java index 71647a68a2..d9e77e1f84 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImplTest.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImplTest.java @@ -16,57 +16,30 @@ package org.openecomp.sdc.tosca.services.impl; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; +import org.junit.*; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; -import org.onap.sdc.tosca.datatypes.model.OperationDefinitionType; +import org.onap.sdc.tosca.datatypes.model.*; +import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil; import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.tosca.TestUtil; import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes; import org.openecomp.sdc.tosca.datatypes.ToscaFlatData; import org.openecomp.sdc.tosca.datatypes.ToscaNodeType; import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel; -import org.onap.sdc.tosca.datatypes.model.NodeTemplate; -import org.onap.sdc.tosca.datatypes.model.NodeType; -import org.onap.sdc.tosca.datatypes.model.ParameterDefinition; -import org.onap.sdc.tosca.datatypes.model.PropertyDefinition; -import org.onap.sdc.tosca.datatypes.model.RequirementAssignment; -import org.onap.sdc.tosca.datatypes.model.RequirementDefinition; -import org.onap.sdc.tosca.datatypes.model.ServiceTemplate; -import org.onap.sdc.tosca.datatypes.model.SubstitutionMapping; -import org.onap.sdc.tosca.datatypes.model.TopologyTemplate; -import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition; -import org.onap.sdc.tosca.datatypes.model.Import; import org.openecomp.sdc.tosca.services.DataModelUtil; -import org.onap.sdc.tosca.datatypes.model.InterfaceType; -import org.onap.sdc.tosca.datatypes.model.InterfaceDefinitionType; -import org.onap.sdc.tosca.datatypes.model.DataType; import org.openecomp.sdc.tosca.services.ToscaAnalyzerService; import org.openecomp.sdc.tosca.services.ToscaConstants; -import org.onap.sdc.tosca.datatypes.model.DefinitionOfDataType; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; import java.io.IOException; +import java.io.InputStream; +import java.util.*; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.mockito.Mockito.when; -import static org.junit.Assert.assertEquals; - -import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil; @RunWith(MockitoJUnitRunner.class) @@ -248,6 +221,32 @@ public class ToscaAnalyzerServiceImplTest { } } + @Test + public void testGetFlatEntityDataTypeDerivedFromPrimitive() throws Exception { + ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); + try (InputStream yamlFile = toscaExtensionYamlUtil.loadYamlFileIs( + "/mock/analyzerService/ServiceTemplateDatatypeFlatTest.yaml")) { + + ServiceTemplate serviceTemplateFromYaml = + toscaExtensionYamlUtil.yamlToObject(yamlFile, ServiceTemplate.class); + + ToscaFlatData flatData = toscaAnalyzerService.getFlatEntity(ToscaElementTypes.DATA_TYPE, + "org.openecomp.datatypes.heat.network.MyNewString", serviceTemplateFromYaml, toscaServiceModel); + + Assert.assertNotNull(flatData); + Assert.assertNotNull(flatData.getFlatEntity()); + DataType flatEntity = (DataType) flatData.getFlatEntity(); + Assert.assertEquals("org.openecomp.datatypes.heat.network.MyString", flatEntity.getDerived_from()); + Assert.assertEquals(2, flatEntity.getConstraints().size()); + Assert.assertNotNull(flatEntity.getConstraints().get(0).getValid_values()); + Assert.assertNotNull(flatEntity.getConstraints().get(1).getMax_length()); + + List inheritanceHierarchyType = flatData.getInheritanceHierarchyType(); + Assert.assertNotNull(inheritanceHierarchyType); + Assert.assertEquals(2, inheritanceHierarchyType.size()); + } + } + @Test public void testCalculateExposedRequirements() throws Exception { RequirementDefinition rd = new RequirementDefinition(); @@ -360,8 +359,7 @@ public class ToscaAnalyzerServiceImplTest { ra.setNode("server_cmaui"); ra.setRelationship("tosca.relationships.network.BindsTo"); - NodeTemplate port0 = - serviceTemplateFromYaml.getTopology_template().getNode_templates().get("cmaui_port_0"); + NodeTemplate port0 = serviceTemplateFromYaml.getTopology_template().getNode_templates().get("cmaui_port_0"); //Test With Empty requirementId Assert.assertEquals(false, toscaAnalyzerService.isRequirementExistInNodeTemplate(port0, "", ra)); @@ -386,8 +384,7 @@ public class ToscaAnalyzerServiceImplTest { ServiceTemplate serviceTemplateFromYaml = toscaExtensionYamlUtil.yamlToObject(yamlFile, ServiceTemplate.class); - NodeTemplate port0 = - serviceTemplateFromYaml.getTopology_template().getNode_templates().get("cmaui_port_0"); + NodeTemplate port0 = serviceTemplateFromYaml.getTopology_template().getNode_templates().get("cmaui_port_0"); List reqList = toscaAnalyzerService.getRequirements(port0, ToscaConstants.BINDING_REQUIREMENT_ID); assertEquals(1, reqList.size()); diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/analyzerService/ServiceTemplateDatatypeFlatTest.yaml b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/analyzerService/ServiceTemplateDatatypeFlatTest.yaml new file mode 100644 index 0000000000..d7dcdca111 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/analyzerService/ServiceTemplateDatatypeFlatTest.yaml @@ -0,0 +1,200 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: nested +imports: +- NeutronPortGlobalTypes: + file: NeutronPortGlobalTypesServiceTemplate.yaml +- NeutronNetGlobalTypes: + file: NeutronNetGlobalTypesServiceTemplate.yaml +- CommonGlobalTypes: + file: CommonGlobalTypesServiceTemplate.yaml +- CinderVolumeGlobalTypes: + file: CinderVolumeGlobalTypesServiceTemplate.yaml +- ContrailNetworkRuleGlobalType: + file: ContrailNetworkRuleGlobalTypeServiceTemplate.yaml +- NeutronSecurityRulesGlobalTypes: + file: NeutronSecurityRulesGlobalTypesServiceTemplate.yaml +- NovaServerGlobalTypes: + file: NovaServerGlobalTypesServiceTemplate.yaml +- ContrailVirtualNetworkGlobalType: + file: ContrailVirtualNetworkGlobalTypeServiceTemplate.yaml +- AbstractSubstituteGlobalTypes: + file: AbstractSubstituteGlobalTypesServiceTemplate.yaml +- nested: + file: GlobalSubstitutionTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vfc.nodes.heat.cmaui_image: + derived_from: org.openecomp.resource.vfc.nodes.heat.nova.Server + properties: + admin_pass: + description: The administrator password for the server + type: string + status: SUPPORTED + default: overridden default value + required: false + new_property: + description: new property + type: string + status: SUPPORTED + required: false +data_types: + org.openecomp.datatypes.heat.network.MyString: + derived_from: string + constraints: + - max_length: 50 + org.openecomp.datatypes.heat.network.MyNewString: + derived_from: org.openecomp.datatypes.heat.network.MyString + description: My new MAC/IP address pairs + constraints: + - valid_values: + - A + - B +topology_template: + inputs: + cmaui_names: + hidden: false + immutable: false + type: list + description: CMAUI1, CMAUI2 server names + entry_schema: + type: String + p1: + hidden: false + immutable: false + type: string + description: UID of OAM network + cmaui_image: + hidden: false + immutable: false + type: string + description: Image for CMAUI server + cmaui_flavor: + hidden: false + immutable: false + type: string + description: Flavor for CMAUI server + security_group_name: + hidden: false + immutable: false + description: not impotrtant + availability_zone_0: + label: availabilityzone name + hidden: false + immutable: false + type: string + description: availabilityzone name + node_templates: + server_cmaui: + type: org.openecomp.resource.vfc.nodes.heat.cmaui_image + properties: + flavor: + get_input: cmaui_flavor + availability_zone: + get_input: availability_zone_0 + image: + get_input: cmaui_image + name: + get_input: + - cmaui_names + - 0 + cmaui_port_0: + type: org.openecomp.resource.cp.nodes.heat.network.neutron.Port + properties: + replacement_policy: AUTO + security_groups: + - get_input: security_group_name + fixed_ips: + - ip_address: + get_input: + - cmaui_oam_ips + - 0 + network: + get_input: p1 + requirements: + - binding: + capability: tosca.capabilities.network.Bindable + node: server_cmaui + relationship: tosca.relationships.network.BindsTo + cmaui1_port_1: + type: org.openecomp.resource.cp.nodes.heat.network.neutron.Port + properties: + replacement_policy: AUTO + security_groups: + - get_input: security_group_name + fixed_ips: + - subnet: subnetNameVal + ip_address: + get_input: + - cmaui_oam_ips + - 1 + - subnet: subnetNameVal2 + ip_address: + get_input: + - cmaui_oam_ips + - 1 + network: jsa_net + requirements: + - link: + capability: tosca.capabilities.network.Linkable + node: jsa_net1 + relationship: tosca.relationships.network.LinksTo + - link: + capability: tosca.capabilities.network.Linkable + node: jsa_net2 + relationship: tosca.relationships.network.LinksTo + - binding: + capability: tosca.capabilities.network.Bindable + node: server_cmaui + relationship: tosca.relationships.network.BindsTo + jsa_net1: + type: org.openecomp.resource.vl.nodes.heat.network.neutron.Net + properties: + shared: true + network_name: + get_input: jsa_net_name + jsa_net2: + type: org.openecomp.resource.vl.nodes.heat.network.neutron.Net + properties: + shared: true + network_name: + get_input: jsa_net_name + groups: + nested: + type: org.openecomp.groups.heat.HeatStack + properties: + heat_file: ../Artifacts/nested.yml + description: cmaui server template for vMMSC + members: + - server_cmaui + - cmaui_port_0 + substitution_mappings: + node_type: org.openecomp.resource.abstract.nodes.heat.nested + capabilities: + host_server_cmaui: + - server_cmaui + - host + os_server_cmaui: + - server_cmaui + - os + endpoint_server_cmaui: + - server_cmaui + - endpoint + binding_server_cmaui: + - server_cmaui + - binding + scalable_server_cmaui: + - server_cmaui + - scalable + attachment_cmaui_port_0: + - cmaui_port_0 + - attachment + requirements: + local_storage_server_cmaui: + - server_cmaui + - local_storage + link_cmaui_port_0: + - cmaui_port_0 + - link + link_cmaui_port_invalid: + - cmaui_port_9 + - link diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/model/serviceTemplateWithServiceFilter.yaml b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/model/serviceTemplateWithServiceFilter.yaml new file mode 100644 index 0000000000..e1a49a46c0 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/mock/model/serviceTemplateWithServiceFilter.yaml @@ -0,0 +1,95 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: Test + template_author: OPENECOMP + template_version: 1.0.0 +description: testing desc tosca service template +imports: +- myfile1: + file: path1/path2/file1.yaml +- myfile2: + file: path1/path2/file2.yaml +artifact_types: + one_artifact: + mime_type: application/java-archive + file_ext: + - yaml + - xml +node_types: + compute_node_type: + derived_from: tosca.nodes.Root + version: 1.0.0 + description: tosca compute test + properties: + cpu_num: + type: integer + description: Number of CPUs requested for a software node instance + required: true + default: 1 + status: SUPPORTED + constraints: + - greater_or_equal: 5.0 + - equal: 5 + - greater_than: 6.02 + - in_range: + - 0 + - UNBOUNDED + attributes: + attDef1: + type: string + default: hi + status: SUPPORTED + requirements: + - re1: + capability: tosca.cap1 + occurrences: + - 5 + - 1 + capabilities: + cap1: + type: tosca.cap + valid_source_types: + - node1 + - node2 + occurrences: + - 1 + - UNBOUNDED +topology_template: + description: topologi template descroption + inputs: + inParam1: + type: string + description: desc + required: false + default: my default val + constraints: + - greater_than: 6 + - greater_or_equal: 9 + entry_schema: + type: tosca.myType + node_templates: + firstNodeTemplate: + type: nodeTypeRef + directives: + - selectable + - substitutable + properties: + prop2: '{ get_input: my_mysql_rootpw }' + prop1: abcd + attributes: + att2: '{ get_input: my_mysql_rootpw }' + att1: att1Val + requirements: + - req1: + service_filter: + properties: + - name : [{get_input : inParam1}] + - req2: + service_filter: + tosca_id: {get_input : inParam1} + substitution_mappings: + node_type: myNodeType.node + capabilities: + database_endpoint: + - database + - database_endpoint -- cgit 1.2.3-korg