[SDC] Onboarding 1710 rebase.
[sdc.git] / openecomp-be / lib / openecomp-sdc-tosca-generator-lib / openecomp-sdc-tosca-generator-core / src / main / java / org / openecomp / sdc / generator / core / services / ManualVspToscaGenerationService.java
1 package org.openecomp.sdc.generator.core.services;
2
3 import static org.openecomp.sdc.generator.util.GeneratorConstants.ALLOWED_FLAVORS_PROPERTY;
4 import static org.openecomp.sdc.generator.util.GeneratorConstants.DISK_SIZE;
5 import static org.openecomp.sdc.generator.util.GeneratorConstants.DISK_SIZE_PROP_DESC_PREFIX;
6 import static org.openecomp.sdc.generator.util.GeneratorConstants.IMAGES_PROPERTY;
7 import static org.openecomp.sdc.generator.util.GeneratorConstants.MEM_SIZE;
8 import static org.openecomp.sdc.generator.util.GeneratorConstants.MEM_SIZE_PROP_DESC_PREFIX;
9 import static org.openecomp.sdc.generator.util.GeneratorConstants.NUM_CPUS;
10 import static org.openecomp.sdc.generator.util.GeneratorConstants.NUM_CPUS_PROP_DESC_PREFIX;
11 import static org.openecomp.sdc.generator.util.GeneratorConstants.PORT_NODE_TEMPLATE_ID_SUFFIX;
12 import static org.openecomp.sdc.generator.util.GeneratorConstants.RELEASE_VENDOR;
13 import static org.openecomp.sdc.generator.util.GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
14 import static org.openecomp.sdc.generator.util.GeneratorConstants.VFC_NODE_TEMPLATE_ID_SUFFIX;
15 import static org.openecomp.sdc.generator.util.GeneratorConstants.VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
16 import static org.openecomp.sdc.generator.util.GeneratorConstants.VNF_NODE_TEMPLATE_ID_SUFFIX;
17
18 import org.apache.commons.collections4.CollectionUtils;
19 import org.apache.commons.collections4.MapUtils;
20 import org.openecomp.sdc.generator.core.utils.GeneratorUtils;
21 import org.openecomp.sdc.generator.datatypes.tosca.MultiFlavorVfcImage;
22 import org.openecomp.sdc.generator.datatypes.tosca.VspModelInfo;
23 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
24 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
25 import org.openecomp.sdc.tosca.datatypes.model.Import;
26 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
27 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
28 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
29 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
30 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
31 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
32 import org.openecomp.sdc.tosca.services.DataModelUtil;
33 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
34 import org.openecomp.sdc.tosca.services.ToscaConstants;
35 import org.openecomp.sdc.tosca.services.ToscaUtil;
36 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
37 import org.openecomp.sdc.translator.services.heattotosca.Constants;
38 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
39 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
40
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.LinkedHashMap;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Objects;
47 import java.util.Optional;
48
49 /**
50  * The type Manual vsp tosca generator.
51  */
52 public class ManualVspToscaGenerationService {
53
54   //Map of the abstract node template id and substitution node type
55   private Map<String, String> abstractSubstitutionIdTypes = new HashMap<>();
56   //Map of service template name and service template for the generated service templates
57   private Map<String, ServiceTemplate> generatedServiceTemplates = new HashMap<>();
58
59
60   /**
61    * Create manual vsp tosca service model tosca service model.
62    *
63    * @param vspModelInfo the vsp model info
64    * @return the tosca service model
65    */
66   public ToscaServiceModel createManualVspToscaServiceModel(VspModelInfo vspModelInfo) {
67     ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
68     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
69     Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(GlobalTypesGenerator
70         .getGlobalTypesServiceTemplate());
71     toscaServiceModel.setServiceTemplates(serviceTemplates);
72     toscaServiceModel.setEntryDefinitionServiceTemplate(Constants.MAIN_TEMPLATE_NAME
73         + TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX);
74     createToscaFromVspData(vspModelInfo, toscaServiceModel);
75     for (Map.Entry<String, ServiceTemplate> serviceTemplateEntry :
76         generatedServiceTemplates.entrySet()) {
77       ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplateEntry
78           .getValue());
79     }
80     return toscaServiceModel;
81   }
82
83   private void createToscaFromVspData(VspModelInfo vspModelInfo,
84                                         ToscaServiceModel toscaServiceModel) {
85     List<ServiceTemplate> serviceTemplates = new ArrayList<>();
86     //Only one component supported
87     Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
88     if (componentName.isPresent()) {
89       //Create main service template
90       ServiceTemplate mainServiceTemplate = createMainServiceTemplate(vspModelInfo);
91       generatedServiceTemplates.put(Constants.MAIN_TEMPLATE_NAME, mainServiceTemplate);
92       //Create substitution service template
93       for (Map.Entry<String, String> entry : abstractSubstitutionIdTypes.entrySet()) {
94         ServiceTemplate substitutionServiceTemplate =
95             createSubstitutionServiceTemplate(componentName.get(), entry.getValue(), vspModelInfo,
96                 toscaServiceModel);
97         generatedServiceTemplates.put(componentName.get(), substitutionServiceTemplate);
98       }
99     }
100
101   }
102
103   private Optional<String> getComponentNameFromVspModel(VspModelInfo vspModelInfo) {
104     String componentName = null;
105     if (MapUtils.isNotEmpty(vspModelInfo.getComponents())) {
106       //supported for single component only
107       componentName = vspModelInfo.getComponents().entrySet().iterator().next().getValue();
108     }
109     return Optional.ofNullable(componentName);
110   }
111
112   private ServiceTemplate createMainServiceTemplate(VspModelInfo vspModelInfo) {
113     ServiceTemplate mainServiceTemplate = createInitMainServiceTemplate(vspModelInfo
114         .getReleaseVendor());
115     Map<String, String> components = vspModelInfo.getComponents();
116     if (MapUtils.isNotEmpty(components)) {
117       //Currently since only one component is supported we can fetch the component in this manner.
118       // May be need to revisited for supporting multiple components
119       String componentId = components.entrySet().iterator().next().getKey();
120       createVnfConfigurationNodeTemplate(mainServiceTemplate, vspModelInfo);
121       createComponentNodeTemplate(mainServiceTemplate, vspModelInfo, componentId);
122       createVnfNodeTemplate(mainServiceTemplate, vspModelInfo);
123     }
124     return mainServiceTemplate;
125   }
126
127   private void createVnfConfigurationNodeTemplate(ServiceTemplate mainServiceTemplate,
128                                                   VspModelInfo vspModelInfo) {
129     Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
130     if (componentName.isPresent()) {
131       NodeTemplate vnfConfigurationNodeTemplate = new NodeTemplate();
132       vnfConfigurationNodeTemplate.setType(ToscaNodeType.VNF_CONFIG_NODE_TYPE);
133       if (Objects.nonNull(vspModelInfo.getAllowedFlavors())) {
134         Map<String, Object> properties = new LinkedHashMap<>();
135         properties.put(ALLOWED_FLAVORS_PROPERTY, vspModelInfo.getAllowedFlavors());
136         vnfConfigurationNodeTemplate.setProperties(properties);
137       }
138       String nodeTemplateId = componentName.get() + VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
139       DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
140           vnfConfigurationNodeTemplate);
141     }
142   }
143
144   private void createComponentNodeTemplate(ServiceTemplate mainServiceTemplate,
145                                                   VspModelInfo vspModelInfo,
146                                                   String componentId) {
147     Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
148     if (componentName.isPresent()) {
149       NodeTemplate vfcNodeTemplate = new NodeTemplate();
150       vfcNodeTemplate.setType(ToscaNodeType.MULTIFLAVOR_VFC_NODE_TYPE);
151       Map<String, Object> properties = new LinkedHashMap<>();
152       if (MapUtils.isNotEmpty(vspModelInfo.getMultiFlavorVfcImages())) {
153         List<MultiFlavorVfcImage> componentImages =
154             vspModelInfo.getMultiFlavorVfcImages().get(componentId);
155         Map<String, MultiFlavorVfcImage> vfcImages = new HashMap<>();
156         for (MultiFlavorVfcImage image : componentImages) {
157           vfcImages.put(image.getSoftware_version(), image);
158         }
159         properties.put(IMAGES_PROPERTY, vfcImages);
160         vfcNodeTemplate.setProperties(properties);
161       }
162       String nodeTemplateId = componentName.get() + VFC_NODE_TEMPLATE_ID_SUFFIX;
163       DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
164           vfcNodeTemplate);
165     }
166   }
167
168   private void createVnfNodeTemplate(ServiceTemplate mainServiceTemplate,
169                                       VspModelInfo vspModelInfo) {
170     Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
171     if (componentName.isPresent()) {
172       NodeTemplate vnfNodeTemplate = new NodeTemplate();
173       String vnfNodeTemplateType =
174           ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName.get();
175       vnfNodeTemplate.setType(vnfNodeTemplateType);
176       List<String> directiveList = new ArrayList<>();
177       directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
178       vnfNodeTemplate.setDirectives(directiveList);
179       vnfNodeTemplate.setProperties(new LinkedHashMap<>());
180       DataModelUtil
181           .addSubstitutionFilteringProperty(getSubstitutionServiceTemplateFileName(componentName
182                   .get()), vnfNodeTemplate, 1);
183       //Enable below if we need "abstract_" as prefix like we have in Unified model
184       //String nodeTemplateId =
185       // Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + componentName + "VNF_NODE_TEMPLATE_ID_SUFFIX";
186       String nodeTemplateId = componentName.get() + VNF_NODE_TEMPLATE_ID_SUFFIX;
187       DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
188           vnfNodeTemplate);
189       abstractSubstitutionIdTypes.put(componentName.get(), vnfNodeTemplateType);
190     }
191   }
192
193   private String getSubstitutionServiceTemplateFileName(String componentName) {
194     return componentName + TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
195   }
196
197   private String getNodeTemplateId(String componentName, String idPrefix, String idSuffix) {
198     StringBuilder builder = new StringBuilder();
199     //builder.append(idPrefix);
200     builder.append(componentName);
201     builder.append(idSuffix);
202     return builder.toString();
203   }
204
205   private ServiceTemplate createInitMainServiceTemplate(String releaseVendor) {
206     ServiceTemplate mainServiceTemplate = new ServiceTemplate();
207     Map<String, String> templateMetadata = new HashMap<>();
208     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
209     if (Objects.nonNull(releaseVendor)) {
210       templateMetadata.put(RELEASE_VENDOR, releaseVendor);
211     }
212     mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
213     mainServiceTemplate.setMetadata(templateMetadata);
214     mainServiceTemplate.setTopology_template(new TopologyTemplate());
215     mainServiceTemplate.setImports(getImports());
216     return mainServiceTemplate;
217   }
218
219   private List<Map<String, Import>> getImports() {
220     Map<String, Import> globalSubstitutionTypeImportMap = new HashMap<>();
221     Import globalSubstitutionTypeImport = new Import();
222     globalSubstitutionTypeImport.setFile(ToscaUtil.getServiceTemplateFileName(Constants
223         .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
224     globalSubstitutionTypeImportMap.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
225         globalSubstitutionTypeImport);
226     Map<String, Import> globalImports = new HashMap<>();
227     List<Map<String, Import>> manualVspGlobalTypesImportList = GlobalTypesGenerator
228         .getManualVspGlobalTypesImportList();
229     manualVspGlobalTypesImportList.add(globalSubstitutionTypeImportMap);
230     return manualVspGlobalTypesImportList;
231   }
232
233   private ServiceTemplate createSubstitutionServiceTemplate(String serviceTemplateName,
234                                                             String substitutionNodeTypeId,
235                                                             VspModelInfo vspModelInfo,
236                                                             ToscaServiceModel toscaServiceModel) {
237     ServiceTemplate substitutionServiceTemplate =
238         createInitSubstitutionServiceTemplate(serviceTemplateName);
239     createSubstitutionServiceTemplateComponents(substitutionServiceTemplate, vspModelInfo,
240         toscaServiceModel);
241     createSubstitutionServiceTemplateNics(substitutionServiceTemplate, vspModelInfo,
242         toscaServiceModel);
243     handleSubstitutionMapping(substitutionServiceTemplate, toscaServiceModel,
244         substitutionNodeTypeId, serviceTemplateName);
245     return substitutionServiceTemplate;
246   }
247
248   private void createSubstitutionServiceTemplateComponents(ServiceTemplate
249                                                                substitutionServiceTemplate,
250                                                            VspModelInfo vspModelInfo,
251                                                            ToscaServiceModel toscaServiceModel) {
252     Map<String, String> components = vspModelInfo.getComponents();
253     if (MapUtils.isNotEmpty(components)) {
254       for (String componentId : components.keySet()) {
255         String componentName = components.get(componentId);
256         String localNodeTypeId =
257             createComponentDefinitionNodeTemplate(substitutionServiceTemplate, componentName);
258         createLocalNodeType(substitutionServiceTemplate, localNodeTypeId);
259       }
260     }
261   }
262
263   private void createSubstitutionServiceTemplateNics(ServiceTemplate substitutionServiceTemplate,
264                                                      VspModelInfo vspModelInfo,
265                                                      ToscaServiceModel toscaServiceModel) {
266     Map<String, List<Nic>> nics = vspModelInfo.getNics();
267     if (MapUtils.isNotEmpty(nics)) {
268       for (Map.Entry<String, List<Nic>> entry : nics.entrySet()) {
269         String componentId = entry.getKey();
270         String componentNodeTemplateId = getSubstitutionComponentNodeTemplateId(
271             vspModelInfo.getComponents().get(componentId));
272         List<Nic> nicList = entry.getValue();
273         if (CollectionUtils.isNotEmpty(nicList)) {
274           for (Nic nic : nicList) {
275             NodeTemplate nicNodeTemplate = new NodeTemplate();
276             nicNodeTemplate.setType(ToscaNodeType.NETWORK_PORT);
277             DataModelUtil.addBindingReqFromPortToCompute(componentNodeTemplateId, nicNodeTemplate);
278             DataModelUtil.addNodeTemplate(substitutionServiceTemplate,
279                 getNicNodeTemplateId(nic.getName()), nicNodeTemplate);
280           }
281         }
282       }
283     }
284   }
285
286   private String getSubstitutionComponentNodeTemplateId(String componentName) {
287     //TODO: Confirm if anything else is needed here
288     return componentName;
289   }
290
291   private String getNicNodeTemplateId(String nicName) {
292     StringBuilder builder = new StringBuilder();
293     builder.append(nicName);
294     builder.append(PORT_NODE_TEMPLATE_ID_SUFFIX);
295     return builder.toString();
296   }
297
298   private String createComponentDefinitionNodeTemplate(ServiceTemplate substitutionServiceTemplate,
299                                                        String componentName) {
300     NodeTemplate nodeTemplate = new NodeTemplate();
301     String localNodeTypeId = getLocalNodeTypeId(componentName);
302     nodeTemplate.setType(localNodeTypeId);
303     DataModelUtil.addNodeTemplate(substitutionServiceTemplate, componentName, nodeTemplate);
304     return localNodeTypeId;
305   }
306
307   private void createLocalNodeType(ServiceTemplate substitutionServiceTemplate,
308                                    String localNodeTypeId) {
309     NodeType localNodeType = new NodeType();
310     localNodeType.setDerived_from(ToscaNodeType.COMPUTE);
311     DataModelUtil.addNodeType(substitutionServiceTemplate, localNodeTypeId, localNodeType );
312   }
313
314   private String getLocalNodeTypeId(String componentName) {
315     return ToscaNodeType.VFC_NODE_TYPE_PREFIX + componentName;
316   }
317
318   private ServiceTemplate createInitSubstitutionServiceTemplate(String serviceTemplateName) {
319     ServiceTemplate substitutionServiceTemplate = new ServiceTemplate();
320     Map<String, String> templateMetadata = new HashMap<>();
321     substitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
322         .TOSCA_DEFINITIONS_VERSION);
323     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, serviceTemplateName);
324     substitutionServiceTemplate.setMetadata(templateMetadata);
325     substitutionServiceTemplate.setTopology_template(new TopologyTemplate());
326     substitutionServiceTemplate.setImports(getImports());
327     return substitutionServiceTemplate;
328   }
329
330   private void handleSubstitutionMapping(ServiceTemplate substitutionServiceTemplate,
331                                          ToscaServiceModel toscaServiceModel,
332                                          String substitutionNodeTypeId,
333                                          String componentName) {
334     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
335     ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
336     NodeType substitutionNodeType =
337         createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
338     DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
339         substitutionNodeType);
340
341     Map<String, Map<String, List<String>>> substitutionMapping =
342         GeneratorUtils.getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
343             substitutionServiceTemplate, toscaServiceModel);
344     if (Objects.nonNull(substitutionMapping)) {
345       //add substitution mapping after capability and requirement expose calculation
346       substitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
347           DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeId,
348               substitutionNodeType, substitutionMapping));
349     }
350   }
351
352   //*************** CREATE GLOBAL SUBSTITUTION SERVICE TEMPLATE **********************
353
354   private ServiceTemplate createGlobalSubstitutionServiceTemplate(ServiceTemplate
355                                                                       substitutionServiceTemplate,
356                                                                   String componentName) {
357     ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
358     NodeType substitutionNodeType =
359         createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
360     String substitutionNodeTypeId = getSubstitutionNodeTypeId(componentName);
361     DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
362         substitutionNodeType);
363     return globalSubstitutionServiceTemplate;
364   }
365
366   private ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
367     ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
368     Map<String, String> templateMetadata = new HashMap<>();
369     globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
370         .TOSCA_DEFINITIONS_VERSION);
371     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
372         Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
373     globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
374     globalSubstitutionServiceTemplate.setImports(getImports());
375     return globalSubstitutionServiceTemplate;
376   }
377
378   private NodeType createGlobalSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
379                                                 String componentName) {
380     NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
381         .createInitSubstitutionNodeType(substitutionServiceTemplate,
382             ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
383     substitutionNodeType.setProperties(
384         getManualVspSubstitutionNodeTypeProperties(substitutionNodeType, componentName));
385     return substitutionNodeType;
386   }
387
388   private Map<String, PropertyDefinition> getManualVspSubstitutionNodeTypeProperties(
389       NodeType substitutionNodeType, String componentName) {
390     //Create num_cpus property
391     PropertyDefinition numCpus = new PropertyDefinition();
392     numCpus.setType(PropertyType.INTEGER.getDisplayName());
393     numCpus.setDescription(NUM_CPUS_PROP_DESC_PREFIX + componentName);
394     numCpus.setRequired(true);
395     //Create disk_size property
396     PropertyDefinition diskSize = new PropertyDefinition();
397     diskSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
398     diskSize.setDescription(DISK_SIZE_PROP_DESC_PREFIX + componentName);
399     diskSize.setRequired(true);
400     //Create mem_size property
401     PropertyDefinition memSize = new PropertyDefinition();
402     memSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
403     memSize.setDescription(MEM_SIZE_PROP_DESC_PREFIX + componentName);
404     memSize.setRequired(true);
405
406     Map<String, PropertyDefinition> manualVspProperties = new LinkedHashMap<>();
407     manualVspProperties.put(NUM_CPUS, numCpus);
408     manualVspProperties.put(DISK_SIZE, diskSize);
409     manualVspProperties.put(MEM_SIZE, memSize);
410
411     return manualVspProperties;
412   }
413
414   private String getSubstitutionNodeTypeId(String componentName) {
415     return ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName;
416   }
417
418   /**
419    * Fetch global substitution service template service template.
420    *
421    * @return the global substitution service template
422    */
423   private ServiceTemplate fetchGlobalSubstitutionServiceTemplate() {
424     ServiceTemplate globalSubstitutionServiceTemplate =
425         generatedServiceTemplates.get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
426     if (Objects.isNull(globalSubstitutionServiceTemplate)) {
427       globalSubstitutionServiceTemplate = createInitGlobalSubstitutionServiceTemplate();
428       generatedServiceTemplates.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
429               globalSubstitutionServiceTemplate);
430     }
431     return globalSubstitutionServiceTemplate;
432   }
433 }