Copy entry_defintion_type to TOSCA.meta
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / resourcetranslation / ResourceTranslationContrailServiceInstanceImpl.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
17
18 import static org.openecomp.sdc.tosca.services.ToscaConstants.MANDATORY_PROPERTY_NAME;
19 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_INVALID_NETWORK_CONNECTION;
20 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_MISSING_VIRTUAL_NETWORK_INTERFACE_LIST;
21 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_MULTIPLE_SERVICE_INSTANCE_DIFF_INTERFACES;
22 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_SERVICE_TEMPLATE_PROPERTY_GET_RESOURCE;
23 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_SERVICE_TEMPLATE_PROPERTY_INVALID_TYPE;
24 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_SERVICE_TEMPLATE_PROPERTY_UNSUPPORTED_RESOURCE;
25 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_UNSUPPORTED_NETWORK_RESOURCE_CONNECTION;
26
27 import com.google.common.collect.ImmutableList;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Objects;
33 import java.util.Optional;
34 import org.onap.sdc.tosca.datatypes.model.AttributeDefinition;
35 import org.onap.sdc.tosca.datatypes.model.GroupDefinition;
36 import org.onap.sdc.tosca.datatypes.model.Import;
37 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
38 import org.onap.sdc.tosca.datatypes.model.NodeType;
39 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
40 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
41 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
42 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
43 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
44 import org.onap.sdc.tosca.datatypes.model.SubstitutionMapping;
45 import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
46 import org.openecomp.sdc.common.errors.CoreException;
47 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
48 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
49 import org.openecomp.sdc.heat.datatypes.model.Resource;
50 import org.openecomp.sdc.heat.services.HeatConstants;
51 import org.openecomp.sdc.logging.api.Logger;
52 import org.openecomp.sdc.logging.api.LoggerFactory;
53 import org.openecomp.sdc.tosca.csar.AsdPackageHelper;
54 import org.openecomp.sdc.tosca.csar.ManifestUtils;
55 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
56 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
57 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
58 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
59 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
60 import org.openecomp.sdc.tosca.services.DataModelUtil;
61 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
62 import org.openecomp.sdc.tosca.services.ToscaConstants;
63 import org.openecomp.sdc.tosca.services.ToscaUtil;
64 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
65 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
66 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
67 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ContrailServiceInstanceTo;
68 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
69 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
70 import org.openecomp.sdc.translator.services.heattotosca.Constants;
71 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
72 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
73 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
74 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
75 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailTranslationHelper;
76 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
77
78 public class ResourceTranslationContrailServiceInstanceImpl extends ResourceTranslationBase {
79
80     private static final String INTERFACE_LIST = "interface_list";
81     protected static Logger logger = LoggerFactory.getLogger(ResourceTranslationContrailServiceInstanceImpl.class);
82
83     @Override
84     public void translate(TranslateTo translateTo) {
85         Resource serviceInstanceResource = translateTo.getResource();
86         AttachedResourceId contrailServiceTemplateAttached = getServiceTemplateAttachedId(translateTo, serviceInstanceResource);
87         if (contrailServiceTemplateAttached.isGetResource()) {
88             translateContrailServiceInstance(translateTo, serviceInstanceResource, contrailServiceTemplateAttached);
89         } else {
90             logger.warn(LOG_SERVICE_TEMPLATE_PROPERTY_GET_RESOURCE, translateTo.getResourceId(), translateTo.getResource().getType());
91         }
92     }
93
94     private void translateContrailServiceInstance(TranslateTo translateTo, Resource serviceInstanceResource,
95                                                   AttachedResourceId contrailServiceTemplateAttached) {
96         String contrailServiceTemplateResourceId = (String) contrailServiceTemplateAttached.getEntityId();
97         Resource contrailServiceTemplateResource = HeatToToscaUtil
98             .getResource(translateTo.getHeatOrchestrationTemplate(), contrailServiceTemplateResourceId, translateTo.getHeatFileName());
99         if (!contrailServiceTemplateResource.getType().equals(HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource())) {
100             logger.warn(LOG_SERVICE_TEMPLATE_PROPERTY_INVALID_TYPE, translateTo.getResourceId(), translateTo.getResource().getType(),
101                 contrailServiceTemplateResourceId, contrailServiceTemplateResource.getType(),
102                 HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource());
103             return;
104         }
105         Optional<String> contrailServiceTemplateTranslatedId = ResourceTranslationFactory.getInstance(contrailServiceTemplateResource)
106             .translateResource(translateTo.getHeatFileName(), translateTo.getServiceTemplate(), translateTo.getHeatOrchestrationTemplate(),
107                 contrailServiceTemplateResource, contrailServiceTemplateResourceId, translateTo.getContext());
108         if (!contrailServiceTemplateTranslatedId.isPresent()) {
109             logger.warn(LOG_SERVICE_TEMPLATE_PROPERTY_UNSUPPORTED_RESOURCE, translateTo.getResourceId(), translateTo.getResource().getType(),
110                 contrailServiceTemplateResourceId, contrailServiceTemplateResource.getType());
111             return;
112         }
113         ServiceTemplate globalSubstitutionServiceTemplate = translateTo.getContext().getTranslatedServiceTemplates()
114             .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
115         String contrailStId = ResourceTranslationContrailServiceTemplateImpl
116             .getContrailSubstitutedNodeTypeId(contrailServiceTemplateTranslatedId.get());
117         NodeType substitutedNodeType = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, contrailStId);
118         int numberOfPorts = getServiceInstanceNumberOfPorts(serviceInstanceResource);
119         if (substitutedNodeType.getRequirements() != null && substitutedNodeType.getRequirements().size() != numberOfPorts) {
120             logger.warn(LOG_MULTIPLE_SERVICE_INSTANCE_DIFF_INTERFACES, contrailServiceTemplateResourceId);
121             return;
122         }
123         addNetworkLinkRequirements(substitutedNodeType, numberOfPorts);
124         NodeTemplate substitutedNodeTemplate = createSubstitutedNodeTemplate(translateTo, contrailServiceTemplateResource, contrailStId,
125             numberOfPorts);
126         String computeNodeTypeId = new ContrailTranslationHelper()
127             .getComputeNodeTypeId(contrailServiceTemplateResource, contrailServiceTemplateResourceId, contrailServiceTemplateTranslatedId.get(),
128                 translateTo.getContext());
129         boolean orderedInterfaces = getOrderedInterfaces(contrailServiceTemplateResource);
130         ServiceTemplate nestedServiceTemplate = createNestedServiceTemplate(translateTo, computeNodeTypeId, contrailStId, substitutedNodeTemplate,
131             orderedInterfaces);
132         addAbstractSubstitutionProperty(translateTo, substitutedNodeTemplate.getProperties(), nestedServiceTemplate, contrailServiceTemplateResource);
133         translateTo.getContext().getTranslatedServiceTemplates().put(new ContrailTranslationHelper()
134             .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(), translateTo.getTranslatedId()), nestedServiceTemplate);
135     }
136
137     private void addAbstractSubstitutionProperty(TranslateTo translateTo, Map<String, Object> substitutionProperties,
138                                                  ServiceTemplate nestedServiceTemplate, Resource contrailServiceTemplateResource) {
139         Map<String, Object> innerProps = new HashMap<>();
140         innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME, ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
141         Object countValue = handleScaleOutProperty(translateTo, innerProps);
142         handleServiceScalingProperty(translateTo, innerProps, contrailServiceTemplateResource);
143         boolean mandatory = false;
144         if (countValue instanceof Integer && (Integer) countValue > 0) {
145             mandatory = true;
146         }
147         if (countValue == null) {
148             mandatory = true;
149         }
150         innerProps.put(MANDATORY_PROPERTY_NAME, mandatory);
151         substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
152     }
153
154     private Object handleScaleOutProperty(TranslateTo translateTo, Map<String, Object> innerProps) {
155         Object scaleOutPropertyValue = translateTo.getResource().getProperties().get(HeatConstants.SCALE_OUT_PROPERTY_NAME);
156         Object countValue = null;
157         if (scaleOutPropertyValue instanceof Map) {
158             countValue = TranslatorHeatToToscaPropertyConverter
159                 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(), Constants.MAX_INSTANCES_PROPERTY_NAME,
160                     ((Map) scaleOutPropertyValue).get(Constants.MAX_INSTANCES_PROPERTY_NAME), null, translateTo.getHeatFileName(),
161                     translateTo.getHeatOrchestrationTemplate(), null, translateTo.getContext());
162             if (countValue != null) {
163                 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
164             } else {
165                 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
166             }
167         } else {
168             innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
169         }
170         return countValue;
171     }
172
173     private void handleServiceScalingProperty(TranslateTo translateTo, Map<String, Object> innerProps, Resource contrailServiceTemplateResource) {
174         Object serviceScalingPropertyValue = contrailServiceTemplateResource.getProperties().get(HeatConstants.SERVICE_SCALING_PROPERTY_NAME);
175         Object serviceScalingValue;
176         if (serviceScalingPropertyValue != null) {
177             serviceScalingValue = TranslatorHeatToToscaPropertyConverter
178                 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(), HeatConstants.SERVICE_SCALING_PROPERTY_NAME,
179                     serviceScalingPropertyValue, null, translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
180                     translateTo.getContext());
181             if (serviceScalingValue != null) {
182                 innerProps.put(ToscaConstants.SCALING_ENABLED_PROPERTY_NAME,
183                     (HeatBoolean.isValueBoolean(serviceScalingValue)) ? HeatBoolean.eval(serviceScalingValue) : serviceScalingValue);
184             }
185         }
186     }
187
188     private boolean getOrderedInterfaces(Resource contrailServiceTemplate) {
189         Object orderedInterfaces = contrailServiceTemplate.getProperties().get("ordered_interfaces");
190         if (orderedInterfaces == null) {
191             return false;
192         }
193         if (orderedInterfaces instanceof String) {
194             return HeatBoolean.eval(orderedInterfaces);
195         }
196         //if get_param, set default value to true
197         return true;
198     }
199
200     private ServiceTemplate createNestedServiceTemplate(TranslateTo translateTo, String computeNodeTypeId, String substitutedNodeTypeId,
201                                                         NodeTemplate substitutedNodeTemplate, boolean orderedInterfaces) {
202         ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
203         setNestedServiceTemplateGeneralDetails(translateTo, nestedSubstitutionServiceTemplate);
204         String heatStackGroupKey = addHeatStackGroup(translateTo, nestedSubstitutionServiceTemplate);
205         addSubstitutionMappingEntry(nestedSubstitutionServiceTemplate, substitutedNodeTypeId);
206         handleInputParameters(nestedSubstitutionServiceTemplate, translateTo);
207         String computeNodeTemplateId = handleComputeNodeTemplate(translateTo, computeNodeTypeId, nestedSubstitutionServiceTemplate,
208             heatStackGroupKey);
209         handleOutputParameters(nestedSubstitutionServiceTemplate, computeNodeTemplateId, translateTo);
210         handleServiceInstanceInterfaces(translateTo,
211             new ContrailServiceInstanceTo(nestedSubstitutionServiceTemplate, substitutedNodeTemplate, heatStackGroupKey, orderedInterfaces,
212                 computeNodeTemplateId));
213         return nestedSubstitutionServiceTemplate;
214     }
215
216     private void handleOutputParameters(ServiceTemplate nestedSubstitutionServiceTemplate, String nodeTemplateId, TranslateTo translateTo) {
217         if (nodeTemplateId == null) {
218             return;
219         }
220         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
221         Optional<NodeType> contrailAbstractNodeType = toscaAnalyzerService
222             .fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo.getContext().getGlobalServiceTemplates().values());
223         if (!contrailAbstractNodeType.isPresent()) {
224             return;
225         }
226         Map<String, AttributeDefinition> contrailAbstractAttributes = contrailAbstractNodeType.get().getAttributes();
227         Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateOutputs = new HashMap<>();
228         if (contrailAbstractAttributes == null) {
229             return;
230         }
231         for (Map.Entry<String, AttributeDefinition> attributeDefinitionEntry : contrailAbstractAttributes.entrySet()) {
232             AttributeDefinition abstractAttributeDef = attributeDefinitionEntry.getValue();
233             if (abstractAttributeDef != null) {
234                 Map<String, List> outputValue = new HashMap<>();
235                 List<String> outputGetAttributeList = new ArrayList<>();
236                 outputGetAttributeList.add(nodeTemplateId);
237                 outputGetAttributeList.add(attributeDefinitionEntry.getKey());
238                 outputValue.put(ToscaFunctions.GET_ATTRIBUTE.getFunctionName(), outputGetAttributeList);
239                 nestedSubstitutionServiceTemplateOutputs
240                     .put(attributeDefinitionEntry.getKey(), DataModelUtil.convertAttributeDefToParameterDef(abstractAttributeDef, outputValue));
241             }
242         }
243         if (!nestedSubstitutionServiceTemplateOutputs.isEmpty()) {
244             nestedSubstitutionServiceTemplate.getTopology_template().setOutputs(nestedSubstitutionServiceTemplateOutputs);
245         }
246     }
247
248     private void handleServiceInstanceInterfaces(TranslateTo translateTo, ContrailServiceInstanceTo contrailServiceInstanceTo) {
249         Resource serviceInstanceResource = translateTo.getResource();
250         Object interfaceListProperty = serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
251         if (interfaceListProperty == null) {
252             return;
253         }
254         if (interfaceListProperty instanceof List) {
255             for (int index = 0; index < ((List) interfaceListProperty).size(); index++) {
256                 Object interfaceEntry = ((List) interfaceListProperty).get(index);
257                 handleInterface(translateTo, interfaceEntry, index, contrailServiceInstanceTo);
258             }
259         } else if (interfaceListProperty instanceof Map) {
260             handleInterface(translateTo, interfaceListProperty, null, contrailServiceInstanceTo);
261         }
262     }
263
264     private void handleInterface(TranslateTo translateTo, Object interfacePropertyValue, Integer index,
265                                  ContrailServiceInstanceTo contrailServiceInstanceTo) {
266         if (index == null) {
267             index = 0;
268         }
269         NodeTemplate portNodeTemplate = createPortNodeTemplate(index, contrailServiceInstanceTo.isOrderedInterfaces(),
270             contrailServiceInstanceTo.getComputeNodeTemplateId());
271         String portNodeTemplateId = Constants.SERVICE_INSTANCE_PORT_PREFIX + index;
272         String portReqMappingKey = Constants.SERVICE_INSTANCE_LINK_PREFIX + portNodeTemplateId;
273         DataModelUtil.addNodeTemplate(contrailServiceInstanceTo.getNestedSubstitutionServiceTemplate(), portNodeTemplateId, portNodeTemplate);
274         updateSubstitutionMappingRequirement(contrailServiceInstanceTo.getNestedSubstitutionServiceTemplate(), portReqMappingKey, portNodeTemplateId);
275         updateHeatStackGroup(contrailServiceInstanceTo.getNestedSubstitutionServiceTemplate(), contrailServiceInstanceTo.getHeatStackGroupKey(),
276             portNodeTemplateId);
277         connectPortToNetwork(translateTo, interfacePropertyValue, contrailServiceInstanceTo.getSubstitutedNodeTemplate(), portReqMappingKey);
278     }
279
280     private void connectPortToNetwork(TranslateTo translateTo, Object interfacePropertyValue, NodeTemplate substitutedNodeTemplate,
281                                       String portReqMappingKey) {
282         List<String> validNetworksForConnections = ImmutableList.of(HeatResourcesTypes.NEUTRON_NET_RESOURCE_TYPE.getHeatResource(),
283             HeatResourcesTypes.CONTRAIL_VIRTUAL_NETWORK_RESOURCE_TYPE.getHeatResource());
284         if (!(interfacePropertyValue instanceof Map)) {
285             return;
286         }
287         Object virtualNetworkValue = ((Map) interfacePropertyValue).get(HeatConstants.VIRTUAL_NETWORK_PROPERTY_NAME);
288         if (virtualNetworkValue == null) {
289             logger.warn(LOG_MISSING_VIRTUAL_NETWORK_INTERFACE_LIST, translateTo.getResourceId(), translateTo.getResource().getType());
290             return;
291         }
292         Optional<AttachedResourceId> networkAttachedResourceId = HeatToToscaUtil
293             .extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
294                 virtualNetworkValue);
295         if (!networkAttachedResourceId.isPresent()) {
296             return;
297         }
298         Optional<String> networkResourceId = HeatToToscaUtil.getContrailAttachedHeatResourceId(networkAttachedResourceId.get());
299         if (networkResourceId.isPresent()) {
300             Resource networkResource = HeatToToscaUtil
301                 .getResource(translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(), translateTo.getHeatFileName());
302             if (validNetworksForConnections.contains(networkResource.getType())) {
303                 Optional<String> networkTranslatedId = getResourceTranslatedId(translateTo.getHeatFileName(),
304                     translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(), translateTo.getContext());
305                 networkTranslatedId
306                     .ifPresent(translatedId -> addLinkToNetworkRequirementAssignment(substitutedNodeTemplate, translatedId, portReqMappingKey));
307             } else {
308                 logger.warn(LOG_UNSUPPORTED_NETWORK_RESOURCE_CONNECTION, translateTo.getResourceId(), translateTo.getResource().getType());
309             }
310         } else if (networkAttachedResourceId.get().isGetParam() && networkAttachedResourceId.get().getEntityId() instanceof String) {
311             TranslatedHeatResource translatedSharedResourceId = translateTo.getContext().getHeatSharedResourcesByParam()
312                 .get(networkAttachedResourceId.get().getEntityId());
313             if (Objects.nonNull(translatedSharedResourceId) && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
314                 addLinkToNetworkRequirementAssignment(substitutedNodeTemplate, translatedSharedResourceId.getTranslatedId(), portReqMappingKey);
315             }
316         } else {
317             logger.warn(LOG_INVALID_NETWORK_CONNECTION, translateTo.getResourceId(), translateTo.getResource().getType(),
318                 virtualNetworkValue.toString());
319         }
320     }
321
322     private NodeTemplate createPortNodeTemplate(Integer index, boolean orderedInterfaces, String computeNodeTemplateId) {
323         NodeTemplate portNodeTemplate = new NodeTemplate();
324         portNodeTemplate.setType(ToscaNodeType.CONTRAIL_PORT);
325         Map<String, Object> portProperties = new HashMap<>();
326         portProperties.put("static_routes", DataModelUtil.createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index, "static_routes"));
327         portProperties.put("virtual_network", DataModelUtil.createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index, "virtual_network"));
328         portProperties
329             .put("allowed_address_pairs", DataModelUtil.createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index, "allowed_address_pairs"));
330         portProperties.put("ip_address", DataModelUtil.createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index, "ip_address"));
331         portProperties.put("static_route", DataModelUtil.createGetInputPropertyValueFromListParameter("static_routes_list", index));
332         portProperties.put("shared_ip", DataModelUtil.createGetInputPropertyValueFromListParameter("shared_ip_list", index));
333         portProperties.put("interface_type", DataModelUtil.createGetInputPropertyValueFromListParameter("service_interface_type_list", index));
334         if (orderedInterfaces) {
335             portProperties.put("order", index);
336         }
337         portNodeTemplate.setProperties(portProperties);
338         DataModelUtil.addBindingReqFromPortToCompute(computeNodeTemplateId, portNodeTemplate);
339         return portNodeTemplate;
340     }
341
342     private void addLinkToNetworkRequirementAssignment(NodeTemplate nodeTemplate, String connectedNodeTranslatedId, String requirementId) {
343         if (nodeTemplate == null || connectedNodeTranslatedId == null) {
344             return;
345         }
346         RequirementAssignment requirement = new RequirementAssignment();
347         requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
348         requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
349         requirement.setNode(connectedNodeTranslatedId);
350         DataModelUtil.addRequirementAssignment(nodeTemplate, requirementId, requirement);
351     }
352
353     private void updateHeatStackGroup(ServiceTemplate serviceTemplate, String heatStackGroupKey, String memberId) {
354         serviceTemplate.getTopology_template().getGroups().get(heatStackGroupKey).getMembers().add(memberId);
355     }
356
357     private void updateSubstitutionMappingRequirement(ServiceTemplate serviceTemplate, String portReqMappingKey, String portNodeTemplateId) {
358         List<String> portReqMappingValue = new ArrayList<>();
359         portReqMappingValue.add(portNodeTemplateId);
360         portReqMappingValue.add(ToscaConstants.LINK_REQUIREMENT_ID);
361         DataModelUtil.addSubstitutionMappingReq(serviceTemplate, portReqMappingKey, portReqMappingValue);
362     }
363
364     private void addSubstitutionMappingEntry(ServiceTemplate nestedSubstitutionServiceTemplate, String substitutedNodeTypeId) {
365         SubstitutionMapping substitutionMappings = new SubstitutionMapping();
366         substitutionMappings.setNode_type(substitutedNodeTypeId);
367         DataModelUtil.addSubstitutionMapping(nestedSubstitutionServiceTemplate, substitutionMappings);
368     }
369
370     private void handleInputParameters(ServiceTemplate nestedSubstitutionServiceTemplate, TranslateTo translateTo) {
371         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
372         Optional<NodeType> contrailAbstractNodeType = toscaAnalyzerService
373             .fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo.getContext().getGlobalServiceTemplates().values());
374         Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateInputs = new HashMap<>();
375         if (contrailAbstractNodeType.isPresent()) {
376             Map<String, PropertyDefinition> contrailAbstractProperties = contrailAbstractNodeType.get().getProperties();
377             for (Map.Entry<String, PropertyDefinition> propertyEntry : contrailAbstractProperties.entrySet()) {
378                 PropertyDefinition abstractPropertyDef = contrailAbstractProperties.get(propertyEntry.getKey());
379                 if (abstractPropertyDef != null) {
380                     nestedSubstitutionServiceTemplateInputs
381                         .put(propertyEntry.getKey(), DataModelUtil.convertPropertyDefToParameterDef(abstractPropertyDef));
382                 }
383             }
384         }
385         if (!nestedSubstitutionServiceTemplateInputs.isEmpty()) {
386             nestedSubstitutionServiceTemplate.getTopology_template().setInputs(nestedSubstitutionServiceTemplateInputs);
387         }
388     }
389
390     private String handleComputeNodeTemplate(TranslateTo translateTo, String computeNodeTypeId, ServiceTemplate nestedSubstitutionServiceTemplate,
391                                              String heatStackGroupKey) {
392         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
393         Optional<NodeType> contrailComputeNodeType = toscaAnalyzerService
394             .fetchNodeType(ToscaNodeType.CONTRAIL_COMPUTE, translateTo.getContext().getGlobalServiceTemplates().values());
395         Map<String, Object> computeNodeTemplateProperties = null;
396         if (contrailComputeNodeType.isPresent()) {
397             Map<String, PropertyDefinition> contrailComputeProperties = contrailComputeNodeType.get().getProperties();
398             computeNodeTemplateProperties = new HashMap<>();
399             if (contrailComputeProperties != null) {
400                 for (String computePropertyKey : contrailComputeProperties.keySet()) {
401                     Map<String, Object> getInputProperty = new HashMap<>();
402                     getInputProperty.put(ToscaFunctions.GET_INPUT.getFunctionName(), computePropertyKey);
403                     computeNodeTemplateProperties.put(computePropertyKey, getInputProperty);
404                 }
405             }
406         }
407         NodeTemplate computeNodeTemplate = new NodeTemplate();
408         computeNodeTemplate.setType(computeNodeTypeId);
409         if (computeNodeTemplateProperties != null && !computeNodeTemplateProperties.isEmpty()) {
410             computeNodeTemplate.setProperties(computeNodeTemplateProperties);
411         }
412         String computeNodeTemplateId = translateTo.getTranslatedId();
413         DataModelUtil.addNodeTemplate(nestedSubstitutionServiceTemplate, computeNodeTemplateId, computeNodeTemplate);
414         nestedSubstitutionServiceTemplate.getTopology_template().getGroups().get(heatStackGroupKey).getMembers().add(computeNodeTemplateId);
415         return computeNodeTemplateId;
416     }
417
418     private String addHeatStackGroup(TranslateTo translateTo, ServiceTemplate serviceTemplate) {
419         GroupDefinition serviceInstanceGroupDefinition = new GroupDefinition();
420         serviceInstanceGroupDefinition.setType(ToscaGroupType.HEAT_STACK);
421         Map<String, Object> groupProperties = new HashMap<>();
422         groupProperties
423             .put("heat_file", "../" + (new ToscaFileOutputServiceCsarImpl(new AsdPackageHelper(new ManifestUtils()))).getArtifactsFolderName() + "/" + translateTo.getHeatFileName());
424         serviceInstanceGroupDefinition.setProperties(groupProperties);
425         serviceInstanceGroupDefinition.setMembers(new ArrayList<>());
426         String heatStackGroupKey = translateTo.getTranslatedId() + "_group";
427         DataModelUtil.addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupKey, serviceInstanceGroupDefinition);
428         return heatStackGroupKey;
429     }
430
431     private void setNestedServiceTemplateGeneralDetails(TranslateTo translateTo, ServiceTemplate nestedSubstitutionServiceTemplate) {
432         Map<String, String> nestedTemplateMetadata = new HashMap<>();
433         String nestedTemplateName = new ContrailTranslationHelper()
434             .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(), translateTo.getResourceId());
435         nestedTemplateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, nestedTemplateName);
436         nestedSubstitutionServiceTemplate.setMetadata(nestedTemplateMetadata);
437         nestedSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
438         nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
439         List<Map<String, Import>> globalTypesImportList = GlobalTypesGenerator.getGlobalTypesImportList();
440         globalTypesImportList.addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
441         nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
442     }
443
444     private NodeTemplate createSubstitutedNodeTemplate(TranslateTo translateTo, Resource contrailServiceTemplateResource,
445                                                        String contrailServiceTemplateTranslatedId, int numberOfPorts) {
446         boolean isImportAddedToServiceTemplate = DataModelUtil
447             .isImportAddedToServiceTemplate(translateTo.getServiceTemplate().getImports(), Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
448         if (!isImportAddedToServiceTemplate) {
449             translateTo.getServiceTemplate().getImports().addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
450         }
451         NodeTemplate substitutesNodeTemplate = new NodeTemplate();
452         substitutesNodeTemplate.setType(contrailServiceTemplateTranslatedId);
453         List<String> directiveList = new ArrayList<>();
454         directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
455         substitutesNodeTemplate.setDirectives(directiveList);
456         substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
457             .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.getResourceId(),
458                 translateTo.getResource().getProperties(), substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
459                 translateTo.getHeatOrchestrationTemplate(), HeatResourcesTypes.CONTRAIL_SERVICE_INSTANCE.getHeatResource(), substitutesNodeTemplate,
460                 translateTo.getContext()));
461         substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
462             .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.getResourceId(),
463                 contrailServiceTemplateResource.getProperties(), substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
464                 translateTo.getHeatOrchestrationTemplate(), HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource(), substitutesNodeTemplate,
465                 translateTo.getContext()));
466         HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
467             .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
468                 HeatConstants.AVAILABILITY_ZONE_ENABLE_PROPERTY_NAME));
469         HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
470             .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
471                 HeatConstants.ORDERED_INTERFACES_PROPERTY_NAME));
472         Object sharedIpListPropertyValue = contrailServiceTemplateResource.getProperties().get(HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
473         String toscaSharedIpListPropertyName = HeatToToscaUtil
474             .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(), HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
475         Optional<List<Map<String, List>>> sharedIpTranslatedSplitFun = new ContrailTranslationHelper()
476             .translateFnSplitFunction(sharedIpListPropertyValue, numberOfPorts, true);
477         if (sharedIpTranslatedSplitFun.isPresent()) {
478             substitutesNodeTemplate.getProperties().put(toscaSharedIpListPropertyName, sharedIpTranslatedSplitFun.get());
479         } else {
480             HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaSharedIpListPropertyName);
481         }
482         Object staticRouteListPropertyValue = contrailServiceTemplateResource.getProperties().get(HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
483         String toscaStaticRoutesListPropertyName = HeatToToscaUtil
484             .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
485                 HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
486         Optional<List<Map<String, List>>> staticRouteTranslatedSplitFun = new ContrailTranslationHelper()
487             .translateFnSplitFunction(staticRouteListPropertyValue, numberOfPorts, true);
488         if (staticRouteTranslatedSplitFun.isPresent()) {
489             substitutesNodeTemplate.getProperties().put(toscaStaticRoutesListPropertyName, staticRouteTranslatedSplitFun.get());
490         } else {
491             HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaStaticRoutesListPropertyName);
492         }
493         Object serviceInterfaceTypeListPropertyValue = contrailServiceTemplateResource.getProperties()
494             .get(HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
495         String toscaServiceInterfaceTypeListPropertyName = HeatToToscaUtil
496             .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
497                 HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
498         Optional<List<Map<String, List>>> serviceInterfaceTypeTranslatedSplitFun = new ContrailTranslationHelper()
499             .translateFnSplitFunction(serviceInterfaceTypeListPropertyValue, numberOfPorts, false);
500         serviceInterfaceTypeTranslatedSplitFun.ifPresent(
501             translatedSplitFun -> substitutesNodeTemplate.getProperties().put(toscaServiceInterfaceTypeListPropertyName, translatedSplitFun));
502         String substitutedNodeTemplateId = translateTo.getTranslatedId();
503         DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), substitutedNodeTemplateId, substitutesNodeTemplate);
504         return substitutesNodeTemplate;
505     }
506
507     private void addNetworkLinkRequirements(NodeType nodeType, int numberOfPorts) {
508         if (nodeType.getRequirements() == null) {
509             List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
510             for (int i = 0; i < numberOfPorts; i++) {
511                 Map<String, RequirementDefinition> requirementDefinitionMap = new HashMap<>();
512                 requirementDefinitionMap.put(ToscaConstants.LINK_REQUIREMENT_ID + "_port_" + i, DataModelUtil
513                     .createRequirement(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE, ToscaNodeType.NATIVE_ROOT,
514                         ToscaRelationshipType.NATIVE_NETWORK_LINK_TO, null));
515                 requirementList.add(requirementDefinitionMap);
516             }
517             if (numberOfPorts > 0) {
518                 nodeType.setRequirements(requirementList);
519             }
520         }
521     }
522
523     private int getServiceInstanceNumberOfPorts(Resource serviceInstanceResource) {
524         int numberOfPorts;
525         Object interfaceTypeProperty = serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
526         if (interfaceTypeProperty == null) {
527             numberOfPorts = 0;
528         } else if (interfaceTypeProperty instanceof List) {
529             numberOfPorts = ((List) interfaceTypeProperty).size();
530         } else if (interfaceTypeProperty instanceof Map) {
531             numberOfPorts = 1;
532         } else {
533             numberOfPorts = 0;
534         }
535         return numberOfPorts;
536     }
537
538     private AttachedResourceId getServiceTemplateAttachedId(TranslateTo translateTo, Resource serviceInstanceResource) {
539         Object serviceTemplateProperty = serviceInstanceResource.getProperties().get("service_template");
540         Optional<AttachedResourceId> serviceTemplateId = HeatToToscaUtil
541             .extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
542                 serviceTemplateProperty);
543         if (serviceTemplateId.isPresent()) {
544             return serviceTemplateId.get();
545         } else {
546             throw new CoreException(new MissingMandatoryPropertyErrorBuilder("service_template").build());
547         }
548     }
549 }