f1582eecb1cc470c55d4cb06bc0d4363bd26398f
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / CommonImportManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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  * Modifications copyright (c) 2019 Nokia
20  * ================================================================================
21  */
22 package org.openecomp.sdc.be.components.impl;
23
24 import static java.util.stream.Collectors.toList;
25
26 import fj.data.Either;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import java.util.function.BiFunction;
34 import java.util.function.Consumer;
35 import java.util.function.Function;
36 import java.util.stream.Collectors;
37 import org.apache.commons.lang3.tuple.ImmutablePair;
38 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
39 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
40 import org.openecomp.sdc.be.components.impl.model.ToscaTypeImportData;
41 import org.openecomp.sdc.be.config.BeEcompErrorManager;
42 import org.openecomp.sdc.be.dao.api.ActionStatus;
43 import org.openecomp.sdc.be.datatypes.elements.ToscaTypeDataDefinition;
44 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
45 import org.openecomp.sdc.be.impl.ComponentsUtils;
46 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
47 import org.openecomp.sdc.be.model.DataTypeDefinition;
48 import org.openecomp.sdc.be.model.GroupTypeDefinition;
49 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
50 import org.openecomp.sdc.be.model.PropertyDefinition;
51 import org.openecomp.sdc.be.model.normatives.ElementTypeEnum;
52 import org.openecomp.sdc.be.model.normatives.ToscaTypeMetadata;
53 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
54 import org.openecomp.sdc.be.model.operations.api.TypeOperations;
55 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
56 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
57 import org.openecomp.sdc.common.log.wrappers.Logger;
58 import org.openecomp.sdc.exception.ResponseFormat;
59 import org.springframework.beans.factory.annotation.Autowired;
60 import org.springframework.stereotype.Component;
61 import org.yaml.snakeyaml.Yaml;
62
63 @Component("commonImportManager")
64 public class CommonImportManager {
65
66     private static final Logger log = Logger.getLogger(CommonImportManager.class.getName());
67     private final ComponentsUtils componentsUtils;
68     private final PropertyOperation propertyOperation;
69     private final ModelOperation modelOperation;
70
71     @Autowired
72     public CommonImportManager(final ComponentsUtils componentsUtils,
73                                final PropertyOperation propertyOperation,
74                                final ModelOperation modelOperation) {
75         this.componentsUtils = componentsUtils;
76         this.propertyOperation = propertyOperation;
77         this.modelOperation = modelOperation;
78     }
79
80     public static void setProperties(Map<String, Object> toscaJson, Consumer<List<PropertyDefinition>> consumer) {
81         consumer.accept(getProperties(toscaJson));
82     }
83
84     private static List<PropertyDefinition> getProperties(Map<String, Object> toscaJson) {
85         List<PropertyDefinition> values = null;
86         Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils.getProperties(toscaJson);
87         if (properties.isLeft()) {
88             values = new ArrayList<>();
89             Map<String, PropertyDefinition> propertiesMap = properties.left().value();
90             if (propertiesMap != null && !propertiesMap.isEmpty()) {
91                 for (Entry<String, PropertyDefinition> entry : propertiesMap.entrySet()) {
92                     String propName = entry.getKey();
93                     PropertyDefinition propertyDefinition = entry.getValue();
94                     PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition);
95                     newPropertyDefinition.setName(propName);
96                     values.add(newPropertyDefinition);
97                 }
98             }
99         }
100         return values;
101     }
102
103     private static <T> List<T> append(List<T> list, T value) {
104         list.add(value);
105         return list;
106     }
107
108     protected void setPropertiesMap(Map<String, Object> toscaJson, Consumer<Map<String, PropertyDefinition>> consumer) {
109         final List<PropertyDefinition> properties = getProperties(toscaJson);
110         if (properties != null) {
111             Map<String, PropertyDefinition> collect = properties.stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity()));
112             consumer.accept(collect);
113         }
114     }
115
116     protected <T> Either<List<T>, ActionStatus> createElementTypesFromYml(String elementTypesYml,
117                                                                           ICreateElementType<String, Map<String, Object>, T> createApi) {
118         List<T> elementTypes;
119         Map<String, Object> toscaJson = convertToFieldMap(elementTypesYml);
120         if (toscaJson == null) {
121             return Either.right(ActionStatus.INVALID_YAML_FILE);
122         }
123         elementTypes = createElementTypesFromToscaJsonMap(createApi, toscaJson);
124         return Either.left(elementTypes);
125     }
126
127     @SuppressWarnings("unchecked")
128     private Map<String, Object> convertToFieldMap(String elementTypesYml) {
129         Map<String, Object> toscaJson = null;
130         try {
131             toscaJson = (Map<String, Object>) new Yaml().load(elementTypesYml);
132         } catch (Exception e) {
133             log.debug("Failed to yaml file {}", elementTypesYml, e);
134         }
135         return toscaJson;
136     }
137
138     protected <T extends ToscaDataDefinition> List<T> createTypesFromToscaJsonMap(BiFunction<String, Map<String, Object>, T> createApi,
139                                                                                   Map<String, Object> toscaJson) {
140         List<T> elementTypes = new ArrayList<>();
141         for (Entry<String, Object> elementTypeNameDataEntry : toscaJson.entrySet()) {
142             String elementTypeName = elementTypeNameDataEntry.getKey();
143             Map<String, Object> elementTypeJsonData = (Map<String, Object>) elementTypeNameDataEntry.getValue();
144             T elementDefinition = createApi.apply(elementTypeName, elementTypeJsonData);
145             elementTypes.add(elementDefinition);
146         }
147         return elementTypes;
148     }
149
150     protected <T> List<T> createElementTypesFromToscaJsonMap(ICreateElementType<String, Map<String, Object>, T> createApi,
151                                                              Map<String, Object> toscaJson) {
152         List<T> elementTypes = new ArrayList<>();
153         for (Entry<String, Object> elementTypeNameDataEntry : toscaJson.entrySet()) {
154             String elementTypeName = elementTypeNameDataEntry.getKey();
155             Map<String, Object> elementTypeJsonData = (Map<String, Object>) elementTypeNameDataEntry.getValue();
156             T elementDefinition = createApi.createElement(elementTypeName, elementTypeJsonData);
157             elementTypes.add(elementDefinition);
158         }
159         return elementTypes;
160     }
161
162     protected <T> Map<String, T> createElementTypesMapFromToscaJsonMap(ICreateElementType<String, Map<String, Object>, T> createApi,
163                                                                        Map<String, Object> toscaJson) {
164         Map<String, T> elementTypesMap = new HashMap<>();
165         Iterator<Entry<String, Object>> elementTypesEntryItr = toscaJson.entrySet().iterator();
166         while (elementTypesEntryItr.hasNext()) {
167             Entry<String, Object> elementTypeNameDataEntry = elementTypesEntryItr.next();
168             String elementTypeName = elementTypeNameDataEntry.getKey();
169             Map<String, Object> elementTypeJsonData = (Map<String, Object>) elementTypeNameDataEntry.getValue();
170             T elementDefinition = createApi.createElement(elementTypeName, elementTypeJsonData);
171             elementTypesMap.put(elementTypeName, elementDefinition);
172         }
173         return elementTypesMap;
174     }
175
176     protected <F> void setField(Map<String, Object> toscaJson, String fieldName, Consumer<F> setter) {
177         if (toscaJson.containsKey(fieldName)) {
178             F fieldValue = (F) toscaJson.get(fieldName);
179             setter.accept(fieldValue);
180         }
181     }
182
183     private ActionStatus convertFromStorageResponseForElementType(StorageOperationStatus status, ElementTypeEnum elementTypeEnum) {
184         ActionStatus ret;
185         switch (elementTypeEnum) {
186             case GROUP_TYPE:
187                 ret = componentsUtils.convertFromStorageResponseForGroupType(status);
188                 break;
189             case POLICY_TYPE:
190                 ret = componentsUtils.convertFromStorageResponseForPolicyType(status);
191                 break;
192             case DATA_TYPE:
193                 ret = componentsUtils.convertFromStorageResponseForDataType(status);
194                 break;
195             case CAPABILITY_TYPE:
196                 ret = componentsUtils.convertFromStorageResponseForCapabilityType(status);
197                 break;
198             case INTERFACE_LIFECYCLE_TYPE:
199                 ret = componentsUtils.convertFromStorageResponseForLifecycleType(status);
200                 break;
201             case RELATIONSHIP_TYPE:
202                 ret = componentsUtils.convertFromStorageResponseForRelationshipType(status);
203                 break;
204             default:
205                 ret = componentsUtils.convertFromStorageResponse(status);
206                 break;
207         }
208         return ret;
209     }
210
211     private <T> ResponseFormat getResponseFormatForElementType(ActionStatus actionStatus, ElementTypeEnum elementTypeEnum, T elementTypeDefinition) {
212         ResponseFormat ret;
213         switch (elementTypeEnum) {
214             case GROUP_TYPE:
215                 ret = componentsUtils.getResponseFormatByGroupType(actionStatus, (GroupTypeDefinition) elementTypeDefinition);
216                 break;
217             case POLICY_TYPE:
218                 ret = componentsUtils.getResponseFormatByPolicyType(actionStatus, (PolicyTypeDefinition) elementTypeDefinition);
219                 break;
220             case DATA_TYPE:
221                 ret = componentsUtils.getResponseFormatByDataType(actionStatus, (DataTypeDefinition) elementTypeDefinition, null);
222                 break;
223             case CAPABILITY_TYPE:
224                 ret = componentsUtils.getResponseFormatByCapabilityType(actionStatus, (CapabilityTypeDefinition) elementTypeDefinition);
225                 break;
226             default:
227                 ret = componentsUtils.getResponseFormat(actionStatus);
228                 break;
229         }
230         return ret;
231     }
232
233     private <T extends ToscaDataDefinition> List<ImmutablePair<T, Boolean>> createTypesByDao(List<T> elementTypesToCreate,
234                                                                                              TypeOperations<T> typeOperations) {
235         List<ImmutablePair<T, Boolean>> createdElementTypes = new ArrayList<>();
236         for (T newTypeDefinition : elementTypesToCreate) {
237             try {
238                 String typeName = newTypeDefinition.getType();
239                 T existingDefinition = typeOperations.getLatestType(typeName);
240                 if (existingDefinition == null /*new type*/) {
241                     typeOperations.addType(newTypeDefinition);
242                 } else {
243                     if (typeOperations.isSameType(newTypeDefinition, existingDefinition)) {
244                         propertyOperation.getJanusGraphGenericDao().rollback();
245                         createdElementTypes.add(new ImmutablePair<>(newTypeDefinition, null));
246                         continue;
247                     } else {
248                         typeOperations.updateType(existingDefinition, newTypeDefinition);
249                     }
250                 }
251                 propertyOperation.getJanusGraphGenericDao().commit();
252                 createdElementTypes.add(new ImmutablePair<>(newTypeDefinition, true));
253             } catch (Exception e) {
254                 propertyOperation.getJanusGraphGenericDao().rollback();
255                 createdElementTypes.add(new ImmutablePair<>(newTypeDefinition, false));
256             }
257
258         }
259         return createdElementTypes;
260     }
261
262     protected <T> Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> createElementTypesByDao(List<T> elementTypesToCreate,
263                                                                                                   Function<T, Either<ActionStatus, ResponseFormat>> validator,
264                                                                                                   Function<T, ImmutablePair<ElementTypeEnum, String>> elementInfoGetter,
265                                                                                                   Function<String, Either<T, StorageOperationStatus>> elementFetcher,
266                                                                                                   Function<T, Either<T, StorageOperationStatus>> elementAdder,
267                                                                                                   BiFunction<T, T, Either<T, StorageOperationStatus>> elementUpgrader) {
268
269         List<ImmutablePair<T, Boolean>> createdElementTypes = new ArrayList<>();
270
271         Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> eitherResult = Either.left(createdElementTypes);
272         Iterator<T> elementTypeItr = elementTypesToCreate.iterator();
273
274         try {
275             while (elementTypeItr.hasNext()) {
276                 T elementType = elementTypeItr.next();
277                 eitherResult = handleType(elementType, validator, elementInfoGetter, elementFetcher, elementAdder, elementUpgrader)
278                     .left()
279                     .map(elem -> append(createdElementTypes, elem));
280
281                 if (eitherResult.isRight()) {
282                     break;
283                 }
284
285                 if (!elementTypeItr.hasNext()) {
286                     log.info("all {} were created successfully!!!", elementType);
287                 }
288             }
289         } catch (Exception e) {
290             eitherResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
291             throw e;
292         } finally {
293             if (eitherResult.isLeft()) {
294                 propertyOperation.getJanusGraphGenericDao().commit();
295             } else {
296                 propertyOperation.getJanusGraphGenericDao().rollback();
297             }
298         }
299
300         return eitherResult;
301     }
302
303     private <T> Either<ImmutablePair<T, Boolean>, ResponseFormat> handleType(T elementType,
304                                                                              Function<T, Either<ActionStatus, ResponseFormat>> validator,
305                                                                              Function<T, ImmutablePair<ElementTypeEnum, String>> elementInfoGetter,
306                                                                              Function<String, Either<T, StorageOperationStatus>> elementFetcher,
307                                                                              Function<T, Either<T, StorageOperationStatus>> elementAdder,
308                                                                              BiFunction<T, T, Either<T, StorageOperationStatus>> elementUpgrader) {
309
310         final ImmutablePair<ElementTypeEnum, String> elementInfo = elementInfoGetter.apply(elementType);
311         ElementTypeEnum elementTypeEnum = elementInfo.left;
312         String elementName = elementInfo.right;
313
314         Either<ActionStatus, ResponseFormat> validateElementType = validator.apply(elementType);
315         if (validateElementType.isRight()) {
316             ResponseFormat responseFormat = validateElementType.right().value();
317             log.debug("Failed in validation of element type: {}. Response is {}", elementType, responseFormat.getFormattedMessage());
318             return Either.right(responseFormat);
319         }
320
321         log.info("send {} : {} to dao for create", elementTypeEnum, elementName);
322
323         Either<T, StorageOperationStatus> findElementType = elementFetcher.apply(elementName);
324         if (findElementType.isRight()) {
325             StorageOperationStatus status = findElementType.right().value();
326             log.debug("searched {} finished with result:{}", elementTypeEnum, status);
327             if (status != StorageOperationStatus.NOT_FOUND) {
328                 ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(status, elementTypeEnum),
329                     elementTypeEnum, elementType);
330                 return Either.right(responseFormat);
331             } else {
332                 return addElementType(elementType, elementAdder, elementTypeEnum, elementName);
333             }
334         } else {
335
336             if (elementUpgrader != null) {
337                 return updateElementType(elementType, elementUpgrader, elementTypeEnum, elementName, findElementType.left().value());
338
339             } else {
340                 // mshitrit Once GroupType Versions are supported add
341                 // code here
342                 log.debug("{} : {} already exists.", elementTypeEnum, elementName);
343                 return Either.left(new ImmutablePair<>(elementType, false));
344             }
345
346         }
347     }
348
349     protected <T> Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> createElementTypesWithVersionByDao(List<T> elementTypesToCreate,
350                                                                                                              Function<T, Either<ActionStatus, ResponseFormat>> validator,
351                                                                                                              Function<T, ImmutablePair<ElementTypeEnum, String>> elementInfoGetter,
352                                                                                                              BiFunction<String, String, Either<T, StorageOperationStatus>> elementFetcher,
353                                                                                                              Function<T, Either<T, StorageOperationStatus>> elementAdder,
354                                                                                                              BiFunction<T, T, Either<T, StorageOperationStatus>> elementUpgrader,
355                                                                                                              String modelName) {
356
357         List<ImmutablePair<T, Boolean>> createdElementTypes = new ArrayList<>();
358
359         Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> eitherResult = Either.left(createdElementTypes);
360         Iterator<T> elementTypeItr = elementTypesToCreate.iterator();
361
362         try {
363             while (elementTypeItr.hasNext()) {
364                 T elementType = elementTypeItr.next();
365                 eitherResult = handleTypeByDao(elementType, validator, elementInfoGetter, elementFetcher, elementAdder, elementUpgrader, modelName)
366                     .left()
367                     .map(elem -> append(createdElementTypes, elem));
368
369                 if (eitherResult.isRight()) {
370                     break;
371                 }
372
373                 if (!elementTypeItr.hasNext()) {
374                     log.info("all {} were created successfully!!!", elementType);
375                 }
376             }
377         } catch (Exception e) {
378             eitherResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
379             throw e;
380         } finally {
381             if (eitherResult.isLeft()) {
382                 propertyOperation.getJanusGraphGenericDao().commit();
383             } else {
384                 propertyOperation.getJanusGraphGenericDao().rollback();
385             }
386         }
387
388         return eitherResult;
389     }
390
391     private <T> Either<ImmutablePair<T, Boolean>, ResponseFormat> handleTypeByDao(T elementType,
392                                                                                   Function<T, Either<ActionStatus, ResponseFormat>> validator,
393                                                                                   Function<T, ImmutablePair<ElementTypeEnum, String>> elementInfoGetter,
394                                                                                   BiFunction<String, String, Either<T, StorageOperationStatus>> elementFetcher,
395                                                                                   Function<T, Either<T, StorageOperationStatus>> elementAdder,
396                                                                                   BiFunction<T, T, Either<T, StorageOperationStatus>> elementUpgrader,
397                                                                                   String modelName) {
398
399         final ImmutablePair<ElementTypeEnum, String> elementInfo = elementInfoGetter.apply(elementType);
400         ElementTypeEnum elementTypeEnum = elementInfo.left;
401         String elementName = elementInfo.right;
402
403         Either<ActionStatus, ResponseFormat> validateElementType = validator.apply(elementType);
404         if (validateElementType.isRight()) {
405             ResponseFormat responseFormat = validateElementType.right().value();
406             log.debug("Failed in validation of element type: {}. Response is {}", elementType, responseFormat.getFormattedMessage());
407             return Either.right(responseFormat);
408         }
409
410         log.info("send {} : {} to dao for create", elementTypeEnum, elementName);
411
412         Either<T, StorageOperationStatus> findElementType = elementFetcher.apply(elementName, modelName);
413         if (findElementType.isRight()) {
414             StorageOperationStatus status = findElementType.right().value();
415             log.debug("searched {} finished with result:{}", elementTypeEnum, status);
416             if (status != StorageOperationStatus.NOT_FOUND) {
417                 ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(status, elementTypeEnum),
418                     elementTypeEnum, elementType);
419                 return Either.right(responseFormat);
420             } else {
421                 return addElementType(elementType, elementAdder, elementTypeEnum, elementName);
422             }
423         } else {
424
425             if (elementUpgrader != null) {
426                 return updateElementType(elementType, elementUpgrader, elementTypeEnum, elementName, findElementType.left().value());
427
428             } else {
429                 // mshitrit Once GroupType Versions are supported add
430                 // code here
431                 log.debug("{} : {} already exists.", elementTypeEnum, elementName);
432                 return Either.left(new ImmutablePair<>(elementType, false));
433             }
434
435         }
436     }
437
438     private <T> Either<ImmutablePair<T, Boolean>, ResponseFormat> addElementType(T elementType,
439                                                                                  Function<T, Either<T, StorageOperationStatus>> elementAdder,
440                                                                                  ElementTypeEnum elementTypeEnum, String elementName) {
441         Either<T, StorageOperationStatus> dataModelResponse = elementAdder.apply(elementType);
442
443         if (dataModelResponse.isRight()) {
444             BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("Create {}", elementTypeEnum.name());
445             log.debug("failed to create {}: {}", elementTypeEnum, elementName);
446             if (dataModelResponse.right().value() != StorageOperationStatus.OK) {
447                 ResponseFormat responseFormat = getResponseFormatForElementType(
448                     convertFromStorageResponseForElementType(dataModelResponse.right().value(), elementTypeEnum), elementTypeEnum, elementType);
449
450                 return Either.right(responseFormat);
451             } else {
452                 return Either.left(new ImmutablePair<>(elementType, false));
453             }
454         } else {
455             log.debug("{} : {}  was created successfully.", elementTypeEnum, elementName);
456             return Either.left(new ImmutablePair<>(elementType, true));
457         }
458     }
459
460     private <T> Either<ImmutablePair<T, Boolean>, ResponseFormat> updateElementType(T elementType,
461                                                                                     BiFunction<T, T, Either<T, StorageOperationStatus>> elementUpgrader,
462                                                                                     ElementTypeEnum elementTypeEnum, String elementName,
463                                                                                     T existingElementType) {
464         Either<T, StorageOperationStatus> upgradeResponse = elementUpgrader.apply(elementType, existingElementType);
465         if (upgradeResponse.isRight()) {
466             StorageOperationStatus status = upgradeResponse.right().value();
467             if (status == StorageOperationStatus.OK) {
468                 return Either.left(new ImmutablePair<>(elementType, false));
469             } else {
470                 ResponseFormat responseFormat = getResponseFormatForElementType(
471                     convertFromStorageResponseForElementType(upgradeResponse.right().value(), elementTypeEnum), elementTypeEnum, elementType);
472                 return Either.right(responseFormat);
473             }
474         } else {
475             log.debug("{} : {}  was upgraded successfully.", elementTypeEnum, elementName);
476             return Either.left(new ImmutablePair<>(elementType, true));
477         }
478     }
479
480     public <T extends ToscaTypeDataDefinition> Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> createElementTypes(
481         ToscaTypeImportData toscaTypeImportData, BiFunction<String, String, Either<List<T>, ActionStatus>> elementTypeFromYmlCreater,
482         BiFunction<List<T>, String, Either<List<ImmutablePair<T, Boolean>>, ResponseFormat>> elementTypeDaoCreater, String modelName) {
483         Either<List<T>, ActionStatus> elementTypes = elementTypeFromYmlCreater.apply(toscaTypeImportData.getToscaTypesYml(), modelName);
484         return elementTypes
485             .right()
486             .map(err -> componentsUtils.getResponseFormat(err, ""))
487             .left()
488             .map(toscaTypes -> enrichTypesWithNonToscaMetadata(toscaTypes, toscaTypeImportData.getToscaTypeMetadata()))
489             .left()
490             .bind(elementTypeList -> elementTypeDaoCreater.apply(elementTypeList, modelName));
491     }
492
493     public <T extends ToscaDataDefinition> List<ImmutablePair<T, Boolean>> createElementTypes(String toscaTypesYml,
494                                                                                               BiFunction<String, Map<String, Object>, T> createApi,
495                                                                                               TypeOperations<T> typeOperations) {
496         Map<String, Object> fieldMap = convertToFieldMap(toscaTypesYml);
497         if (fieldMap == null) {
498             throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML_FILE);
499         }
500         List<T> elementTypes = createTypesFromToscaJsonMap(createApi, fieldMap);
501         return createTypesByDao(elementTypes, typeOperations);
502     }
503
504     private <T extends ToscaTypeDataDefinition> List<T> enrichTypesWithNonToscaMetadata(List<T> toscaTypes,
505                                                                                         Map<String, ToscaTypeMetadata> toscaTypeMetadata) {
506         return toscaTypes.stream()
507             .map(toscaType -> setNonToscaMetaDataOnType(toscaTypeMetadata, toscaType))
508             .collect(toList());
509     }
510
511     private <T extends ToscaTypeDataDefinition> T setNonToscaMetaDataOnType(Map<String, ToscaTypeMetadata> toscaTypeMetadata, T toscaTypeDefinition) {
512         String toscaType = toscaTypeDefinition.getType();
513         ToscaTypeMetadata typeMetaData = toscaTypeMetadata.get(toscaType);
514         if (typeMetaData == null) {
515             log.debug("failing while trying to associate metadata for type {}. type not exist", toscaType);
516             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
517         }
518         toscaTypeDefinition.setIcon(typeMetaData.getIcon());
519         toscaTypeDefinition.setName(typeMetaData.getDisplayName());
520         return toscaTypeDefinition;
521     }
522
523     public <T> Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> createElementTypes(String elementTypesYml,
524                                                                                           Function<String, Either<List<T>, ActionStatus>> elementTypeFromYmlCreater,
525                                                                                           Function<List<T>, Either<List<ImmutablePair<T, Boolean>>, ResponseFormat>> elementTypeDaoCreater,
526                                                                                           ElementTypeEnum elementTypeEnum) {
527
528         Either<List<T>, ActionStatus> elementTypes = elementTypeFromYmlCreater.apply(elementTypesYml);
529         if (elementTypes.isRight()) {
530             ActionStatus status = elementTypes.right().value();
531             ResponseFormat responseFormat = getResponseFormatForElementType(status, elementTypeEnum, null);
532             return Either.right(responseFormat);
533         }
534         return elementTypeDaoCreater.apply(elementTypes.left().value());
535
536     }
537
538     public void addTypesToDefaultImports(final ElementTypeEnum elementTypeEnum, final String typesYaml, final String modelName) {
539         modelOperation.addTypesToDefaultImports(elementTypeEnum, typesYaml, modelName);
540     }
541
542     public interface ICreateElementType<T1, T2, T3> {
543
544         T3 createElement(T1 firstArg, T2 secondArg);
545     }
546 }