Sync Integ to Master
[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  */
20
21 package org.openecomp.sdc.be.components.impl;
22
23 import fj.data.Either;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
26 import org.openecomp.sdc.be.config.BeEcompErrorManager;
27 import org.openecomp.sdc.be.dao.api.ActionStatus;
28 import org.openecomp.sdc.be.impl.ComponentsUtils;
29 import org.openecomp.sdc.be.model.*;
30 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
31 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
32 import org.openecomp.sdc.exception.ResponseFormat;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.springframework.stereotype.Component;
36 import org.yaml.snakeyaml.Yaml;
37
38 import javax.annotation.Resource;
39 import java.util.ArrayList;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Map.Entry;
44 import java.util.function.BiFunction;
45 import java.util.function.Consumer;
46 import java.util.function.Function;
47 import java.util.stream.Collectors;
48
49 @Component("commonImportManager")
50 public class CommonImportManager {
51
52     private static final Logger log = LoggerFactory.getLogger(CommonImportManager.class);
53
54     @Resource
55     private ComponentsUtils componentsUtils;
56     @Resource
57     private PropertyOperation propertyOperation;
58
59     protected void setProperties(Map<String, Object> toscaJson, Consumer<List<PropertyDefinition>> consumer) {
60         consumer.accept(getProperties(toscaJson));
61     }
62
63     private List<PropertyDefinition> getProperties(Map<String, Object> toscaJson) {
64         List<PropertyDefinition> values = null;
65         Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils.getProperties(toscaJson);
66
67         if (properties.isLeft()) {
68             values = new ArrayList<>();
69             Map<String, PropertyDefinition> propertiesMap = properties.left().value();
70             if (propertiesMap != null && propertiesMap.isEmpty() == false) {
71
72                 for (Entry<String, PropertyDefinition> entry : propertiesMap.entrySet()) {
73                     String propName = entry.getKey();
74                     PropertyDefinition propertyDefinition = entry.getValue();
75                     PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition);
76                     newPropertyDefinition.setName(propName);
77                     values.add(newPropertyDefinition);
78                 }
79             }
80         }
81
82         return values;
83     }
84
85     protected void setPropertiesMap(Map<String, Object> toscaJson, Consumer<Map<String, PropertyDefinition>> consumer) {
86         final List<PropertyDefinition> properties = getProperties(toscaJson);
87         if (properties != null) {
88             Map<String, PropertyDefinition> collect = properties.stream().collect(Collectors.toMap(e -> e.getName(), e -> e));
89             consumer.accept(collect);
90         }
91
92     }
93
94     interface ICreateElementType<T1, T2, ElementType> {
95         ElementType createElement(T1 firstArg, T2 secondArg);
96     }
97
98     protected <ElementDefinition> Either<List<ElementDefinition>, ActionStatus> createElementTypesFromYml(String elementTypesYml, ICreateElementType<String, Map<String, Object>, ElementDefinition> createApi) {
99
100         List<ElementDefinition> elementTypes = new ArrayList<>();
101         try {
102             Map<String, Object> toscaJson = (Map<String, Object>) new Yaml().load(elementTypesYml);
103
104             elementTypes = createElementTypesFromToscaJsonMap(createApi, toscaJson);
105         } catch (Exception e) {
106             log.debug("Failed to yaml file {}", elementTypesYml, e);
107             return Either.right(ActionStatus.INVALID_YAML_FILE);
108         }
109         return Either.left(elementTypes);
110     }
111
112         /**
113          * @param createApi * @param createApi
114          * @param elementTypes
115          * @param toscaJson
116          */
117     protected <ElementDefinition> List<ElementDefinition> createElementTypesFromToscaJsonMap(
118                 ICreateElementType<String, Map<String, Object>, ElementDefinition> createApi, Map<String, Object> toscaJson) {
119         List<ElementDefinition> elementTypes = new ArrayList<>();
120         
121         Iterator<Entry<String, Object>> elementTypesEntryItr = toscaJson.entrySet().iterator();
122         while (elementTypesEntryItr.hasNext()) {
123             Entry<String, Object> elementTypeNameDataEntry = elementTypesEntryItr.next();
124             String elementTypeName = elementTypeNameDataEntry.getKey();
125             Map<String, Object> elementTypeJsonData = (Map<String, Object>) elementTypeNameDataEntry.getValue();
126             ElementDefinition elementDefinition = createApi.createElement(elementTypeName, elementTypeJsonData);
127             elementTypes.add(elementDefinition);
128         }
129         return elementTypes;
130     }
131
132     protected <FieldType> void setField(Map<String, Object> toscaJson, String fieldName, Consumer<FieldType> setter) {
133         if (toscaJson.containsKey(fieldName)) {
134             FieldType fieldValue = (FieldType) toscaJson.get(fieldName);
135             setter.accept(fieldValue);
136         }
137
138     }
139
140     public enum ElementTypeEnum {
141         PolicyType, GroupType, DataType, CapabilityType, InterfaceLifecycleType
142     };
143
144     private ActionStatus convertFromStorageResponseForElementType(StorageOperationStatus status, ElementTypeEnum elementTypeEnum) {
145         ActionStatus ret;
146         switch (elementTypeEnum) {
147         case GroupType:
148             ret = componentsUtils.convertFromStorageResponseForGroupType(status);
149             break;
150         case DataType:
151             ret = componentsUtils.convertFromStorageResponseForDataType(status);
152             break;
153         case CapabilityType:
154             ret = componentsUtils.convertFromStorageResponseForCapabilityType(status);
155             break;
156         case InterfaceLifecycleType:
157             ret = componentsUtils.convertFromStorageResponseForLifecycleType(status);
158             break;
159         default:
160             ret = componentsUtils.convertFromStorageResponse(status);
161             break;
162         }
163         return ret;
164     }
165
166     private <ElementTypeDefinition> ResponseFormat getResponseFormatForElementType(ActionStatus actionStatus, ElementTypeEnum elementTypeEnum, ElementTypeDefinition elementTypeDefinition) {
167         ResponseFormat ret;
168         switch (elementTypeEnum) {
169         case GroupType:
170             ret = componentsUtils.getResponseFormatByGroupType(actionStatus, (GroupTypeDefinition) elementTypeDefinition);
171             break;
172         case PolicyType:
173             ret = componentsUtils.getResponseFormatByPolicyType(actionStatus, (PolicyTypeDefinition) elementTypeDefinition);
174             break;
175         case DataType:
176             ret = componentsUtils.getResponseFormatByDataType(actionStatus, (DataTypeDefinition) elementTypeDefinition, null);
177             break;
178         case CapabilityType:
179             ret = componentsUtils.getResponseFormatByCapabilityType(actionStatus, (CapabilityTypeDefinition) elementTypeDefinition);
180             break;
181
182         default:
183             ret = componentsUtils.getResponseFormat(actionStatus);
184             break;
185         }
186         return ret;
187     }
188
189     protected <ElementTypeDefinition> Either<List<ImmutablePair<ElementTypeDefinition, Boolean>>, ResponseFormat> createElementTypesByDao(List<ElementTypeDefinition> elementTypesToCreate,
190             Function<ElementTypeDefinition, Either<ActionStatus, ResponseFormat>> validator, Function<ElementTypeDefinition, ImmutablePair<ElementTypeEnum, String>> elementInfoGetter,
191             Function<String, Either<ElementTypeDefinition, StorageOperationStatus>> elementFetcher, Function<ElementTypeDefinition, Either<ElementTypeDefinition, StorageOperationStatus>> elementAdder,
192             BiFunction<ElementTypeDefinition, ElementTypeDefinition, Either<ElementTypeDefinition, StorageOperationStatus>> elementUpgrader) {
193
194         List<ImmutablePair<ElementTypeDefinition, Boolean>> createdElementTypes = new ArrayList<>();
195
196         Either<List<ImmutablePair<ElementTypeDefinition, Boolean>>, ResponseFormat> eitherResult = Either.left(createdElementTypes);
197
198         Iterator<ElementTypeDefinition> elementTypeItr = elementTypesToCreate.iterator();
199
200         try {
201
202             while (elementTypeItr.hasNext()) {
203                 ElementTypeDefinition elementType = elementTypeItr.next();
204                 final ImmutablePair<ElementTypeEnum, String> elementInfo = elementInfoGetter.apply(elementType);
205                 ElementTypeEnum elementTypeEnum = elementInfo.left;
206                 String elementName = elementInfo.right;
207
208                 Either<ActionStatus, ResponseFormat> validateElementType = validator.apply(elementType);
209                 if (validateElementType.isRight()) {
210                     ResponseFormat responseFormat = validateElementType.right().value();
211                     log.debug("Failed in validation of element type: {}. Response is {}", elementType, responseFormat.getFormattedMessage());
212                     eitherResult = Either.right(responseFormat);
213                     break;
214                 }
215
216                 log.info("send {} : {} to dao for create", elementTypeEnum, elementName);
217
218                 Either<ElementTypeDefinition, StorageOperationStatus> findElementType = elementFetcher.apply(elementName);
219                 if (findElementType.isRight()) {
220                     StorageOperationStatus status = findElementType.right().value();
221                     log.debug("searched {} finished with result:{}", elementTypeEnum, status.name());
222                     if (status != StorageOperationStatus.NOT_FOUND) {
223                         ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(status, elementTypeEnum), elementTypeEnum, elementType);
224                         eitherResult = Either.right(responseFormat);
225                         break;
226                     } else {
227                         Either<ElementTypeDefinition, StorageOperationStatus> dataModelResponse = elementAdder.apply(elementType);
228
229                         if (dataModelResponse.isRight()) {
230                             try {
231                                 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("Create {}", elementTypeEnum.name());
232                                 log.debug("failed to create {}: {}", elementTypeEnum, elementName);
233                                 if (dataModelResponse.right().value() != StorageOperationStatus.SCHEMA_VIOLATION) {
234                                     ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(dataModelResponse.right().value(), elementTypeEnum), elementTypeEnum, elementType);
235
236                                     eitherResult = Either.right(responseFormat);
237                                     break;
238                                 } else {
239                                     createdElementTypes.add(new ImmutablePair<ElementTypeDefinition, Boolean>(elementType, false));
240                                 }
241                             } finally {
242                                 propertyOperation.getTitanGenericDao().rollback();
243                             }
244                         } else {
245                             propertyOperation.getTitanGenericDao().commit();
246                             createdElementTypes.add(new ImmutablePair<ElementTypeDefinition, Boolean>(elementType, true));
247                             log.debug("{} : {}  was created successfully.", elementTypeEnum, elementName);
248                         }
249                         if (!elementTypeItr.hasNext()) {
250                             log.info("all {} were created successfully!!!", elementTypeEnum);
251                         }
252
253                     }
254                 } else {
255
256                     if (elementUpgrader != null) {
257                         Either<ElementTypeDefinition, StorageOperationStatus> upgradeResponse = null;
258                         try {
259                             upgradeResponse = elementUpgrader.apply(elementType, findElementType.left().value());
260                             if (upgradeResponse.isRight()) {
261                                 StorageOperationStatus status = upgradeResponse.right().value();
262                                 if (status == StorageOperationStatus.OK) {
263                                     createdElementTypes.add(new ImmutablePair<ElementTypeDefinition, Boolean>(elementType, false));
264                                 } else {
265                                     ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(upgradeResponse.right().value(), elementTypeEnum), elementTypeEnum, elementType);
266                                     eitherResult = Either.right(responseFormat);
267                                     break;
268                                 }
269                             } else {
270                                 log.debug("{} : {}  was upgraded successfully.", elementTypeEnum, elementName);
271                                 createdElementTypes.add(new ImmutablePair<ElementTypeDefinition, Boolean>(elementType, true));
272                             }
273                         } finally {
274                             if (upgradeResponse == null || upgradeResponse.isRight()) {
275                                 propertyOperation.getTitanGenericDao().rollback();
276                             } else {
277                                 propertyOperation.getTitanGenericDao().commit();
278                             }
279                         }
280
281                     } else {
282                         // mshitrit Once GroupType Versions are supported add
283                         // code here
284                         createdElementTypes.add(new ImmutablePair<ElementTypeDefinition, Boolean>(elementType, false));
285                         log.debug("{} : {} already exists.", elementTypeEnum, elementName);
286                     }
287
288                 }
289
290             }
291         } finally {
292             if (eitherResult.isRight()) {
293                 propertyOperation.getTitanGenericDao().rollback();
294             }
295         }
296
297         return eitherResult;
298
299     }
300
301     public <ElementTypeDefinition> Either<List<ImmutablePair<ElementTypeDefinition, Boolean>>, ResponseFormat> createElementTypes(String elementTypesYml, Function<String, Either<List<ElementTypeDefinition>, ActionStatus>> elementTypeFromYmlCreater,
302             Function<List<ElementTypeDefinition>, Either<List<ImmutablePair<ElementTypeDefinition, Boolean>>, ResponseFormat>> elementTypeDaoCreater, ElementTypeEnum elementTypeEnum) {
303
304         Either<List<ElementTypeDefinition>, ActionStatus> elementTypes = elementTypeFromYmlCreater.apply(elementTypesYml);
305         if (elementTypes.isRight()) {
306             ActionStatus status = elementTypes.right().value();
307             ResponseFormat responseFormat = getResponseFormatForElementType(status, elementTypeEnum, null);
308             return Either.right(responseFormat);
309         }
310         return elementTypeDaoCreater.apply(elementTypes.left().value());
311
312     }
313 }