[SDC-139] Check the validity of input parameter
[sdc/sdc-tosca.git] / src / main / java / org / openecomp / sdc / tosca / parser / impl / SdcCsarHelperImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * sdc-distribution-client
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.tosca.parser.impl;
22
23 import java.util.*;
24 import java.util.Map.Entry;
25 import java.util.stream.Collectors;
26
27 import org.apache.commons.lang3.tuple.ImmutablePair;
28 import org.apache.commons.lang3.tuple.Pair;
29 import org.openecomp.sdc.tosca.parser.api.ISdcCsarHelper;
30 import org.openecomp.sdc.tosca.parser.utils.GeneralUtility;
31 import org.openecomp.sdc.tosca.parser.utils.SdcToscaUtility;
32 import org.openecomp.sdc.toscaparser.api.Group;
33 import org.openecomp.sdc.toscaparser.api.NodeTemplate;
34 import org.openecomp.sdc.toscaparser.api.Property;
35 import org.openecomp.sdc.toscaparser.api.SubstitutionMappings;
36 import org.openecomp.sdc.toscaparser.api.TopologyTemplate;
37 import org.openecomp.sdc.toscaparser.api.ToscaTemplate;
38 import org.openecomp.sdc.toscaparser.api.elements.Metadata;
39 import org.openecomp.sdc.toscaparser.api.elements.NodeType;
40 import org.openecomp.sdc.toscaparser.api.functions.Function;
41 import org.openecomp.sdc.toscaparser.api.parameters.Input;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import static org.openecomp.sdc.tosca.parser.impl.SdcPropertyNames.PROPERTY_NAME_CUSTOMIZATIONUUID;
46
47 public class SdcCsarHelperImpl implements ISdcCsarHelper {
48
49     private static final String PATH_DELIMITER = "#";
50     private static final String CUSTOMIZATION_UUID = "customizationUUID";
51     private ToscaTemplate toscaTemplate;
52     private static Logger log = LoggerFactory.getLogger(SdcCsarHelperImpl.class.getName());
53
54     public SdcCsarHelperImpl(ToscaTemplate toscaTemplate) {
55         this.toscaTemplate = toscaTemplate;
56     }
57
58     @Override
59     //Sunny flow  - covered with UT, flat and nested
60     public String getNodeTemplatePropertyLeafValue(NodeTemplate nodeTemplate, String leafValuePath) {
61         if (nodeTemplate == null) {
62             log.error("getNodeTemplatePropertyLeafValue - nodeTemplate is null");
63             return null;
64         }
65         if (GeneralUtility.isEmptyString(leafValuePath)) {
66             log.error("getNodeTemplatePropertyLeafValue - leafValuePath is null or empty");
67             return null;
68         }
69         String[] split = getSplittedPath(leafValuePath);
70         LinkedHashMap<String, Property> properties = nodeTemplate.getProperties();
71         Object property = processProperties(split, properties);
72         return property == null || property instanceof Function ? null : String.valueOf(property);
73     }
74
75     @Override
76     public Object getNodeTemplatePropertyAsObject(NodeTemplate nodeTemplate, String leafValuePath) {
77         if (nodeTemplate == null) {
78             log.error("getNodeTemplatePropertyAsObject - nodeTemplate is null");
79             return null;
80         }
81         if (GeneralUtility.isEmptyString(leafValuePath)) {
82             log.error("getNodeTemplatePropertyAsObject - leafValuePath is null or empty");
83             return null;
84         }
85         String[] split = getSplittedPath(leafValuePath);
86         LinkedHashMap<String, Property> properties = nodeTemplate.getProperties();
87         return processProperties(split, properties);
88     }
89     
90     public Map<String, Map<String, Object>> getCpPropertiesFromVfcAsObject(NodeTemplate vfc) {
91         if (vfc == null) {
92             log.error("getCpPropertiesFromVfc - vfc is null");
93             return new HashMap<>();
94         }
95
96         String presetProperty = "_ip_requirements";
97         Map<String, Map<String, Object>> cps = new HashMap<>();
98
99         Map<String, Property> props = vfc.getProperties();
100         if (props != null) {
101             // find all port names by pre-set property (ip_requirements)
102             for (Map.Entry<String, Property> entry : props.entrySet()) {
103                 if (entry.getKey().endsWith(presetProperty)) {
104                     String portName = entry.getKey().replaceAll(presetProperty, "");
105                     cps.put(portName, new HashMap<>());
106                 }
107             }
108
109             if (cps.size() > 0) {
110                 // ports found - find all their properties
111                 for (String portName : cps.keySet()) {
112                     for (Map.Entry<String, Property> property: props.entrySet()) {
113                         if (property.getKey().startsWith(portName)) {
114                             String portProperty = property.getKey().replaceFirst(portName + "_", "");
115                             if (property.getValue() != null) {
116                                 cps.get(portName).put(portProperty, property.getValue().getValue());
117                             }
118                         }
119                     }
120                 }
121             }
122         }
123
124         return cps;
125     }
126
127     public Map<String, Map<String, Object>> getCpPropertiesFromVfc(NodeTemplate vfc) {
128
129         if (vfc == null) {
130             log.error("getCpPropertiesFromVfc - vfc is null");
131             return new HashMap<>();
132         }
133
134         String presetProperty = "_ip_requirements";
135         Map<String, Map<String, Object>> cps = new HashMap<>();
136
137         Map<String, Property> props = vfc.getProperties();
138         if (props != null) {
139             // find all port names by pre-set property (ip_requirements)
140             for (Map.Entry<String, Property> entry : props.entrySet()) {
141                 if (entry.getKey().endsWith(presetProperty)) {
142                     String portName = entry.getKey().replaceAll(presetProperty, "");
143                     cps.put(portName, new HashMap<>());
144                 }
145             }
146
147             if (cps.size() > 0) {
148                 // ports found - find all their properties
149                 for (String portName : cps.keySet()) {
150                     for (Map.Entry<String, Property> property: props.entrySet()) {
151                         if (property.getKey().startsWith(portName)) {
152                             Map<String, Object> portPaths = new HashMap<>();
153                             String portProperty = property.getKey().replaceFirst(portName + "_", "");
154                             buildPathMappedToValue(portProperty, property.getValue().getValue(), portPaths);
155
156                             cps.get(portName).putAll(portPaths);
157                         }
158                     }
159                 }
160             }
161         }
162
163         return cps;
164     }
165
166     @SuppressWarnings("unchecked")
167     private void buildPathMappedToValue(String path, Object property, Map<String, Object> pathsMap) {
168         if (property instanceof Map) {
169             for (Map.Entry<String, Object> item : ((Map<String, Object>) property).entrySet()) {
170                 if (item.getValue() instanceof Map || item.getValue() instanceof List) {
171                     buildPathMappedToValue(path + PATH_DELIMITER + item.getKey(), item.getValue(), pathsMap);
172                 } else {
173                     pathsMap.put(path + PATH_DELIMITER + item.getKey(), item.getValue());
174                 }
175             }
176         } else if (property instanceof List) {
177             for (Object item: (List<Object>)property) {
178                 buildPathMappedToValue(path, item, pathsMap);
179             }
180         } else {
181             pathsMap.put(path, property);
182         }
183
184     }
185
186     @Override
187     //Sunny flow - covered with UT
188     public List<NodeTemplate> getServiceVlList() {
189         List<NodeTemplate> serviceVlList = getNodeTemplateBySdcType(toscaTemplate.getTopologyTemplate(), SdcTypes.VL);
190         return serviceVlList;
191     }
192
193     @Override
194     //Sunny flow - covered with UT
195     public List<NodeTemplate> getServiceVfList() {
196         List<NodeTemplate> serviceVfList = getNodeTemplateBySdcType(toscaTemplate.getTopologyTemplate(), SdcTypes.VF);
197         return serviceVfList;
198     }
199
200     @Override
201     //Sunny flow - covered with UT
202     public String getMetadataPropertyValue(Metadata metadata, String metadataPropertyName) {
203         if (GeneralUtility.isEmptyString(metadataPropertyName)) {
204             log.error("getMetadataPropertyValue - the metadataPropertyName is null or empty");
205             return null;
206         }
207         if (metadata == null) {
208             log.error("getMetadataPropertyValue - the metadata is null");
209             return null;
210         }
211         String metadataPropertyValue = metadata.getValue(metadataPropertyName);
212         return metadataPropertyValue;
213     }
214
215
216     @Override
217     //Sunny flow - covered with UT
218     public List<NodeTemplate> getServiceNodeTemplatesByType(String nodeType) {
219         if (GeneralUtility.isEmptyString(nodeType)) {
220             log.error("getServiceNodeTemplatesByType - nodeType - is null or empty");
221             return new ArrayList<>();
222         }
223
224         List<NodeTemplate> res = new ArrayList<>();
225         List<NodeTemplate> nodeTemplates = toscaTemplate.getNodeTemplates();
226         for (NodeTemplate nodeTemplate : nodeTemplates) {
227             if (nodeType.equals(nodeTemplate.getTypeDefinition().getType())) {
228                 res.add(nodeTemplate);
229             }
230         }
231
232         return res;
233     }
234
235
236     @Override
237     public List<NodeTemplate> getServiceNodeTemplates() {
238         List<NodeTemplate> nodeTemplates = toscaTemplate.getNodeTemplates();
239         return nodeTemplates;
240     }
241
242     @Override
243     //Sunny flow - covered with UT
244     public List<NodeTemplate> getVfcListByVf(String vfCustomizationId) {
245         if (GeneralUtility.isEmptyString(vfCustomizationId)) {
246             log.error("getVfcListByVf - vfCustomizationId - is null or empty");
247             return new ArrayList<>();
248         }
249
250         List<NodeTemplate> serviceVfList = getServiceVfList();
251         NodeTemplate vfInstance = getNodeTemplateByCustomizationUuid(serviceVfList, vfCustomizationId);
252         List<NodeTemplate> vfcs = getNodeTemplateBySdcType(vfInstance, SdcTypes.VFC);
253         vfcs.addAll(getNodeTemplateBySdcType(vfInstance, SdcTypes.CVFC));
254
255         return vfcs;
256     }
257
258     @Override
259     //Sunny flow - covered with UT
260     public List<Group> getVfModulesByVf(String vfCustomizationUuid) {
261         List<NodeTemplate> serviceVfList = getServiceVfList();
262         NodeTemplate nodeTemplateByCustomizationUuid = getNodeTemplateByCustomizationUuid(serviceVfList, vfCustomizationUuid);
263         if (nodeTemplateByCustomizationUuid != null) {
264             /*SubstitutionMappings substitutionMappings = nodeTemplateByCustomizationUuid.getSubstitutionMappings();
265                         if (substitutionMappings != null){
266                                 List<Group> groups = substitutionMappings.getGroups();
267                                 if (groups != null){
268                                         List<Group> collect = groups.stream().filter(x -> "org.openecomp.groups.VfModule".equals(x.getTypeDefinition().getType())).collect(Collectors.toList());
269                                         log.debug("getVfModulesByVf - VfModules are {}", collect);
270                                         return collect;
271                                 }
272                         }*/
273             String name = nodeTemplateByCustomizationUuid.getName();
274             String normaliseComponentInstanceName = SdcToscaUtility.normaliseComponentInstanceName(name);
275             List<Group> serviceLevelGroups = toscaTemplate.getTopologyTemplate().getGroups();
276             log.debug("getVfModulesByVf - VF node template name {}, normalized name {}. Searching groups on service level starting with VF normalized name...", name, normaliseComponentInstanceName);
277             if (serviceLevelGroups != null) {
278                 List<Group> collect = serviceLevelGroups
279                         .stream()
280                         .filter(x -> "org.openecomp.groups.VfModule".equals(x.getTypeDefinition().getType()) && x.getName().startsWith(normaliseComponentInstanceName))
281                         .collect(Collectors.toList());
282                 return collect;
283             }
284         }
285         return new ArrayList<>();
286     }
287
288     @Override
289     //Sunny flow - covered with UT
290     public String getServiceInputLeafValueOfDefault(String inputLeafValuePath) {
291         if (GeneralUtility.isEmptyString(inputLeafValuePath)) {
292             log.error("getServiceInputLeafValueOfDefault - inputLeafValuePath is null or empty");
293             return null;
294         }
295
296         String[] split = getSplittedPath(inputLeafValuePath);
297         if (split.length < 2 || !split[1].equals("default")) {
298             log.error("getServiceInputLeafValue - inputLeafValuePath should be of format <input name>#default[optionally #<rest of path>] ");
299             return null;
300         }
301
302         List<Input> inputs = toscaTemplate.getInputs();
303         if (inputs != null) {
304             Optional<Input> findFirst = inputs.stream().filter(x -> x.getName().equals(split[0])).findFirst();
305             if (findFirst.isPresent()) {
306                 Input input = findFirst.get();
307                 Object current = input.getDefault();
308                 Object property = iterateProcessPath(2, current, split);
309                 return property == null || property instanceof Function? null : String.valueOf(property);
310             }
311         }
312         log.error("getServiceInputLeafValue - value not found");
313         return null;
314     }
315
316     @Override
317     public Object getServiceInputLeafValueOfDefaultAsObject(String inputLeafValuePath) {
318         if (GeneralUtility.isEmptyString(inputLeafValuePath)) {
319             log.error("getServiceInputLeafValueOfDefaultAsObject - inputLeafValuePath is null or empty");
320             return null;
321         }
322
323         String[] split = getSplittedPath(inputLeafValuePath);
324         if (split.length < 2 || !split[1].equals("default")) {
325             log.error("getServiceInputLeafValueOfDefaultAsObject - inputLeafValuePath should be of format <input name>#default[optionally #<rest of path>] ");
326             return null;
327         }
328
329         List<Input> inputs = toscaTemplate.getInputs();
330         if (inputs != null) {
331             Optional<Input> findFirst = inputs.stream().filter(x -> x.getName().equals(split[0])).findFirst();
332             if (findFirst.isPresent()) {
333                 Input input = findFirst.get();
334                 Object current = input.getDefault();
335                 return iterateProcessPath(2, current, split);
336             }
337         }
338         log.error("getServiceInputLeafValueOfDefaultAsObject - value not found");
339         return null;
340     }
341
342     @SuppressWarnings({ "unchecked", "rawtypes" })
343     private Object iterateProcessPath(Integer index, Object current, String[] split) {
344         if (current == null) {
345             log.error("iterateProcessPath - this input has no default");
346             return null;
347         }
348         if (split.length > index) {
349             for (int i = index; i < split.length; i++) {
350                 if (current instanceof Map) {
351                     current = ((Map<String, Object>) current).get(split[i]);
352                 } else if (current instanceof List) {
353                     current = ((List) current).get(0);
354                     i--;
355                 }
356                  else {
357                         log.error("iterateProcessPath - found an unexpected leaf where expected to find a complex type");
358                         return null;
359                 }
360             }
361         }
362         if (current != null) {
363             return current;
364         }
365         log.error("iterateProcessPath - Path not Found");
366         return null;
367     }
368
369     private String[] getSplittedPath(String inputLeafValuePath) {
370         return inputLeafValuePath.split(PATH_DELIMITER);
371     }
372
373
374     @Override
375     //Sunny flow - covered with UT
376     public String getServiceSubstitutionMappingsTypeName() {
377         SubstitutionMappings substitutionMappings = toscaTemplate.getTopologyTemplate().getSubstitutionMappings();
378         if (substitutionMappings == null) {
379             log.debug("getServiceSubstitutionMappingsTypeName - No Substitution Mappings defined");
380             return null;
381         }
382
383         NodeType nodeType = substitutionMappings.getNodeDefinition();
384         if (nodeType == null) {
385             log.debug("getServiceSubstitutionMappingsTypeName - No Substitution Mappings node defined");
386             return null;
387         }
388
389         return nodeType.getType();
390     }
391
392     @Override
393     //Sunny flow - covered with UT
394     public Metadata getServiceMetadata() {
395         return toscaTemplate.getMetaData();
396     }
397
398     @Override
399     //Sunny flow - covered with UT
400     public Map<String, Object> getServiceMetadataProperties() {
401         if (toscaTemplate.getMetaData()==null){
402             return null;
403         }
404         return toscaTemplate.getMetaData().getPropertyMap();
405     }
406
407     @Override
408     //Sunny flow - covered with UT
409     public List<Input> getServiceInputs() {
410         return toscaTemplate.getInputs();
411     }
412
413     @Override
414     //Sunny flow - covered with UT
415     public String getGroupPropertyLeafValue(Group group, String leafValuePath) {
416         if (group == null) {
417             log.error("getGroupPropertyLeafValue - group is null");
418             return null;
419         }
420
421         if (GeneralUtility.isEmptyString(leafValuePath)) {
422             log.error("getGroupPropertyLeafValue - leafValuePath is null or empty");
423             return null;
424         }
425
426         String[] split = getSplittedPath(leafValuePath);
427         LinkedHashMap<String, Property> properties = group.getProperties();
428         Object property = processProperties(split, properties);
429         return property == null || property instanceof Function? null : String.valueOf(property);
430     }
431
432     @Override
433     public Object getGroupPropertyAsObject(Group group, String leafValuePath) {
434         if (group == null) {
435             log.error("getGroupPropertyAsObject - group is null");
436             return null;
437         }
438
439         if (GeneralUtility.isEmptyString(leafValuePath)) {
440             log.error("getGroupPropertyAsObject - leafValuePath is null or empty");
441             return null;
442         }
443
444         String[] split = getSplittedPath(leafValuePath);
445         LinkedHashMap<String, Property> properties = group.getProperties();
446         return processProperties(split, properties);
447     }
448
449     @Override
450     //Sunny flow - covered with UT
451     public List<NodeTemplate> getCpListByVf(String vfCustomizationId) {
452         List<NodeTemplate> cpList = new ArrayList<>();
453         if (GeneralUtility.isEmptyString(vfCustomizationId)) {
454             log.error("getCpListByVf vfCustomizationId string is empty");
455             return cpList;
456         }
457
458         List<NodeTemplate> serviceVfList = getServiceVfList();
459         if (serviceVfList == null || serviceVfList.size() == 0) {
460             log.error("getCpListByVf Vfs not exist for vfCustomizationId {}", vfCustomizationId);
461             return cpList;
462         }
463         NodeTemplate vfInstance = getNodeTemplateByCustomizationUuid(serviceVfList, vfCustomizationId);
464         if (vfInstance == null) {
465             log.debug("getCpListByVf vf list is null");
466             return cpList;
467         }
468         cpList = getNodeTemplateBySdcType(vfInstance, SdcTypes.CP);
469         if (cpList == null || cpList.size() == 0)
470             log.debug("getCpListByVf cps not exist for vfCustomizationId {}", vfCustomizationId);
471         return cpList;
472     }
473
474     @Override
475     //Sunny flow - covered with UT
476     public List<NodeTemplate> getMembersOfVfModule(NodeTemplate vf, Group serviceLevelVfModule) {
477         if (vf == null) {
478             log.error("getMembersOfVfModule - vf is null");
479             return new ArrayList<>();
480         }
481
482         if (serviceLevelVfModule == null || serviceLevelVfModule.getMetadata() == null || serviceLevelVfModule.getMetadata().getValue(SdcPropertyNames.PROPERTY_NAME_VFMODULEMODELINVARIANTUUID) == null) {
483             log.error("getMembersOfVfModule - vfModule or its metadata is null. Cannot match a VF group based on invariantUuid from missing metadata.");
484             return new ArrayList<>();
485         }
486
487
488         SubstitutionMappings substitutionMappings = vf.getSubMappingToscaTemplate();
489         if (substitutionMappings != null) {
490             List<Group> groups = substitutionMappings.getGroups();
491             if (groups != null) {
492                 Optional<Group> findFirst = groups
493                         .stream()
494                         .filter(x -> (x.getMetadata() != null && serviceLevelVfModule.getMetadata().getValue(SdcPropertyNames.PROPERTY_NAME_VFMODULEMODELINVARIANTUUID).equals(x.getMetadata().getValue(SdcPropertyNames.PROPERTY_NAME_VFMODULEMODELINVARIANTUUID)))).findFirst();
495                 if (findFirst.isPresent()) {
496                     List<String> members = findFirst.get().getMembers();
497                     if (members != null) {
498                         List<NodeTemplate> collect = substitutionMappings.getNodeTemplates().stream().filter(x -> members.contains(x.getName())).collect(Collectors.toList());
499                         return collect;
500                     }
501                 }
502             }
503         }
504         return new ArrayList<>();
505     }
506
507     @Override
508     //Sunny flow - covered with UT
509     @SuppressWarnings("unchecked")
510     public List<Pair<NodeTemplate, NodeTemplate>> getNodeTemplatePairsByReqName(
511             List<NodeTemplate> listOfReqNodeTemplates, List<NodeTemplate> listOfCapNodeTemplates, String reqName) {
512         if (listOfReqNodeTemplates == null || listOfCapNodeTemplates == null || reqName == null) {
513             //TODO error message
514             return new ArrayList<>();
515         }
516
517         List<Pair<NodeTemplate, NodeTemplate>> pairsList = new ArrayList<>();
518
519         if (listOfReqNodeTemplates != null) {
520             for (NodeTemplate reqNodeTemplate : listOfReqNodeTemplates) {
521                 List<Object> requirements = reqNodeTemplate.getRequirements();
522                 for (Object reqEntry : requirements) {
523                     LinkedHashMap<String, Object> reqEntryHash = (LinkedHashMap<String, Object>) reqEntry;
524                     Map<String, Object> reqEntryMap = (Map<String, Object>) reqEntryHash.get(reqName);
525                     if (reqEntryMap != null) {
526                         Object node = reqEntryMap.get("node");
527                         if (node != null) {
528                             String nodeString = (String) node;
529                             Optional<NodeTemplate> findFirst = listOfCapNodeTemplates.stream().filter(x -> x.getName().equals(nodeString)).findFirst();
530                             if (findFirst.isPresent()) {
531                                 pairsList.add(new ImmutablePair<NodeTemplate, NodeTemplate>(reqNodeTemplate, findFirst.get()));
532                             }
533                         }
534                     }
535                 }
536             }
537         }
538         return pairsList;
539     }
540
541     @Override
542     //Sunny flow - covered with UT
543     //TODO constant strings
544     public List<NodeTemplate> getAllottedResources() {
545         List<NodeTemplate> nodeTemplates = null;
546         nodeTemplates = toscaTemplate.getTopologyTemplate().getNodeTemplates();
547         if (nodeTemplates.isEmpty()) {
548             log.error("getAllottedResources nodeTemplates not exist");
549         }
550         nodeTemplates = nodeTemplates.stream().filter(
551                 x -> x.getMetaData() != null && x.getMetaData().getValue("category").equals("Allotted Resource"))
552                 .collect(Collectors.toList());
553         if (nodeTemplates.isEmpty()) {
554             log.debug("getAllottedResources -  allotted resources not exist");
555         } else {
556         }
557
558         return nodeTemplates;
559     }
560
561     @Override
562     //Sunny flow - covered with UT
563     public String getTypeOfNodeTemplate(NodeTemplate nodeTemplate) {
564         if (nodeTemplate == null) {
565
566             log.error("getTypeOfNodeTemplate nodeTemplate is null");
567             return null;
568         }
569         return nodeTemplate.getTypeDefinition().getType();
570     }
571
572         @Override
573         public String getConformanceLevel() {
574                 LinkedHashMap<String, Object> csarMeta = toscaTemplate.getMetaProperties("csar.meta");
575                 if (csarMeta == null){
576                         log.warn("No csar.meta file is found in CSAR - this file should hold the conformance level of the CSAR. This might be OK for older CSARs.");
577                         return null;
578                 }
579
580                 Object conformanceLevel = csarMeta.get("SDC-TOSCA-Definitions-Version");
581                 if (conformanceLevel != null){
582                         String confLevelStr = conformanceLevel.toString();
583                         log.debug("CSAR conformance level is {}", confLevelStr);
584                         return confLevelStr;
585                 } else {
586                         log.error("Invalid csar.meta file - no entry found for SDC-TOSCA-Definitions-Version key. This entry should hold the conformance level.");
587                         return null;
588                 }
589         }
590         
591         
592         @Override
593         public String getNodeTemplateCustomizationUuid(NodeTemplate nt) {
594                 String res = null;
595                 if (nt != null && nt.getMetaData() != null){
596                         res = nt.getMetaData().getValue(CUSTOMIZATION_UUID);
597                 } else {
598                         log.error("Node template or its metadata is null");
599                 }
600                 return res;
601         }
602
603     public List<NodeTemplate> getNodeTemplateBySdcType(NodeTemplate parentNodeTemplate, SdcTypes sdcType) {
604         return getNodeTemplateBySdcType(parentNodeTemplate, sdcType, false); 
605     }
606     
607     private List<NodeTemplate> getNodeTemplateBySdcType(NodeTemplate parentNodeTemplate, SdcTypes sdcType, boolean isVNF)  {
608         
609         if (parentNodeTemplate == null) {
610             log.error("getNodeTemplateBySdcType - nodeTemplate is null or empty");
611             return new ArrayList<>();
612         }
613
614         if (sdcType == null) {
615             log.error("getNodeTemplateBySdcType - sdcType is null or empty");
616             return new ArrayList<>();
617         }
618
619         SubstitutionMappings substitutionMappings = parentNodeTemplate.getSubMappingToscaTemplate();
620
621         if (substitutionMappings != null) {
622             List<NodeTemplate> nodeTemplates = substitutionMappings.getNodeTemplates();
623             if (nodeTemplates != null && nodeTemplates.size() > 0) {
624                 if (sdcType.equals(SdcTypes.VFC) && isVNF)  {
625                         return nodeTemplates.stream()
626                                 .filter(x -> (x.getMetaData() != null &&
627                                         sdcType.toString().equals(x.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE))) &&  isVNFType(x))
628                                 .collect(Collectors.toList());
629                 }
630                 else {
631                     return nodeTemplates.stream()
632                                 .filter(x -> (x.getMetaData() != null &&
633                                         sdcType.toString().equals(x.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE))) &&  !isVNFType(x))
634                                 .collect(Collectors.toList());
635                 }
636             }
637             else {
638                 log.debug("getNodeTemplateBySdcType - SubstitutionMappings' node Templates not exist");
639             }
640         } else
641             log.debug("getNodeTemplateBySdcType - SubstitutionMappings not exist");
642
643         return new ArrayList<>();
644     }
645
646     public Map<String, String> filterNodeTemplatePropertiesByValue(NodeTemplate nodeTemplate, FilterType filterType, String pattern) {
647         Map<String, String> filterMap = new HashMap<>();
648
649         if (nodeTemplate == null) {
650             log.error("filterNodeTemplatePropertiesByValue nodeTemplate is null");
651             return filterMap;
652         }
653
654         if (filterType == null) {
655             log.error("filterNodeTemplatePropertiesByValue filterType is null");
656             return filterMap;
657         }
658
659         if (GeneralUtility.isEmptyString(pattern)) {
660             log.error("filterNodeTemplatePropertiesByValue pattern string is empty");
661             return filterMap;
662         }
663
664         Map<String, Property> ntProperties = nodeTemplate.getProperties();
665
666         if (ntProperties != null && ntProperties.size() > 0) {
667
668             for (Property current : ntProperties.values()) {
669                 filterProperties(current.getValue(), current.getName(), filterType, pattern, filterMap);
670             }
671         }
672
673         log.trace("filterNodeTemplatePropertiesByValue - filterMap value: {}", filterMap);
674
675         return filterMap;
676     }
677     
678         public NodeTemplate getVnfConfig(String vfCustomizationUuid) {
679                 
680                 if (GeneralUtility.isEmptyString(vfCustomizationUuid)) {
681             log.error("getVnfConfig - vfCustomizationId - is null or empty");
682             return null;
683         }
684
685         List<NodeTemplate> serviceVfList = getServiceVfList();
686         NodeTemplate vfInstance = getNodeTemplateByCustomizationUuid(serviceVfList, vfCustomizationUuid);
687         NodeTemplate vnfConfig = getNodeTemplateBySdcType(vfInstance, SdcTypes.VFC, true).stream().findAny().orElse(null);
688                 return vnfConfig;
689         }
690
691     @Override
692     public boolean hasTopology(NodeTemplate nodeTemplate) {
693         if (nodeTemplate == null) {
694             log.error("hasTopology - nodeTemplate - is null");
695             return false;
696         }
697
698         if (nodeTemplate.getMetaData() != null) {
699             String type = nodeTemplate.getMetaData().getValue("type");
700             log.debug("hasTopology - node template {} is a {} type", nodeTemplate.getName(), type);
701             return SdcTypes.isComplex(SdcTypes.valueOf(type));
702         }
703
704         return false;
705     }
706
707     @Override
708     public List<NodeTemplate> getNodeTemplateChildren(NodeTemplate nodeTemplate) {
709         if (nodeTemplate == null) {
710             log.error("getNodeTemplateChildren - nodeTemplate - is null");
711             return new ArrayList<>();
712         }
713
714         SubstitutionMappings substitutionMappings = nodeTemplate.getSubMappingToscaTemplate();
715         if (substitutionMappings != null) {
716             List<NodeTemplate> nodeTemplates = substitutionMappings.getNodeTemplates();
717             if (nodeTemplates != null && nodeTemplates.size() > 0) {
718
719                 return nodeTemplates.stream()
720                         .filter(x -> !isVNFType(x))
721                         .collect(Collectors.toList());
722             }
723             else {
724                 log.debug("getNodeTemplateChildren - SubstitutionMappings' node Templates not exist");
725             }
726         } else
727             log.debug("getNodeTemplateChildren - SubstitutionMappings not exist");
728
729         return new ArrayList<>();
730     }
731
732     /************************************* helper functions ***********************************/
733     private boolean isVNFType(NodeTemplate nt) {
734         return nt.getType().endsWith("VnfConfiguration");
735     }
736
737     @SuppressWarnings("unchecked")
738     private Map<String, String> filterProperties(Object property, String path, FilterType filterType, String pattern, Map<String, String> filterMap) {
739
740         if (property instanceof Map) {
741             for (Map.Entry<String, Object> item: ((Map<String, Object>) property).entrySet()) {
742                 if (item.getKey().equals("get_input")) {
743                     String itemToStr = item.getKey() + ":" + item.getValue().toString();
744                     filterProperties(itemToStr, path, filterType, pattern, filterMap);
745                 } else {
746                     path += PATH_DELIMITER + item.getKey();
747                     filterProperties(item.getValue(), path, filterType, pattern, filterMap);
748                 }
749             }
750         } else if (property instanceof List) {
751             for (Object item: (List<Object>)property) {
752                 filterProperties(item, path, filterType, pattern, filterMap);
753             }
754         } else if (property instanceof Function) {
755             if (filterType.isMatch(property.toString(), pattern)) {
756                 filterMap.put(path, property.toString());
757             }
758         } else {
759             if (filterType.isMatch(property.toString(), pattern)) {
760                 filterMap.put(path, property.toString());
761             }
762         }
763
764         return filterMap;
765     }
766
767     public List<NodeTemplate> getServiceNodeTemplateBySdcType(SdcTypes sdcType) {
768         if (sdcType == null) {
769             log.error("getServiceNodeTemplateBySdcType - sdcType is null or empty");
770             return new ArrayList<>();
771         }
772
773         TopologyTemplate topologyTemplate = toscaTemplate.getTopologyTemplate();
774         return getNodeTemplateBySdcType(topologyTemplate, sdcType);
775     }
776  
777
778     /************************************* helper functions ***********************************/
779     private List<NodeTemplate> getNodeTemplateBySdcType(TopologyTemplate topologyTemplate, SdcTypes sdcType) {
780         if (sdcType == null) {
781             log.error("getNodeTemplateBySdcType - sdcType is null or empty");
782             return new ArrayList<>();
783         }
784
785         if (topologyTemplate == null) {
786             log.error("getNodeTemplateBySdcType - topologyTemplate is null");
787             return new ArrayList<>();
788         }
789
790         List<NodeTemplate> nodeTemplates = topologyTemplate.getNodeTemplates();
791
792         if (nodeTemplates != null && nodeTemplates.size() > 0)
793             return nodeTemplates.stream().filter(x -> (x.getMetaData() != null && sdcType.toString().equals(x.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE)))).collect(Collectors.toList());
794
795         log.debug("getNodeTemplateBySdcType - topologyTemplate's nodeTemplates not exist");
796         return new ArrayList<>();
797     }
798
799     //Assumed to be unique property for the list
800     private NodeTemplate getNodeTemplateByCustomizationUuid(List<NodeTemplate> nodeTemplates, String customizationId) {
801        if (customizationId != null) {
802             Optional<NodeTemplate> findFirst = nodeTemplates.stream().filter(x -> (x.getMetaData() != null && customizationId.equals(x.getMetaData().getValue(PROPERTY_NAME_CUSTOMIZATIONUUID)))).findFirst();
803             return findFirst.isPresent() ? findFirst.get() : null;
804         }
805         else {
806             log.error("getNodeTemplateByCustomizationUuid - customizationId is null");
807             return null;
808         }
809     }
810
811     private Object processProperties(String[] split, LinkedHashMap<String, Property> properties) {
812         Optional<Entry<String, Property>> findFirst = properties.entrySet().stream().filter(x -> x.getKey().equals(split[0])).findFirst();
813         if (findFirst.isPresent()) {
814             Property property = findFirst.get().getValue();
815             Object current = property.getValue();
816             return iterateProcessPath(1, current, split);
817         }
818         String propName = (split != null && split.length > 0 ? split[0] : null);
819         log.error("processProperties - property {} not found", propName);
820         return null;
821     }
822
823         
824
825     
826     
827 }