Fix checkstyle violations in sdc/jtosca
[sdc/sdc-tosca.git] / src / main / java / org / onap / sdc / toscaparser / api / TopologyTemplate.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 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.onap.sdc.toscaparser.api;
22
23 import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
24 import org.onap.sdc.toscaparser.api.elements.InterfacesDef;
25 import org.onap.sdc.toscaparser.api.elements.NodeType;
26 import org.onap.sdc.toscaparser.api.elements.RelationshipType;
27 import org.onap.sdc.toscaparser.api.functions.Function;
28 import org.onap.sdc.toscaparser.api.functions.GetAttribute;
29 import org.onap.sdc.toscaparser.api.functions.GetInput;
30 import org.onap.sdc.toscaparser.api.parameters.Input;
31 import org.onap.sdc.toscaparser.api.parameters.Output;
32 import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
33
34 import java.util.ArrayList;
35 import java.util.HashSet;
36 import java.util.LinkedHashMap;
37 import java.util.Map;
38
39 public class TopologyTemplate {
40
41     private static final String DESCRIPTION = "description";
42     private static final String INPUTS = "inputs";
43     private static final String NODE_TEMPLATES = "node_templates";
44     private static final String RELATIONSHIP_TEMPLATES = "relationship_templates";
45     private static final String OUTPUTS = "outputs";
46     private static final String GROUPS = "groups";
47     private static final String SUBSTITUTION_MAPPINGS = "substitution_mappings";
48     private static final String POLICIES = "policies";
49     private static final String METADATA = "metadata";
50
51     private static String[] SECTIONS = {
52             DESCRIPTION, INPUTS, NODE_TEMPLATES, RELATIONSHIP_TEMPLATES,
53             OUTPUTS, GROUPS, SUBSTITUTION_MAPPINGS, POLICIES, METADATA
54     };
55
56     private LinkedHashMap<String, Object> tpl;
57     LinkedHashMap<String, Object> metaData;
58     private ArrayList<Input> inputs;
59     private ArrayList<Output> outputs;
60     private ArrayList<RelationshipTemplate> relationshipTemplates;
61     private ArrayList<NodeTemplate> nodeTemplates;
62     private LinkedHashMap<String, Object> customDefs;
63     private LinkedHashMap<String, Object> relTypes;//TYPE
64     private NodeTemplate subMappedNodeTemplate;
65     private ArrayList<Group> groups;
66     private ArrayList<Policy> policies;
67     private LinkedHashMap<String, Object> parsedParams = null;//TYPE
68     private String description;
69     private ToscaGraph graph;
70     private SubstitutionMappings substitutionMappings;
71     private boolean resolveGetInput;
72
73     public TopologyTemplate(
74             LinkedHashMap<String, Object> _template,
75             LinkedHashMap<String, Object> _customDefs,
76             LinkedHashMap<String, Object> _relTypes,//TYPE
77             LinkedHashMap<String, Object> _parsedParams,
78             NodeTemplate _subMappedNodeTemplate,
79             boolean _resolveGetInput) {
80
81         tpl = _template;
82         if (tpl != null) {
83             subMappedNodeTemplate = _subMappedNodeTemplate;
84             metaData = _metaData();
85             customDefs = _customDefs;
86             relTypes = _relTypes;
87             parsedParams = _parsedParams;
88             resolveGetInput = _resolveGetInput;
89             _validateField();
90             description = _tplDescription();
91             inputs = _inputs();
92             relationshipTemplates = _relationshipTemplates();
93             //todo: pass subMappedNodeTemplate to ET constractor
94             nodeTemplates = _nodeTemplates();
95             outputs = _outputs();
96             if (nodeTemplates != null) {
97                 graph = new ToscaGraph(nodeTemplates);
98             }
99             groups = _groups();
100             policies = _policies();
101             _processIntrinsicFunctions();
102             substitutionMappings = _substitutionMappings();
103         }
104     }
105
106     @SuppressWarnings("unchecked")
107     private ArrayList<Input> _inputs() {
108         ArrayList<Input> alInputs = new ArrayList<>();
109         for (String name : _tplInputs().keySet()) {
110             Object attrs = _tplInputs().get(name);
111             Input input = new Input(name, (LinkedHashMap<String, Object>) attrs, customDefs);
112             if (parsedParams != null && parsedParams.get(name) != null) {
113                 input.validate(parsedParams.get(name));
114             } else {
115                 Object _default = input.getDefault();
116                 if (_default != null) {
117                     input.validate(_default);
118                 }
119             }
120             if ((parsedParams != null && parsedParams.get(input.getName()) == null || parsedParams == null)
121                     && input.isRequired() && input.getDefault() == null) {
122                 System.out.format("Log warning: The required parameter \"%s\" is not provided\n", input.getName());
123             }
124             alInputs.add(input);
125         }
126         return alInputs;
127
128     }
129
130     private LinkedHashMap<String, Object> _metaData() {
131         if (tpl.get(METADATA) != null) {
132             return (LinkedHashMap<String, Object>) tpl.get(METADATA);
133         } else {
134             return new LinkedHashMap<String, Object>();
135         }
136
137     }
138
139     private ArrayList<NodeTemplate> _nodeTemplates() {
140         ArrayList<NodeTemplate> alNodeTemplates = new ArrayList<>();
141         LinkedHashMap<String, Object> tpls = _tplNodeTemplates();
142         if (tpls != null) {
143             for (String name : tpls.keySet()) {
144                 NodeTemplate tpl = new NodeTemplate(name,
145                         tpls,
146                         customDefs,
147                         relationshipTemplates,
148                         relTypes,
149                         subMappedNodeTemplate);
150                 if (tpl.getTypeDefinition() != null) {
151                     boolean b = NodeType.TOSCA_DEF.get(tpl.getType()) != null;
152                     if (b || (tpl.getCustomDef() != null && !tpl.getCustomDef().isEmpty())) {
153                         tpl.validate();
154                         alNodeTemplates.add(tpl);
155                     }
156                 }
157             }
158         }
159         return alNodeTemplates;
160     }
161
162     @SuppressWarnings("unchecked")
163     private ArrayList<RelationshipTemplate> _relationshipTemplates() {
164         ArrayList<RelationshipTemplate> alRelationshipTemplates = new ArrayList<>();
165         LinkedHashMap<String, Object> tpls = _tplRelationshipTemplates();
166         if (tpls != null) {
167             for (String name : tpls.keySet()) {
168                 RelationshipTemplate tpl = new RelationshipTemplate(
169                         (LinkedHashMap<String, Object>) tpls.get(name), name, customDefs, null, null, subMappedNodeTemplate);
170
171                 alRelationshipTemplates.add(tpl);
172             }
173         }
174         return alRelationshipTemplates;
175     }
176
177     private ArrayList<Output> _outputs() {
178         ArrayList<Output> alOutputs = new ArrayList<>();
179         for (Map.Entry<String, Object> me : _tplOutputs().entrySet()) {
180             String oname = me.getKey();
181             LinkedHashMap<String, Object> oattrs = (LinkedHashMap<String, Object>) me.getValue();
182             Output o = new Output(oname, oattrs);
183             o.validate();
184             alOutputs.add(o);
185         }
186         return alOutputs;
187     }
188
189     private SubstitutionMappings _substitutionMappings() {
190         LinkedHashMap<String, Object> tplSubstitutionMapping = (LinkedHashMap<String, Object>) _tplSubstitutionMappings();
191
192         //*** the commenting-out below and the weaker condition are in the Python source
193         // #if tpl_substitution_mapping and self.sub_mapped_node_template:
194         if (tplSubstitutionMapping != null && tplSubstitutionMapping.size() > 0) {
195             return new SubstitutionMappings(tplSubstitutionMapping,
196                     nodeTemplates,
197                     inputs,
198                     outputs,
199                     groups,
200                     subMappedNodeTemplate,
201                     customDefs);
202         }
203         return null;
204
205     }
206
207     @SuppressWarnings("unchecked")
208     private ArrayList<Policy> _policies() {
209         ArrayList<Policy> alPolicies = new ArrayList<>();
210         for (Map.Entry<String, Object> me : _tplPolicies().entrySet()) {
211             String policyName = me.getKey();
212             LinkedHashMap<String, Object> policyTpl = (LinkedHashMap<String, Object>) me.getValue();
213             ArrayList<String> targetList = (ArrayList<String>) policyTpl.get("targets");
214             ArrayList<NodeTemplate> targetNodes = new ArrayList<>();
215             ArrayList<Object> targetObjects = new ArrayList<>();
216             ArrayList<Group> targetGroups = new ArrayList<>();
217             String targetsType = "groups";
218             if (targetList != null && targetList.size() >= 1) {
219                 targetGroups = _getPolicyGroups(targetList);
220                 if (targetGroups == null || targetGroups.isEmpty()) {
221                     targetsType = "node_templates";
222                     targetNodes = _getGroupMembers(targetList);
223                     for (NodeTemplate nt : targetNodes) {
224                         targetObjects.add(nt);
225                     }
226                 } else {
227                     for (Group gr : targetGroups) {
228                         targetObjects.add(gr);
229                     }
230                 }
231             }
232             Policy policyObj = new Policy(policyName,
233                     policyTpl,
234                     targetObjects,
235                     targetsType,
236                     customDefs,
237                     subMappedNodeTemplate);
238             alPolicies.add(policyObj);
239         }
240         return alPolicies;
241     }
242
243     private ArrayList<Group> _groups() {
244         ArrayList<Group> groups = new ArrayList<>();
245         ArrayList<NodeTemplate> memberNodes = null;
246         for (Map.Entry<String, Object> me : _tplGroups().entrySet()) {
247             String groupName = me.getKey();
248             LinkedHashMap<String, Object> groupTpl = (LinkedHashMap<String, Object>) me.getValue();
249             ArrayList<String> memberNames = (ArrayList<String>) groupTpl.get("members");
250             if (memberNames != null) {
251                 DataEntity.validateDatatype("list", memberNames, null, null, null);
252                 if (memberNames.size() < 1 ||
253                         (new HashSet<String>(memberNames)).size() != memberNames.size()) {
254                     ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE005", String.format(
255                             "InvalidGroupTargetException: Member nodes \"%s\" should be >= 1 and not repeated",
256                             memberNames.toString())));
257                 } else {
258                     memberNodes = _getGroupMembers(memberNames);
259                 }
260             }
261             Group group = new Group(groupName,
262                     groupTpl,
263                     memberNodes,
264                     customDefs, subMappedNodeTemplate);
265             groups.add(group);
266         }
267         return groups;
268     }
269
270     private ArrayList<NodeTemplate> _getGroupMembers(ArrayList<String> memberNames) {
271         ArrayList<NodeTemplate> memberNodes = new ArrayList<>();
272         _validateGroupMembers(memberNames);
273         for (String member : memberNames) {
274             for (NodeTemplate node : nodeTemplates) {
275                 if (member.equals(node.getName())) {
276                     memberNodes.add(node);
277                 }
278             }
279         }
280         return memberNodes;
281     }
282
283     private ArrayList<Group> _getPolicyGroups(ArrayList<String> memberNames) {
284         ArrayList<Group> memberGroups = new ArrayList<>();
285         for (String member : memberNames) {
286             for (Group group : groups) {
287                 if (member.equals(group.getName())) {
288                     memberGroups.add(group);
289                 }
290             }
291         }
292         return memberGroups;
293     }
294
295     private void _validateGroupMembers(ArrayList<String> members) {
296         ArrayList<String> nodeNames = new ArrayList<>();
297         for (NodeTemplate node : nodeTemplates) {
298             nodeNames.add(node.getName());
299         }
300         for (String member : members) {
301             if (!nodeNames.contains(member)) {
302                 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE239", String.format(
303                         "InvalidGroupTargetException: Target member \"%s\" is not found in \"nodeTemplates\"", member)));
304             }
305         }
306     }
307
308     // topology template can act like node template
309     // it is exposed by substitution_mappings.
310
311     public String nodetype() {
312         return substitutionMappings.getNodeType();
313     }
314
315     public LinkedHashMap<String, Object> capabilities() {
316         return substitutionMappings.getCapabilities();
317     }
318
319     public LinkedHashMap<String, Object> requirements() {
320         return substitutionMappings.getRequirements();
321     }
322
323     private String _tplDescription() {
324         return (String) tpl.get(DESCRIPTION);
325         //if description:
326         //      return description.rstrip()
327     }
328
329     @SuppressWarnings("unchecked")
330     private LinkedHashMap<String, Object> _tplInputs() {
331         if (tpl.get(INPUTS) != null) {
332             return (LinkedHashMap<String, Object>) tpl.get(INPUTS);
333         }
334         return new LinkedHashMap<String, Object>();
335     }
336
337     @SuppressWarnings("unchecked")
338     private LinkedHashMap<String, Object> _tplNodeTemplates() {
339         return (LinkedHashMap<String, Object>) tpl.get(NODE_TEMPLATES);
340     }
341
342     @SuppressWarnings("unchecked")
343     private LinkedHashMap<String, Object> _tplRelationshipTemplates() {
344         if (tpl.get(RELATIONSHIP_TEMPLATES) != null) {
345             return (LinkedHashMap<String, Object>) tpl.get(RELATIONSHIP_TEMPLATES);
346         }
347         return new LinkedHashMap<String, Object>();
348     }
349
350     @SuppressWarnings("unchecked")
351     private LinkedHashMap<String, Object> _tplOutputs() {
352         if (tpl.get(OUTPUTS) != null) {
353             return (LinkedHashMap<String, Object>) tpl.get(OUTPUTS);
354         }
355         return new LinkedHashMap<String, Object>();
356     }
357
358     @SuppressWarnings("unchecked")
359     private LinkedHashMap<String, Object> _tplSubstitutionMappings() {
360         if (tpl.get(SUBSTITUTION_MAPPINGS) != null) {
361             return (LinkedHashMap<String, Object>) tpl.get(SUBSTITUTION_MAPPINGS);
362         }
363         return new LinkedHashMap<String, Object>();
364     }
365
366     @SuppressWarnings("unchecked")
367     private LinkedHashMap<String, Object> _tplGroups() {
368         if (tpl.get(GROUPS) != null) {
369             return (LinkedHashMap<String, Object>) tpl.get(GROUPS);
370         }
371         return new LinkedHashMap<String, Object>();
372     }
373
374     @SuppressWarnings("unchecked")
375     private LinkedHashMap<String, Object> _tplPolicies() {
376         if (tpl.get(POLICIES) != null) {
377             return (LinkedHashMap<String, Object>) tpl.get(POLICIES);
378         }
379         return new LinkedHashMap<>();
380     }
381
382     private void _validateField() {
383         for (String name : tpl.keySet()) {
384             boolean bFound = false;
385             for (String section : SECTIONS) {
386                 if (name.equals(section)) {
387                     bFound = true;
388                     break;
389                 }
390             }
391             if (!bFound) {
392                 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE240", String.format(
393                         "UnknownFieldError: TopologyTemplate contains unknown field \"%s\"", name)));
394             }
395         }
396     }
397
398     @SuppressWarnings("unchecked")
399     private void _processIntrinsicFunctions() {
400         // Process intrinsic functions
401
402         // Current implementation processes functions within node template
403         // properties, requirements, interfaces inputs and template outputs.
404
405         if (nodeTemplates != null) {
406             for (NodeTemplate nt : nodeTemplates) {
407                 for (Property prop : nt.getPropertiesObjects()) {
408                     prop.setValue(Function.getFunction(this, nt, prop.getValue(), resolveGetInput));
409                 }
410                 for (InterfacesDef ifd : nt.getInterfaces()) {
411                     LinkedHashMap<String, Object> ifin = ifd.getInputs();
412                     if (ifin != null) {
413                         for (Map.Entry<String, Object> me : ifin.entrySet()) {
414                             String name = me.getKey();
415                             Object value = Function.getFunction(this, nt, me.getValue(), resolveGetInput);
416                             ifd.setInput(name, value);
417                         }
418                     }
419                 }
420                 if (nt.getRequirements() != null) {
421                     for (RequirementAssignment req : nt.getRequirements().getAll()) {
422                         LinkedHashMap<String, Object> rel;
423                         Object t = req.getRelationship();
424                         // it can be a string or a LHM...
425                         if (t instanceof LinkedHashMap) {
426                             rel = (LinkedHashMap<String, Object>) t;
427                         } else {
428                             // we set it to null to fail the next test
429                             // and avoid the get("proprties")
430                             rel = null;
431                         }
432
433                         if (rel != null && rel.get("properties") != null) {
434                             LinkedHashMap<String, Object> relprops =
435                                     (LinkedHashMap<String, Object>) rel.get("properties");
436                             for (String key : relprops.keySet()) {
437                                 Object value = relprops.get(key);
438                                 Object func = Function.getFunction(this, req, value, resolveGetInput);
439                                 relprops.put(key, func);
440                             }
441                         }
442                     }
443                 }
444                 if (nt.getCapabilitiesObjects() != null) {
445                     for (CapabilityAssignment cap : nt.getCapabilitiesObjects()) {
446                         if (cap.getPropertiesObjects() != null) {
447                             for (Property prop : cap.getPropertiesObjects()) {
448                                 Object propvalue = Function.getFunction(this, nt, prop.getValue(), resolveGetInput);
449                                 if (propvalue instanceof GetInput) {
450                                     propvalue = ((GetInput) propvalue).result();
451                                     for (String p : cap.getProperties().keySet()) {
452                                         //Object v = cap.getProperties().get(p);
453                                         if (p.equals(prop.getName())) {
454                                             cap.setProperty(p, propvalue);
455                                         }
456                                     }
457                                 }
458                             }
459                         }
460                     }
461                 }
462                 for (RelationshipType rel : nt.getRelationships().keySet()) {
463                     NodeTemplate node = nt.getRelationships().get(rel);
464                     ArrayList<RelationshipTemplate> relTpls = node.getRelationshipTemplate();
465                     if (relTpls != null) {
466                         for (RelationshipTemplate relTpl : relTpls) {
467                             // TT 5
468                             for (InterfacesDef iface : relTpl.getInterfaces()) {
469                                 if (iface.getInputs() != null) {
470                                     for (String name : iface.getInputs().keySet()) {
471                                         Object value = iface.getInputs().get(name);
472                                         Object func = Function.getFunction(
473                                                 this,
474                                                 relTpl,
475                                                 value,
476                                                 resolveGetInput);
477                                         iface.setInput(name, func);
478                                     }
479                                 }
480                             }
481                         }
482                     }
483                 }
484             }
485         }
486         for (Output output : outputs) {
487             Object func = Function.getFunction(this, outputs, output.getValue(), resolveGetInput);
488             if (func instanceof GetAttribute) {
489                 output.setAttr(Output.VALUE, func);
490             }
491         }
492     }
493
494     public static String getSubMappingNodeType(LinkedHashMap<String, Object> topologyTpl) {
495         if (topologyTpl != null && topologyTpl instanceof LinkedHashMap) {
496             Object submapTpl = topologyTpl.get(SUBSTITUTION_MAPPINGS);
497             return SubstitutionMappings.stGetNodeType((LinkedHashMap<String, Object>) submapTpl);
498         }
499         return null;
500     }
501
502     // getters
503
504     public LinkedHashMap<String, Object> getTpl() {
505         return tpl;
506     }
507
508     public LinkedHashMap<String, Object> getMetadata() {
509         return metaData;
510     }
511
512     public ArrayList<Input> getInputs() {
513         return inputs;
514     }
515
516     public ArrayList<Output> getOutputs() {
517         return outputs;
518     }
519
520     public ArrayList<Policy> getPolicies() {
521         return policies;
522     }
523
524     public ArrayList<RelationshipTemplate> getRelationshipTemplates() {
525         return relationshipTemplates;
526     }
527
528     public ArrayList<NodeTemplate> getNodeTemplates() {
529         return nodeTemplates;
530     }
531
532     public ArrayList<Group> getGroups() {
533         return groups;
534     }
535
536     public SubstitutionMappings getSubstitutionMappings() {
537         return substitutionMappings;
538     }
539
540     public LinkedHashMap<String, Object> getParsedParams() {
541         return parsedParams;
542     }
543
544     public boolean getResolveGetInput() {
545         return resolveGetInput;
546     }
547
548     public LinkedHashMap<String, Object> getCustomDefs() {
549         return customDefs;
550     }
551 }
552
553 /*python
554
555 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
556 #    not use this file except in compliance with the License. You may obtain
557 #    a copy of the License at
558 #
559 #         http://www.apache.org/licenses/LICENSE-2.0
560 #
561 #    Unless required by applicable law or agreed to in writing, software
562 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
563 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
564 #    License for the specific language governing permissions and limitations
565 #    under the License.
566
567
568 import logging
569
570 from toscaparser.common import exception
571 from toscaparser.dataentity import DataEntity
572 from toscaparser import functions
573 from toscaparser.groups import Group
574 from toscaparser.nodetemplate import NodeTemplate
575 from toscaparser.parameters import Input
576 from toscaparser.parameters import Output
577 from toscaparser.policy import Policy
578 from toscaparser.relationship_template import RelationshipTemplate
579 from toscaparser.substitution_mappings import SubstitutionMappings
580 from toscaparser.tpl_relationship_graph import ToscaGraph
581 from toscaparser.utils.gettextutils import _
582
583
584 # Topology template key names
585 SECTIONS = (DESCRIPTION, INPUTS, NODE_TEMPLATES,
586             RELATIONSHIP_TEMPLATES, OUTPUTS, GROUPS,
587             SUBSTITUION_MAPPINGS, POLICIES) = \
588            ('description', 'inputs', 'node_templates',
589             'relationship_templates', 'outputs', 'groups',
590             'substitution_mappings', 'policies')
591
592 log = logging.getLogger("tosca.model")
593
594
595 class TopologyTemplate(object):
596
597     '''Load the template data.'''
598     def __init__(self, template, custom_defs,
599                  rel_types=None, parsed_params=None,
600                  sub_mapped_node_template=None):
601         self.tpl = template
602         self.sub_mapped_node_template = sub_mapped_node_template
603         if self.tpl:
604             self.custom_defs = custom_defs
605             self.rel_types = rel_types
606             self.parsed_params = parsed_params
607             self._validate_field()
608             self.description = self._tpl_description()
609             self.inputs = self._inputs()
610             self.relationship_templates = self._relationship_templates()
611             self.nodetemplates = self._nodetemplates()
612             self.outputs = self._outputs()
613             if hasattr(self, 'nodetemplates'):
614                 self.graph = ToscaGraph(self.nodetemplates)
615             self.groups = self._groups()
616             self.policies = self._policies()
617             self._process_intrinsic_functions()
618             self.substitution_mappings = self._substitution_mappings()
619
620     def _inputs(self):
621         inputs = []
622         for name, attrs in self._tpl_inputs().items():
623             input = Input(name, attrs)
624             if self.parsed_params and name in self.parsed_params:
625                 input.validate(self.parsed_params[name])
626             else:
627                 default = input.default
628                 if default:
629                     input.validate(default)
630             if (self.parsed_params and input.name not in self.parsed_params
631                 or self.parsed_params is None) and input.required \
632                     and input.default is None:
633                 log.warning(_('The required parameter %s '
634                               'is not provided') % input.name)
635
636             inputs.append(input)
637         return inputs
638
639     def _nodetemplates(self):
640         nodetemplates = []
641         tpls = self._tpl_nodetemplates()
642         if tpls:
643             for name in tpls:
644                 tpl = NodeTemplate(name, tpls, self.custom_defs,
645                                    self.relationship_templates,
646                                    self.rel_types)
647                 if (tpl.type_definition and
648                     (tpl.type in tpl.type_definition.TOSCA_DEF or
649                      (tpl.type not in tpl.type_definition.TOSCA_DEF and
650                       bool(tpl.custom_def)))):
651                     tpl.validate(self)
652                     nodetemplates.append(tpl)
653         return nodetemplates
654
655     def _relationship_templates(self):
656         rel_templates = []
657         tpls = self._tpl_relationship_templates()
658         for name in tpls:
659             tpl = RelationshipTemplate(tpls[name], name, self.custom_defs)
660             rel_templates.append(tpl)
661         return rel_templates
662
663     def _outputs(self):
664         outputs = []
665         for name, attrs in self._tpl_outputs().items():
666             output = Output(name, attrs)
667             output.validate()
668             outputs.append(output)
669         return outputs
670
671     def _substitution_mappings(self):
672         tpl_substitution_mapping = self._tpl_substitution_mappings()
673         # if tpl_substitution_mapping and self.sub_mapped_node_template:
674         if tpl_substitution_mapping:
675             return SubstitutionMappings(tpl_substitution_mapping,
676                                         self.nodetemplates,
677                                         self.inputs,
678                                         self.outputs,
679                                         self.sub_mapped_node_template,
680                                         self.custom_defs)
681
682     def _policies(self):
683         policies = []
684         for policy in self._tpl_policies():
685             for policy_name, policy_tpl in policy.items():
686                 target_list = policy_tpl.get('targets')
687                 if target_list and len(target_list) >= 1:
688                     target_objects = []
689                     targets_type = "groups"
690                     target_objects = self._get_policy_groups(target_list)
691                     if not target_objects:
692                         targets_type = "node_templates"
693                         target_objects = self._get_group_members(target_list)
694                     policyObj = Policy(policy_name, policy_tpl,
695                                        target_objects, targets_type,
696                                        self.custom_defs)
697                     policies.append(policyObj)
698         return policies
699
700     def _groups(self):
701         groups = []
702         member_nodes = None
703         for group_name, group_tpl in self._tpl_groups().items():
704             member_names = group_tpl.get('members')
705             if member_names is not None:
706                 DataEntity.validate_datatype('list', member_names)
707                 if len(member_names) < 1 or \
708                         len(member_names) != len(set(member_names)):
709                     exception.ValidationIssueCollector.appendException(
710                         exception.InvalidGroupTargetException(
711                             message=_('Member nodes "%s" should be >= 1 '
712                                       'and not repeated') % member_names))
713                 else:
714                     member_nodes = self._get_group_members(member_names)
715             group = Group(group_name, group_tpl,
716                           member_nodes,
717                           self.custom_defs)
718             groups.append(group)
719         return groups
720
721     def _get_group_members(self, member_names):
722         member_nodes = []
723         self._validate_group_members(member_names)
724         for member in member_names:
725             for node in self.nodetemplates:
726                 if node.name == member:
727                     member_nodes.append(node)
728         return member_nodes
729
730     def _get_policy_groups(self, member_names):
731         member_groups = []
732         for member in member_names:
733             for group in self.groups:
734                 if group.name == member:
735                     member_groups.append(group)
736         return member_groups
737
738     def _validate_group_members(self, members):
739         node_names = []
740         for node in self.nodetemplates:
741             node_names.append(node.name)
742         for member in members:
743             if member not in node_names:
744                 exception.ValidationIssueCollector.appendException(
745                     exception.InvalidGroupTargetException(
746                         message=_('Target member "%s" is not found in '
747                                   'node_templates') % member))
748
749     # topology template can act like node template
750     # it is exposed by substitution_mappings.
751     def nodetype(self):
752         return self.substitution_mappings.node_type \
753             if self.substitution_mappings else None
754
755     def capabilities(self):
756         return self.substitution_mappings.capabilities \
757             if self.substitution_mappings else None
758
759     def requirements(self):
760         return self.substitution_mappings.requirements \
761             if self.substitution_mappings else None
762
763     def _tpl_description(self):
764         description = self.tpl.get(DESCRIPTION)
765         if description:
766             return description.rstrip()
767
768     def _tpl_inputs(self):
769         return self.tpl.get(INPUTS) or {}
770
771     def _tpl_nodetemplates(self):
772         return self.tpl.get(NODE_TEMPLATES)
773
774     def _tpl_relationship_templates(self):
775         return self.tpl.get(RELATIONSHIP_TEMPLATES) or {}
776
777     def _tpl_outputs(self):
778         return self.tpl.get(OUTPUTS) or {}
779
780     def _tpl_substitution_mappings(self):
781         return self.tpl.get(SUBSTITUION_MAPPINGS) or {}
782
783     def _tpl_groups(self):
784         return self.tpl.get(GROUPS) or {}
785
786     def _tpl_policies(self):
787         return self.tpl.get(POLICIES) or {}
788
789     def _validate_field(self):
790         for name in self.tpl:
791             if name not in SECTIONS:
792                 exception.ValidationIssueCollector.appendException(
793                     exception.UnknownFieldError(what='Template', field=name))
794
795     def _process_intrinsic_functions(self):
796         """Process intrinsic functions
797
798         Current implementation processes functions within node template
799         properties, requirements, interfaces inputs and template outputs.
800         """
801         if hasattr(self, 'nodetemplates'):
802             for node_template in self.nodetemplates:
803                 for prop in node_template.get_properties_objects():
804                     prop.value = functions.get_function(self,
805                                                         node_template,
806                                                         prop.value)
807                 for interface in node_template.interfaces:
808                     if interface.inputs:
809                         for name, value in interface.inputs.items():
810                             interface.inputs[name] = functions.get_function(
811                                 self,
812                                 node_template,
813                                 value)
814                 if node_template.requirements and \
815                    isinstance(node_template.requirements, list):
816                     for req in node_template.requirements:
817                         rel = req
818                         for req_name, req_item in req.items():
819                             if isinstance(req_item, dict):
820                                 rel = req_item.get('relationship')
821                                 break
822                         if rel and 'properties' in rel:
823                             for key, value in rel['properties'].items():
824                                 rel['properties'][key] = \
825                                     functions.get_function(self,
826                                                            req,
827                                                            value)
828                 if node_template.get_capabilities_objects():
829                     for cap in node_template.get_capabilities_objects():
830                         if cap.get_properties_objects():
831                             for prop in cap.get_properties_objects():
832                                 propvalue = functions.get_function(
833                                     self,
834                                     node_template,
835                                     prop.value)
836                                 if isinstance(propvalue, functions.GetInput):
837                                     propvalue = propvalue.result()
838                                     for p, v in cap._properties.items():
839                                         if p == prop.name:
840                                             cap._properties[p] = propvalue
841                 for rel, node in node_template.relationships.items():
842                     rel_tpls = node.relationship_tpl
843                     if rel_tpls:
844                         for rel_tpl in rel_tpls:
845                             for interface in rel_tpl.interfaces:
846                                 if interface.inputs:
847                                     for name, value in \
848                                             interface.inputs.items():
849                                         interface.inputs[name] = \
850                                             functions.get_function(self,
851                                                                    rel_tpl,
852                                                                    value)
853         for output in self.outputs:
854             func = functions.get_function(self, self.outputs, output.value)
855             if isinstance(func, functions.GetAttribute):
856                 output.attrs[output.VALUE] = func
857
858     @classmethod
859     def get_sub_mapping_node_type(cls, topology_tpl):
860         if topology_tpl and isinstance(topology_tpl, dict):
861             submap_tpl = topology_tpl.get(SUBSTITUION_MAPPINGS)
862             return SubstitutionMappings.get_node_type(submap_tpl)
863 */