Support for Test Topology Auto Design- Service Import
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ResourceImportManager.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
23 package org.openecomp.sdc.be.components.impl;
24
25 import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE;
26 import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaElementOperation.createDataType;
27 import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaElementOperation.createDataTypeDefinitionWithName;
28 import static org.openecomp.sdc.be.utils.TypeUtils.setField;
29
30 import fj.data.Either;
31 import java.util.Collections;
32 import java.util.LinkedHashMap;
33 import org.apache.commons.codec.binary.Base64;
34 import org.apache.commons.collections4.CollectionUtils;
35 import org.apache.commons.collections4.MapUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.apache.commons.lang3.tuple.ImmutablePair;
38 import org.openecomp.sdc.be.auditing.api.AuditEventFactory;
39 import org.openecomp.sdc.be.auditing.impl.AuditingManager;
40 import org.openecomp.sdc.be.auditing.impl.resourceadmin.AuditImportResourceAdminEventFactory;
41 import org.openecomp.sdc.be.components.csar.CsarInfo;
42 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
43 import org.openecomp.sdc.be.components.impl.ImportUtils.Constants;
44 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
45 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
46 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
47 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
48 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
49 import org.openecomp.sdc.be.config.BeEcompErrorManager;
50 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
51 import org.openecomp.sdc.be.dao.api.ActionStatus;
52 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
53 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
54 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
55 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
56 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
57 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
58 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
59 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
60 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
61 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
62 import org.openecomp.sdc.be.impl.ComponentsUtils;
63 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
64 import org.openecomp.sdc.be.model.ArtifactDefinition;
65 import org.openecomp.sdc.be.model.AttributeDefinition;
66 import org.openecomp.sdc.be.model.CapabilityDefinition;
67 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
68 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
69 import org.openecomp.sdc.be.model.DataTypeDefinition;
70 import org.openecomp.sdc.be.model.InterfaceDefinition;
71 import org.openecomp.sdc.be.model.LifecycleStateEnum;
72 import org.openecomp.sdc.be.model.PropertyDefinition;
73 import org.openecomp.sdc.be.model.RequirementDefinition;
74 import org.openecomp.sdc.be.model.Resource;
75 import org.openecomp.sdc.be.model.UploadResourceInfo;
76 import org.openecomp.sdc.be.model.User;
77 import org.openecomp.sdc.be.model.category.CategoryDefinition;
78 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
79 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
80 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
81 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
82 import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation;
83 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
84 import org.openecomp.sdc.be.resources.data.auditing.model.CommonAuditData;
85 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
86 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
87 import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil;
88 import org.openecomp.sdc.be.utils.TypeUtils;
89 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
90 import org.openecomp.sdc.common.log.wrappers.Logger;
91 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
92 import org.openecomp.sdc.common.util.ValidationUtils;
93 import org.openecomp.sdc.exception.ResponseFormat;
94 import org.springframework.beans.factory.annotation.Autowired;
95 import org.springframework.stereotype.Component;
96 import org.springframework.web.context.WebApplicationContext;
97 import org.yaml.snakeyaml.Yaml;
98
99 import javax.servlet.ServletContext;
100 import java.util.ArrayList;
101 import java.util.Arrays;
102 import java.util.HashMap;
103 import java.util.HashSet;
104 import java.util.Iterator;
105 import java.util.List;
106 import java.util.Map;
107 import java.util.Map.Entry;
108 import java.util.Set;
109 import java.util.function.Function;
110 import java.util.regex.Pattern;
111 import java.util.stream.Collectors;
112
113 @Component("resourceImportManager")
114 public class ResourceImportManager {
115
116     private static final Logger log = Logger.getLogger(ResourceImportManager.class);
117
118     static final Pattern PROPERTY_NAME_PATTERN_IGNORE_LENGTH = Pattern.compile("[\\w\\-\\_\\d\\:]+");
119     private static final String IMPLEMENTATION = "implementation";
120     private static final String INPUTS = "inputs";
121     private static final String TYPE = "type";
122     private static final String DESCRIPTION = "description";
123     private static final String REQUIRED = "required";
124     private static final String DEFAULT = "default";
125     private static final String STATUS = "status";
126
127     private ServletContext servletContext;
128
129     private AuditingManager auditingManager;
130     private ResourceBusinessLogic resourceBusinessLogic;
131     public ServiceBusinessLogic getServiceBusinessLogic() {
132         return serviceBusinessLogic;
133     }
134
135     public void setServiceBusinessLogic(ServiceBusinessLogic serviceBusinessLogic) {
136         this.serviceBusinessLogic = serviceBusinessLogic;
137     }
138
139     @Autowired
140     private ServiceBusinessLogic serviceBusinessLogic;
141     private InterfaceOperationBusinessLogic interfaceOperationBusinessLogic;
142
143     private IGraphLockOperation graphLockOperation;
144     private ToscaOperationFacade toscaOperationFacade;
145
146     private final ComponentsUtils componentsUtils;
147     private final CapabilityTypeOperation capabilityTypeOperation;
148
149     private ResponseFormatManager responseFormatManager;
150
151     @Autowired
152     public ResourceImportManager(ComponentsUtils componentsUtils, CapabilityTypeOperation capabilityTypeOperation) {
153         this.componentsUtils = componentsUtils;
154         this.capabilityTypeOperation = capabilityTypeOperation;
155     }
156
157     @Autowired
158     public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
159         this.toscaOperationFacade = toscaOperationFacade;
160     }
161
162     public ImmutablePair<Resource, ActionStatus> importNormativeResource(String resourceYml,
163                                                                          UploadResourceInfo resourceMetaData,
164                                                                          User creator, boolean createNewVersion,
165                                                                          boolean needLock) {
166
167         LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction();
168         lifecycleChangeInfo.setUserRemarks("certification on import");
169         Function<Resource, Boolean> validator = resource -> resourceBusinessLogic
170             .validatePropertiesDefaultValues(resource);
171
172         return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, false,
173             createNewVersion, needLock, null, null, false, null, null, false);
174     }
175
176     public ImmutablePair<Resource, ActionStatus> importNormativeResourceFromCsar(String resourceYml,
177                                                                                  UploadResourceInfo resourceMetaData,
178                                                                                  User creator, boolean createNewVersion,
179                                                                                  boolean needLock) {
180
181         LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction();
182         lifecycleChangeInfo.setUserRemarks("certification on import");
183         Function<Resource, Boolean> validator = resource -> resourceBusinessLogic
184             .validatePropertiesDefaultValues(resource);
185
186         return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, false,
187             createNewVersion, needLock, null, null, false, null, null, false);
188     }
189
190     public ImmutablePair<Resource, ActionStatus> importCertifiedResource(String resourceYml,
191                                                                          UploadResourceInfo resourceMetaData,
192                                                                          User creator,
193                                                                          Function<Resource, Boolean> validationFunction,
194                                                                          LifecycleChangeInfoWithAction lifecycleChangeInfo,
195                                                                          boolean isInTransaction,
196                                                                          boolean createNewVersion, boolean needLock,
197                                                                          Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
198                                                                          List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
199                                                                          boolean forceCertificationAllowed,
200                                                                          CsarInfo csarInfo, String nodeName,
201                                                                          boolean isNested) {
202         Resource resource = new Resource();
203         ImmutablePair<Resource, ActionStatus> responsePair = new ImmutablePair<>(resource, ActionStatus.CREATED);
204         Either<ImmutablePair<Resource, ActionStatus>, ResponseFormat> response = Either.left(responsePair);
205
206         String latestCertifiedResourceId = null;
207         try {
208             boolean shouldBeCertified = nodeTypeArtifactsToHandle == null || nodeTypeArtifactsToHandle.isEmpty();
209             setConstantMetaData(resource, shouldBeCertified);
210             setMetaDataFromJson(resourceMetaData, resource);
211
212             populateResourceFromYaml(resourceYml, resource);
213
214             Boolean isValidResource = validationFunction.apply(resource);
215             if (!createNewVersion) {
216                 Either<Resource, StorageOperationStatus> latestByName = toscaOperationFacade
217                     .getLatestByName(resource.getName());
218                 if (latestByName.isLeft()) {
219                     throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST,
220                         resource.getName());
221                 }
222             }
223             resource = resourceBusinessLogic
224                 .createOrUpdateResourceByImport(resource, creator, true, isInTransaction, needLock, csarInfo, nodeName,
225                     isNested).left;
226             Resource changeStateResponse;
227
228             if (nodeTypeArtifactsToHandle != null && !nodeTypeArtifactsToHandle.isEmpty()) {
229                 Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes =
230                     resourceBusinessLogic
231                         .handleNodeTypeArtifacts(resource, nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts,
232                             creator, isInTransaction, false);
233                 if (handleNodeTypeArtifactsRes.isRight()) {
234                     //TODO: should be used more correct action
235                     throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
236                 }
237             }
238             latestCertifiedResourceId = getLatestCertifiedResourceId(resource);
239             changeStateResponse = resourceBusinessLogic
240                 .propagateStateToCertified(creator, resource, lifecycleChangeInfo, isInTransaction, needLock,
241                     forceCertificationAllowed);
242             responsePair = new ImmutablePair<>(changeStateResponse, response.left()
243                 .value().right);
244         } catch (RuntimeException e) {
245             handleImportResourceException(resourceMetaData, creator, true, e);
246         } finally {
247             if (latestCertifiedResourceId != null && needLock) {
248                 log.debug("unlock resource {}", latestCertifiedResourceId);
249                 graphLockOperation.unlockComponent(latestCertifiedResourceId, NodeTypeEnum.Resource);
250             }
251         }
252
253         return responsePair;
254     }
255
256     private ResponseFormat getResponseFormatFromComponentException(RuntimeException e) {
257         if (e instanceof ComponentException) {
258             return ((ComponentException) e).getResponseFormat() == null ?
259                 componentsUtils
260                     .getResponseFormat(((ComponentException) e).getActionStatus(), ((ComponentException) e).getParams())
261                 :
262                 ((ComponentException) e).getResponseFormat();
263         }
264         return null;
265     }
266
267     private String getLatestCertifiedResourceId(Resource resource) {
268         Map<String, String> allVersions = resource.getAllVersions();
269         Double latestCertifiedVersion = 0.0;
270         if (allVersions != null) {
271             for (String version : allVersions.keySet()) {
272                 Double dVersion = Double.valueOf(version);
273                 if ((dVersion > latestCertifiedVersion) && (version.endsWith(".0"))) {
274                     latestCertifiedVersion = dVersion;
275                 }
276             }
277             return allVersions.get(String.valueOf(latestCertifiedVersion));
278         } else {
279             return null;
280         }
281     }
282
283     public void populateResourceMetadata(UploadResourceInfo resourceMetaData, Resource resource) {
284         if (resource != null && resourceMetaData != null) {
285             resource.setDescription(resourceMetaData.getDescription());
286             resource.setTags(resourceMetaData.getTags());
287             resource.setCategories(resourceMetaData.getCategories());
288             resource.setContactId(resourceMetaData.getContactId());
289             resource.setName(resourceMetaData.getName());
290             resource.setIcon(resourceMetaData.getResourceIconPath());
291             resource.setResourceVendorModelNumber(resourceMetaData.getResourceVendorModelNumber());
292             resource.setResourceType(ResourceTypeEnum.valueOf(resourceMetaData.getResourceType()));
293             if (resourceMetaData.getVendorName() != null) {
294                 resource.setVendorName(resourceMetaData.getVendorName());
295             }
296             if (resourceMetaData.getVendorRelease() != null) {
297                 resource.setVendorRelease(resourceMetaData.getVendorRelease());
298             }
299         }
300     }
301
302     public ImmutablePair<Resource, ActionStatus> importUserDefinedResource(String resourceYml,
303                                                                            UploadResourceInfo resourceMetaData,
304                                                                            User creator, boolean isInTransaction) {
305
306         Resource resource = new Resource();
307         ImmutablePair<Resource, ActionStatus> responsePair = new ImmutablePair<>(resource, ActionStatus.CREATED);
308
309         try {
310             setMetaDataFromJson(resourceMetaData, resource);
311
312             populateResourceFromYaml(resourceYml, resource);
313
314             // currently import VF isn't supported. In future will be supported
315             // import VF only with CSAR file!!
316             if (ResourceTypeEnum.VF == resource.getResourceType()) {
317                 log.debug("Now import VF isn't supported. It will be supported in future with CSAR file only");
318                 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
319             }
320
321             resourceBusinessLogic.validateDerivedFromNotEmpty(creator, resource, AuditingActionEnum.CREATE_RESOURCE);
322             Boolean validatePropertiesTypes = resourceBusinessLogic.validatePropertiesDefaultValues(resource);
323
324             responsePair = resourceBusinessLogic.createOrUpdateResourceByImport(resource, creator,
325                 false, isInTransaction, true, null, null, false);
326
327         } catch (RuntimeException e) {
328             handleImportResourceException(resourceMetaData, creator, false, e);
329         }
330         return responsePair;
331
332     }
333
334     private void populateResourceFromYaml(String resourceYml, Resource resource) {
335         @SuppressWarnings("unchecked")
336         Object ymlObj = new Yaml().load(resourceYml);
337         if (ymlObj instanceof Map) {
338             Map<String, Object> toscaJsonAll = (Map<String, Object>) ymlObj;
339             Map<String, Object> toscaJson = toscaJsonAll;
340
341             // Checks if exist and builds the node_types map
342             if (toscaJsonAll.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName())
343                 && resource.getResourceType() != ResourceTypeEnum.CVFC) {
344                 toscaJson = new HashMap<>();
345                 toscaJson.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(),
346                     toscaJsonAll.get(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName()));
347             }
348             final List<Object> foundElements = new ArrayList<>();
349             final Either<List<Object>, ResultStatusEnum> toscaElements = ImportUtils.findToscaElements(toscaJsonAll,
350                 ToscaTagNamesEnum.DATA_TYPES.getElementName(), ToscaElementTypeEnum.MAP, foundElements);
351             if (toscaElements.isLeft()) {
352                 final Map<String, Object> toscaAttributes = (Map<String, Object>) foundElements.get(0);
353                 if (MapUtils.isNotEmpty(toscaAttributes)) {
354                     resource.setDataTypes(extractDataTypeFromJson(resourceBusinessLogic, toscaAttributes));
355                 }
356             }
357             // Derived From
358             Resource parentResource = setDerivedFrom(toscaJson, resource);
359             if (StringUtils.isEmpty(resource.getToscaResourceName())) {
360                 setToscaResourceName(toscaJson, resource);
361             }
362             setAttributes(toscaJson, resource);
363             setCapabilities(toscaJson, resource, parentResource);
364             setProperties(toscaJson, resource);
365             setRequirements(toscaJson, resource, parentResource);
366             setInterfaceLifecycle(toscaJson, resource);
367         } else {
368             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
369         }
370
371     }
372
373     private void setToscaResourceName(Map<String, Object> toscaJson, Resource resource) {
374         Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils
375             .findFirstToscaMapElement(toscaJson, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
376         if (toscaElement.isLeft() || toscaElement.left().value().size() == 1) {
377             String toscaResourceName = toscaElement.left().value().keySet().iterator().next();
378             resource.setToscaResourceName(toscaResourceName);
379         }
380     }
381
382     private void setInterfaceLifecycle(Map<String, Object> toscaJson, Resource resource) {
383         Either<Map<String, Object>, ResultStatusEnum> toscaInterfaces = ImportUtils
384             .findFirstToscaMapElement(toscaJson, TypeUtils.ToscaTagNamesEnum.INTERFACES);
385         if (toscaInterfaces.isLeft()) {
386             Map<String, Object> jsonInterfaces = toscaInterfaces.left().value();
387             Map<String, InterfaceDefinition> moduleInterfaces = new HashMap<>();
388             Iterator<Entry<String, Object>> interfacesNameValue = jsonInterfaces.entrySet().iterator();
389             while (interfacesNameValue.hasNext()) {
390                 Entry<String, Object> interfaceNameValue = interfacesNameValue.next();
391                 Either<InterfaceDefinition, ResultStatusEnum> eitherInterface = createModuleInterface(interfaceNameValue
392                     .getValue(), resource);
393                 if (eitherInterface.isRight()) {
394                     log.info("error when creating interface:{}, for resource:{}", interfaceNameValue.getKey(),
395                         resource.getName());
396                 } else {
397                     moduleInterfaces.put(interfaceNameValue.getKey(), eitherInterface.left().value());
398                 }
399
400             }
401             if (moduleInterfaces.size() > 0) {
402                 resource.setInterfaces(moduleInterfaces);
403             }
404         }
405     }
406
407     private Either<InterfaceDefinition, ResultStatusEnum> createModuleInterface(Object interfaceJson,
408                                                                                 Resource resource) {
409         final InterfaceDefinition interf = new InterfaceDefinition();
410         Either<InterfaceDefinition, ResultStatusEnum> result = Either.left(interf);
411
412         try {
413             if (interfaceJson instanceof String) {
414                 final String requirementJsonString = (String) interfaceJson;
415                 interf.setType(requirementJsonString);
416             } else if (interfaceJson instanceof Map && ResourceTypeEnum.VFC.equals(resource.getResourceType())) {
417                 final Map<String, Object> requirementJsonMap = (Map<String, Object>) interfaceJson;
418                 final Map<String, OperationDataDefinition> operations = new HashMap<>();
419
420                 for (final Entry<String, Object> entry : requirementJsonMap.entrySet()) {
421                     if (entryIsInterfaceType(entry)) {
422                         final String type = (String) requirementJsonMap
423                             .get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName());
424                         interf.setType(type);
425                         interf.setUniqueId(type.toLowerCase());
426                     } else if (entryContainsImplementationForAKnownOperation(entry, interf.getType())) {
427
428                         final OperationDataDefinition operation = new OperationDataDefinition();
429                         operation.setName(entry.getKey());
430
431                         final Map<?, ?> entryValue = (Map<?, ?>) entry.getValue();
432                         if (entryValue.containsKey(IMPLEMENTATION)) {
433                             operation.setImplementation(handleOperationImplementation(entry));
434                         }
435                         if (entryValue.containsKey(INPUTS)) {
436                             final Map<String, Object> interfaceInputs = (Map<String, Object>) entryValue
437                                 .get(ToscaTagNamesEnum.INPUTS.getElementName());
438                             operation.setInputs(handleInterfaceInput(interfaceInputs));
439                         }
440                         operations.put(entry.getKey(), operation);
441                     }
442                 }
443                 if (!operations.isEmpty()) {
444                     interf.setOperations(operations);
445                 }
446             } else {
447                 result = Either.right(ResultStatusEnum.GENERAL_ERROR);
448             }
449
450         } catch (Exception e) {
451             BeEcompErrorManager.getInstance().logBeSystemError("Import Resource- create interface");
452             log.debug("error when creating interface, message:{}", e.getMessage(), e);
453             result = Either.right(ResultStatusEnum.GENERAL_ERROR);
454         }
455
456         return result;
457     }
458
459     private ArtifactDataDefinition handleOperationImplementation(final Entry<String, Object> entry) {
460         final ArtifactDataDefinition implementation = new ArtifactDataDefinition();
461         final String artifactName = ((Map<String, String>) entry.getValue()).get(IMPLEMENTATION);
462         if (OperationArtifactUtil.artifactNameIsALiteralValue(artifactName)) {
463             implementation.setArtifactName(artifactName);
464         } else {
465             implementation.setArtifactName(QUOTE + artifactName + QUOTE);
466         }
467         return implementation;
468     }
469
470     private ListDataDefinition<OperationInputDefinition> handleInterfaceInput(
471         final Map<String, Object> interfaceInputs) {
472         final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>();
473         for (final Entry<String, Object> interfaceInput : interfaceInputs.entrySet()) {
474             final OperationInputDefinition operationInput = new OperationInputDefinition();
475             operationInput.setName(interfaceInput.getKey());
476             if (interfaceInput.getValue() instanceof Map) {
477                 final LinkedHashMap<String, Object> inputPropertyValue =
478                     (LinkedHashMap<String, Object>) interfaceInput.getValue();
479                 log.info("createModuleInterface: i interfaceInput.getKey() {}, {} , {}  ",
480                     interfaceInput.getKey(), inputPropertyValue.keySet(),
481                     inputPropertyValue.values());
482                 if (inputPropertyValue.get(TYPE) != null) {
483                     operationInput.setType(inputPropertyValue.get(TYPE).toString());
484                 }
485                 if (inputPropertyValue.get(DESCRIPTION) != null) {
486                     operationInput.setDescription(inputPropertyValue.get(DESCRIPTION).toString());
487                 }
488                 if (inputPropertyValue.get(REQUIRED) != null) {
489                     operationInput.setRequired(
490                         Boolean.getBoolean(inputPropertyValue.get(REQUIRED).toString()));
491                 }
492                 if (inputPropertyValue.get(DEFAULT) != null) {
493                     operationInput.setToscaDefaultValue(inputPropertyValue.get(DEFAULT).toString());
494                 }
495                 if (inputPropertyValue.get(STATUS) != null) {
496                     operationInput.setStatus(inputPropertyValue.get(STATUS).toString());
497                 }
498
499             } else if (interfaceInput.getValue() instanceof String) {
500                 final String value = (String) interfaceInput.getValue();
501                 operationInput.setDefaultValue(value);
502                 operationInput.setToscaDefaultValue(value);
503                 operationInput.setValue(value);
504             }
505             inputs.getListToscaDataDefinition().add(operationInput);
506             inputs.add(operationInput);
507         }
508         return inputs;
509     }
510
511     private boolean entryIsInterfaceType(final Entry<String, Object> entry) {
512         if(entry.getKey().equals(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) {
513             if (entry.getValue() instanceof String) {
514                 return true;
515             }
516             throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML);
517         }
518         return false;
519     }
520
521     private boolean entryContainsImplementationForAKnownOperation(final Entry<String, Object> entry,
522                                                                   final String interfaceType) {
523         if (entry.getValue() instanceof Map && ((Map<?, ?>)entry.getValue()).containsKey(IMPLEMENTATION)) {
524             if (isAKnownOperation(interfaceType, entry.getKey())){
525                 return true;
526             }
527             throw new ByActionStatusComponentException(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
528         }
529         return false;
530     }
531
532     private boolean isAKnownOperation(String interfaceType, String operation) {
533         Either<Map<String, InterfaceDefinition>, ResponseFormat> interfaceLifecycleTypes = interfaceOperationBusinessLogic
534             .getAllInterfaceLifecycleTypes();
535         if (interfaceLifecycleTypes.isRight() || interfaceLifecycleTypes.left().value() == null) {
536             return false;
537         }
538
539         for (Entry<String, InterfaceDefinition> interfaceLifecycleType : interfaceLifecycleTypes.left().value()
540             .entrySet()) {
541             if (interfaceTypeAndOperationMatches(interfaceLifecycleType, interfaceType, operation)) {
542                 return true;
543             }
544         }
545         return false;
546     }
547
548     private boolean interfaceTypeAndOperationMatches(Entry<String, InterfaceDefinition> interfaceLifecycleType,
549                                                      String interfaceType, String operation) {
550         if (interfaceLifecycleType.getKey().equalsIgnoreCase(interfaceType)
551             && interfaceLifecycleType.getValue().getOperations() != null) {
552             for (String interfaceLifecycleTypeOperation : interfaceLifecycleType.getValue().getOperations().keySet()) {
553                 if (interfaceLifecycleTypeOperation != null && interfaceLifecycleTypeOperation
554                     .equalsIgnoreCase(operation)) {
555                     return true;
556                 }
557             }
558         }
559         return false;
560     }
561
562     private void setRequirements(Map<String, Object> toscaJson, Resource resource,
563                                  Resource parentResource) {// Note that parentResource can be null
564         Either<List<Object>, ResultStatusEnum> toscaRequirements = ImportUtils
565             .findFirstToscaListElement(toscaJson, TypeUtils.ToscaTagNamesEnum.REQUIREMENTS);
566         if (toscaRequirements.isLeft()) {
567             List<Object> jsonRequirements = toscaRequirements.left().value();
568             Map<String, List<RequirementDefinition>> moduleRequirements = new HashMap<>();
569             // Checking for name duplication
570             Set<String> reqNames = new HashSet<>();
571             // Getting flattened list of capabilities of parent node - cap name
572             // to cap type
573             Map<String, String> reqName2TypeMap = getReqName2Type(parentResource);
574             for (Object jsonRequirementObj : jsonRequirements) {
575                 // Requirement
576                 Map<String, Object> requirementJsonWrapper = (Map<String, Object>) jsonRequirementObj;
577                 String requirementName = requirementJsonWrapper.keySet().iterator().next();
578                 String reqNameLowerCase = requirementName.toLowerCase();
579                 if (reqNames.contains(reqNameLowerCase)) {
580                     log.debug(
581                         "More than one requirement with same name {} (case-insensitive) in imported TOSCA file is invalid",
582                         reqNameLowerCase);
583                     throw new ByActionStatusComponentException(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME,
584                         "requirement", reqNameLowerCase);
585                 }
586                 reqNames.add(reqNameLowerCase);
587                 RequirementDefinition requirementDef = createRequirementFromImportFile(requirementJsonWrapper
588                     .get(requirementName));
589                 requirementDef.setName(requirementName);
590                 if (moduleRequirements.containsKey(requirementDef.getCapability())) {
591                     moduleRequirements.get(requirementDef.getCapability()).add(requirementDef);
592                 } else {
593                     List<RequirementDefinition> list = new ArrayList<>();
594                     list.add(requirementDef);
595                     moduleRequirements.put(requirementDef.getCapability(), list);
596                 }
597
598                 // Validating against req/cap of "derived from" node
599                 Boolean validateVsParentCap = validateCapNameVsDerived(reqName2TypeMap, requirementDef
600                     .getCapability(), requirementDef.getName());
601                 if (!validateVsParentCap) {
602                     String parentResourceName = parentResource != null ? parentResource.getName() : "";
603                     log.debug("Requirement with name {} already exists in parent {}", requirementDef.getName(),
604                         parentResourceName);
605                     throw new ByActionStatusComponentException(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED,
606                         "requirement", requirementDef
607                         .getName()
608                         .toLowerCase(), parentResourceName);
609                 }
610             }
611             if (moduleRequirements.size() > 0) {
612                 resource.setRequirements(moduleRequirements);
613             }
614
615         }
616     }
617
618     private RequirementDefinition createRequirementFromImportFile(Object requirementJson) {
619         RequirementDefinition requirement = new RequirementDefinition();
620
621         if (requirementJson instanceof String) {
622             String requirementJsonString = (String) requirementJson;
623             requirement.setCapability(requirementJsonString);
624         } else if (requirementJson instanceof Map) {
625             Map<String, Object> requirementJsonMap = (Map<String, Object>) requirementJson;
626             if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.CAPABILITY.getElementName())) {
627                 requirement.setCapability(
628                     (String) requirementJsonMap.get(TypeUtils.ToscaTagNamesEnum.CAPABILITY.getElementName()));
629             }
630
631             if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.NODE.getElementName())) {
632                 requirement.setNode((String) requirementJsonMap.get(TypeUtils.ToscaTagNamesEnum.NODE.getElementName()));
633             }
634
635             if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.RELATIONSHIP.getElementName())) {
636                 requirement.setRelationship(
637                     (String) requirementJsonMap.get(TypeUtils.ToscaTagNamesEnum.RELATIONSHIP.getElementName()));
638             }
639             if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName())) {
640                 List<Object> occurrencesList = (List) requirementJsonMap
641                     .get(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName());
642                 validateOccurrences(occurrencesList);
643                 requirement.setMinOccurrences(occurrencesList.get(0).toString());
644                 requirement.setMaxOccurrences(occurrencesList.get(1).toString());
645             }
646         } else {
647             throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML);
648         }
649         return requirement;
650     }
651
652     private void setProperties(Map<String, Object> toscaJson, Resource resource) {
653         Map<String, Object> reducedToscaJson = new HashMap<>(toscaJson);
654         ImportUtils.removeElementFromJsonMap(reducedToscaJson, "capabilities");
655         Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils
656             .getProperties(reducedToscaJson);
657         if (properties.isLeft()) {
658             List<PropertyDefinition> propertiesList = new ArrayList<>();
659             Map<String, PropertyDefinition> value = properties.left().value();
660             if (value != null) {
661                 for (Entry<String, PropertyDefinition> entry : value.entrySet()) {
662                     String name = entry.getKey();
663                     if (!PROPERTY_NAME_PATTERN_IGNORE_LENGTH.matcher(name).matches()) {
664                         log.debug("The property with invalid name {} occured upon import resource {}. ", name,
665                             resource.getName());
666                         throw new ByActionStatusComponentException(componentsUtils
667                             .convertFromResultStatusEnum(ResultStatusEnum.INVALID_PROPERTY_NAME,
668                                 JsonPresentationFields.PROPERTY));
669                     }
670                     PropertyDefinition propertyDefinition = entry.getValue();
671                     propertyDefinition.setName(name);
672                     propertiesList.add(propertyDefinition);
673                 }
674             }
675             resource.setProperties(propertiesList);
676         } else if (properties.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND) {
677             throw new ByActionStatusComponentException(componentsUtils.convertFromResultStatusEnum(properties
678                 .right()
679                 .value(), JsonPresentationFields.PROPERTY));
680         }
681     }
682
683     private ResultStatusEnum setAttributes(Map<String, Object> toscaJson, Resource resource) {
684         ResultStatusEnum result = ResultStatusEnum.OK;
685         Either<Map<String, AttributeDataDefinition>, ResultStatusEnum> attributes = ImportUtils
686             .getAttributes(toscaJson);
687         if (attributes.isLeft()) {
688             List<AttributeDataDefinition> attributeList = new ArrayList<>();
689             Map<String, AttributeDataDefinition> value = attributes.left().value();
690             if (value != null) {
691                 for (Entry<String, AttributeDataDefinition> entry : value.entrySet()) {
692                     String name = entry.getKey();
693                     AttributeDataDefinition attributeDef = entry.getValue();
694                     attributeDef.setName(name);
695                     attributeList.add(attributeDef);
696                 }
697             }
698             resource.setAttributes(attributeList);
699         } else {
700             result = attributes.right().value();
701         }
702         return result;
703     }
704
705     private Resource setDerivedFrom(Map<String, Object> toscaJson, Resource resource) {
706         Either<String, ResultStatusEnum> toscaDerivedFromElement = ImportUtils
707             .findFirstToscaStringElement(toscaJson, TypeUtils.ToscaTagNamesEnum.DERIVED_FROM);
708         Resource derivedFromResource = null;
709         if (toscaDerivedFromElement.isLeft()) {
710             String derivedFrom = toscaDerivedFromElement.left().value();
711             log.debug("Derived from TOSCA name is {}", derivedFrom);
712             resource.setDerivedFrom(Arrays.asList(new String[]{derivedFrom}));
713             Either<Resource, StorageOperationStatus> latestByToscaResourceName = toscaOperationFacade
714                 .getLatestByToscaResourceName(derivedFrom);
715
716             if (latestByToscaResourceName.isRight()) {
717                 StorageOperationStatus operationStatus = latestByToscaResourceName.right().value();
718                 if (operationStatus == StorageOperationStatus.NOT_FOUND) {
719                     operationStatus = StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND;
720                 }
721                 log.debug("Error when fetching parent resource {}, error: {}", derivedFrom, operationStatus);
722                 ActionStatus convertFromStorageResponse = componentsUtils.convertFromStorageResponse(operationStatus);
723                 BeEcompErrorManager.getInstance()
724                     .logBeComponentMissingError("Import TOSCA YAML", "resource", derivedFrom);
725                 throw new ByActionStatusComponentException(convertFromStorageResponse, derivedFrom);
726             }
727             derivedFromResource = latestByToscaResourceName.left().value();
728         }
729         return derivedFromResource;
730     }
731
732     private void setCapabilities(Map<String, Object> toscaJson, Resource resource,
733                                  Resource parentResource) {// Note that parentResource can be null
734         Either<Map<String, Object>, ResultStatusEnum> toscaCapabilities = ImportUtils
735             .findFirstToscaMapElement(toscaJson, TypeUtils.ToscaTagNamesEnum.CAPABILITIES);
736         if (toscaCapabilities.isLeft()) {
737             Map<String, Object> jsonCapabilities = toscaCapabilities.left().value();
738             Map<String, List<CapabilityDefinition>> moduleCapabilities = new HashMap<>();
739             Iterator<Entry<String, Object>> capabilitiesNameValue = jsonCapabilities.entrySet().iterator();
740             Set<String> capNames = new HashSet<>();
741             // Getting flattened list of capabilities of parent node - cap name
742             // to cap type
743             Map<String, String> capName2TypeMap = getCapName2Type(parentResource);
744             while (capabilitiesNameValue.hasNext()) {
745                 Entry<String, Object> capabilityNameValue = capabilitiesNameValue.next();
746
747                 // Validating that no req/cap duplicates exist in imported YAML
748                 String capNameLowerCase = capabilityNameValue.getKey().toLowerCase();
749                 if (capNames.contains(capNameLowerCase)) {
750                     log.debug(
751                         "More than one capability with same name {} (case-insensitive) in imported TOSCA file is invalid",
752                         capNameLowerCase);
753                     throw new ByActionStatusComponentException(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME, "capability",
754                         capNameLowerCase);
755                 }
756                 capNames.add(capNameLowerCase);
757
758                 CapabilityDefinition capabilityDef = createCapabilityFromImportFile(capabilityNameValue
759                     .getValue());
760                 capabilityDef.setName(capabilityNameValue.getKey());
761                 if (moduleCapabilities.containsKey(capabilityDef.getType())) {
762                     moduleCapabilities.get(capabilityDef.getType()).add(capabilityDef);
763                 } else {
764                     List<CapabilityDefinition> list = new ArrayList<>();
765                     list.add(capabilityDef);
766                     moduleCapabilities.put(capabilityDef.getType(), list);
767                 }
768
769                 // Validating against req/cap of "derived from" node
770                 Boolean validateVsParentCap = validateCapNameVsDerived(capName2TypeMap, capabilityDef
771                     .getType(), capabilityDef.getName());
772
773                 if (!validateVsParentCap) {
774                     // Here parentResource is for sure not null, so it's
775                     // null-safe
776                     // Check added to avoid sonar warning
777                     String parentResourceName = parentResource != null ? parentResource.getName() : "";
778                     log.debug("Capability with name {} already exists in parent {}", capabilityDef.getName(),
779                         parentResourceName);
780                     throw new ByActionStatusComponentException(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED,
781                         "capability", capabilityDef
782                         .getName()
783                         .toLowerCase(), parentResourceName);
784                 }
785             }
786             if (moduleCapabilities.size() > 0) {
787                 resource.setCapabilities(moduleCapabilities);
788             }
789         }
790     }
791
792     private Map<String, String> getCapName2Type(Resource parentResource) {
793         Map<String, String> capName2type = new HashMap<>();
794         if (parentResource != null) {
795             Map<String, List<CapabilityDefinition>> capabilities = parentResource.getCapabilities();
796             if (capabilities != null) {
797                 for (List<CapabilityDefinition> capDefinitions : capabilities.values()) {
798                     for (CapabilityDefinition capDefinition : capDefinitions) {
799                         String nameLowerCase = capDefinition.getName().toLowerCase();
800                         if (capName2type.get(nameLowerCase) != null) {
801                             String parentResourceName = parentResource.getName();
802                             log.debug("Resource with name {} has more than one capability with name {}, ignoring case",
803                                 parentResourceName, nameLowerCase);
804                             BeEcompErrorManager.getInstance()
805                                 .logInternalDataError("Import resource", "Parent resource " + parentResourceName
806                                         + " of imported resource has one or more capabilities with name " + nameLowerCase,
807                                     ErrorSeverity.ERROR);
808                             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
809                         }
810                         capName2type.put(nameLowerCase, capDefinition.getType());
811                     }
812                 }
813             }
814         }
815         return capName2type;
816     }
817
818     private Map<String, String> getReqName2Type(Resource parentResource) {
819         Map<String, String> reqName2type = new HashMap<>();
820         if (parentResource != null) {
821             Map<String, List<RequirementDefinition>> requirements = parentResource.getRequirements();
822             if (requirements != null) {
823                 for (List<RequirementDefinition> reqDefinitions : requirements.values()) {
824                     for (RequirementDefinition reqDefinition : reqDefinitions) {
825                         String nameLowerCase = reqDefinition.getName().toLowerCase();
826                         if (reqName2type.get(nameLowerCase) != null) {
827                             String parentResourceName = parentResource.getName();
828                             log.debug("Resource with name {} has more than one requirement with name {}, ignoring case",
829                                 parentResourceName, nameLowerCase);
830                             BeEcompErrorManager.getInstance()
831                                 .logInternalDataError("Import resource", "Parent resource " + parentResourceName
832                                         + " of imported resource has one or more requirements with name " + nameLowerCase,
833                                     ErrorSeverity.ERROR);
834                             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
835                         }
836                         reqName2type.put(nameLowerCase, reqDefinition.getCapability());
837                     }
838                 }
839             }
840         }
841         return reqName2type;
842     }
843
844     private Boolean validateCapNameVsDerived(Map<String, String> parentCapName2Type, String childCapabilityType,
845                                              String reqCapName) {
846         String capNameLowerCase = reqCapName.toLowerCase();
847         log.trace("Validating capability {} vs parent resource", capNameLowerCase);
848         String parentCapType = parentCapName2Type.get(capNameLowerCase);
849         if (parentCapType != null) {
850             if (childCapabilityType.equals(parentCapType)) {
851                 log.debug(
852                     "Capability with name {} is of same type {} for imported resource and its parent - this is OK",
853                     capNameLowerCase, childCapabilityType);
854                 return true;
855             }
856             Either<Boolean, StorageOperationStatus> capabilityTypeDerivedFrom = capabilityTypeOperation
857                 .isCapabilityTypeDerivedFrom(childCapabilityType, parentCapType);
858             if (capabilityTypeDerivedFrom.isRight()) {
859                 log.debug("Couldn't check whether imported resource capability derives from its parent's capability");
860                 throw new ByActionStatusComponentException(
861                     componentsUtils.convertFromStorageResponse(capabilityTypeDerivedFrom
862                     .right()
863                     .value()));
864             }
865             return capabilityTypeDerivedFrom.left().value();
866         }
867         return true;
868     }
869
870     private CapabilityDefinition createCapabilityFromImportFile(Object capabilityJson) {
871
872         CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
873
874         if (capabilityJson instanceof String) {
875             String capabilityJsonString = (String) capabilityJson;
876             capabilityDefinition.setType(capabilityJsonString);
877         } else if (capabilityJson instanceof Map) {
878             Map<String, Object> capabilityJsonMap = (Map<String, Object>) capabilityJson;
879             // Type
880             if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) {
881                 capabilityDefinition
882                     .setType((String) capabilityJsonMap.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName()));
883             }
884             // ValidSourceTypes
885             if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())) {
886                 capabilityDefinition.setValidSourceTypes(
887                     (List<String>) capabilityJsonMap.get(TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES
888                     .getElementName()));
889             }
890             // ValidSourceTypes
891             if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName())) {
892                 capabilityDefinition.setDescription(
893                     (String) capabilityJsonMap.get(TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName()));
894             }
895             if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName())) {
896                 List<Object> occurrencesList = (List) capabilityJsonMap
897                     .get(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName());
898                 validateOccurrences(occurrencesList);
899                 capabilityDefinition.setMinOccurrences(occurrencesList.get(0).toString());
900                 capabilityDefinition.setMaxOccurrences(occurrencesList.get(1).toString());
901             }
902             if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.PROPERTIES.getElementName())) {
903
904                 Either<Map<String, PropertyDefinition>, ResultStatusEnum> propertiesRes = ImportUtils
905                     .getProperties(capabilityJsonMap);
906                 if (propertiesRes.isRight()) {
907                     throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND);
908                 } else {
909                     propertiesRes.left()
910                         .value()
911                         .entrySet()
912                         .stream()
913                         .forEach(e -> e.getValue().setName(e.getKey().toLowerCase()));
914                     List<ComponentInstanceProperty> capabilityProperties = propertiesRes.left()
915                         .value()
916                         .values()
917                         .stream()
918                         .map(p -> new ComponentInstanceProperty(p, p
919                             .getDefaultValue(), null))
920                         .collect(Collectors.toList());
921                     capabilityDefinition.setProperties(capabilityProperties);
922                 }
923             }
924
925         } else if (!(capabilityJson instanceof List)) {
926             throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML);
927         }
928         return capabilityDefinition;
929     }
930
931     private void handleImportResourceException(UploadResourceInfo resourceMetaData, User user, boolean isNormative,
932                                                RuntimeException e) {
933         ResponseFormat responseFormat;
934         ComponentException newException;
935         if (e instanceof ComponentException) {
936             ComponentException componentException = (ComponentException) e;
937             responseFormat = componentException.getResponseFormat();
938             if (responseFormat == null) {
939                 responseFormat = getResponseFormatManager()
940                     .getResponseFormat(componentException.getActionStatus(), componentException.getParams());
941             }
942             newException = componentException;
943         } else {
944             responseFormat = getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR);
945             newException = new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
946         }
947         String payloadName = (resourceMetaData != null) ? resourceMetaData.getPayloadName() : "";
948         BeEcompErrorManager.getInstance().logBeSystemError("Import Resource " + payloadName);
949         log.debug("Error when importing resource from payload:{} Exception text: {}", payloadName, e.getMessage(), e);
950         auditErrorImport(resourceMetaData, user, responseFormat, isNormative);
951         throw newException;
952     }
953
954     private void auditErrorImport(UploadResourceInfo resourceMetaData, User user, ResponseFormat errorResponseWrapper,
955                                   boolean isNormative) {
956         String version, lifeCycleState;
957         if (isNormative) {
958             version = TypeUtils.getFirstCertifiedVersionVersion();
959             lifeCycleState = LifecycleStateEnum.CERTIFIED.name();
960         } else {
961             version = "";
962             lifeCycleState = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name();
963
964         }
965
966         String message = "";
967         if (errorResponseWrapper.getMessageId() != null) {
968             message = errorResponseWrapper.getMessageId() + ": ";
969         }
970         message += errorResponseWrapper.getFormattedMessage();
971
972         AuditEventFactory factory = new AuditImportResourceAdminEventFactory(
973             CommonAuditData.newBuilder()
974                 .status(errorResponseWrapper.getStatus())
975                 .description(message)
976                 .requestId(ThreadLocalsHolder.getUuid())
977                 .build(),
978             new ResourceCommonInfo(resourceMetaData.getName(), ComponentTypeEnum.RESOURCE.getValue()),
979             ResourceVersionInfo.newBuilder()
980                 .state(lifeCycleState)
981                 .version(version)
982                 .build(),
983             ResourceVersionInfo.newBuilder()
984                 .state("")
985                 .version("")
986                 .build(),
987             "", user, "");
988         getAuditingManager().auditEvent(factory);
989
990     }
991
992     private void setMetaDataFromJson(final UploadResourceInfo resourceMetaData, final Resource resource) {
993         this.populateResourceMetadata(resourceMetaData, resource);
994         resource.setCreatorUserId(resourceMetaData.getContactId());
995
996         final String payloadData = resourceMetaData.getPayloadData();
997         if (payloadData != null) {
998             resource.setToscaVersion(getToscaVersion(payloadData));
999             resource.setAttributes(getAttributes(payloadData));
1000         }
1001
1002         final List<CategoryDefinition> categories = resourceMetaData.getCategories();
1003         calculateResourceIsAbstract(resource, categories);
1004     }
1005
1006     private List<AttributeDataDefinition> getAttributes(final String payloadData) {
1007         final Map<String, Object> mappedToscaTemplate = decodePayload(payloadData);
1008
1009         final List<AttributeDataDefinition> attributeDataDefinitionList = new ArrayList<>();
1010
1011         final Either<Map<String, Object>, ResultStatusEnum> firstToscaMapElement = ImportUtils
1012             .findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.ATTRIBUTES);
1013         if (firstToscaMapElement.isRight()) {
1014             return attributeDataDefinitionList;
1015         }
1016         final Map<String, Object> attributes = firstToscaMapElement.left().value();
1017
1018         final Iterator<Entry<String, Object>> propertiesNameValue = attributes.entrySet().iterator();
1019         while (propertiesNameValue.hasNext()) {
1020             final Entry<String, Object> attributeNameValue = propertiesNameValue.next();
1021             final Object value = attributeNameValue.getValue();
1022             final String key = attributeNameValue.getKey();
1023             if (value instanceof Map) {
1024
1025                 final Map<String, Object> attributeMap = (Map<String, Object>) value;
1026
1027                 final AttributeDefinition attributeDefinition = new AttributeDefinition();
1028                 attributeDefinition.setName(key);
1029
1030                 setField(attributeMap, ToscaTagNamesEnum.DESCRIPTION, attributeDefinition::setDescription);
1031                 setField(attributeMap, ToscaTagNamesEnum.TYPE, attributeDefinition::setType);
1032                 setField(attributeMap, ToscaTagNamesEnum.STATUS, attributeDefinition::setStatus);
1033                 setField(attributeMap, ToscaTagNamesEnum.ENTRY_SCHEMA, attributeDefinition::setEntry_schema);
1034                 attributeDataDefinitionList.add(attributeDefinition);
1035             } else {
1036                 final AttributeDefinition attributeDefinition = new AttributeDefinition();
1037                 attributeDefinition.setName(key);
1038                 attributeDataDefinitionList.add(attributeDefinition);
1039             }
1040         }
1041         return attributeDataDefinitionList;
1042     }
1043
1044     private Map<String, Object> decodePayload(final String payloadData) {
1045         final String decodedPayload = new String(Base64.decodeBase64(payloadData));
1046         return (Map<String, Object>) new Yaml().load(decodedPayload);
1047     }
1048
1049     private String getToscaVersion(final String payloadData) {
1050         final Map<String, Object> mappedToscaTemplate = decodePayload(payloadData);
1051         final Either<String, ResultStatusEnum> findFirstToscaStringElement =
1052             ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
1053         if (findFirstToscaStringElement.isLeft()) {
1054             return findFirstToscaStringElement.left().value();
1055         } else {
1056             return null;
1057         }
1058     }
1059
1060     private Map<String, Object> getDataTypes(final String payloadData) {
1061         final Map<String, Object> mappedToscaTemplate = decodePayload(payloadData);
1062         final Either<Map<String, Object>, ResultStatusEnum> findFirstToscaStringElement =
1063             ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.DATA_TYPES);
1064         if (findFirstToscaStringElement.isLeft()) {
1065             return findFirstToscaStringElement.left().value();
1066         } else {
1067             return Collections.EMPTY_MAP;
1068         }
1069     }
1070
1071     private void calculateResourceIsAbstract(Resource resource, List<CategoryDefinition> categories) {
1072         if (categories != null && !categories.isEmpty()) {
1073             CategoryDefinition categoryDef = categories.get(0);
1074             resource.setAbstract(false);
1075             if (categoryDef != null && categoryDef.getName() != null && categoryDef.getName()
1076                 .equals(Constants.ABSTRACT_CATEGORY_NAME)) {
1077                 SubCategoryDefinition subCategoryDef = categoryDef.getSubcategories().get(0);
1078                 if (subCategoryDef != null && subCategoryDef.getName().equals(Constants.ABSTRACT_SUBCATEGORY)) {
1079                     resource.setAbstract(true);
1080                 }
1081             }
1082         }
1083     }
1084
1085     private void setConstantMetaData(Resource resource, boolean shouldBeCertified) {
1086         String version;
1087         LifecycleStateEnum state;
1088         if (shouldBeCertified) {
1089             version = TypeUtils.getFirstCertifiedVersionVersion();
1090             state = ImportUtils.Constants.NORMATIVE_TYPE_LIFE_CYCLE;
1091         } else {
1092             version = ImportUtils.Constants.FIRST_NON_CERTIFIED_VERSION;
1093             state = ImportUtils.Constants.NORMATIVE_TYPE_LIFE_CYCLE_NOT_CERTIFIED_CHECKOUT;
1094         }
1095         resource.setVersion(version);
1096         resource.setLifecycleState(state);
1097         resource.setHighestVersion(ImportUtils.Constants.NORMATIVE_TYPE_HIGHEST_VERSION);
1098         resource.setVendorName(ImportUtils.Constants.VENDOR_NAME);
1099         resource.setVendorRelease(ImportUtils.Constants.VENDOR_RELEASE);
1100
1101     }
1102
1103     private void validateOccurrences(List<Object> occurrensesList) {
1104
1105         if (!ValidationUtils.validateListNotEmpty(occurrensesList)) {
1106             log.debug("Occurrenses list empty");
1107             throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES);
1108         }
1109
1110         if (occurrensesList.size() < 2) {
1111             log.debug("Occurrenses list size not 2");
1112             throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES);
1113         }
1114         Object minObj = occurrensesList.get(0);
1115         Object maxObj = occurrensesList.get(1);
1116         Integer minOccurrences;
1117         Integer maxOccurrences;
1118         if (minObj instanceof Integer) {
1119             minOccurrences = (Integer) minObj;
1120         } else {
1121             log.debug("Invalid occurrenses format. low_bound occurrense must be Integer {}", minObj);
1122             throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES);
1123         }
1124         if (minOccurrences < 0) {
1125             log.debug("Invalid occurrenses format.low_bound occurrense negative {}", minOccurrences);
1126             throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES);
1127         }
1128
1129         if (maxObj instanceof String) {
1130             if (!"UNBOUNDED".equals(maxObj)) {
1131                 log.debug("Invalid occurrenses format. Max occurrence is {}", maxObj);
1132                 throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES);
1133             }
1134         } else {
1135             if (maxObj instanceof Integer) {
1136                 maxOccurrences = (Integer) maxObj;
1137             } else {
1138                 log.debug("Invalid occurrenses format.  Max occurrence is {}", maxObj);
1139                 throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES);
1140             }
1141
1142             if (maxOccurrences <= 0 || maxOccurrences < minOccurrences) {
1143                 log.debug("Invalid occurrenses format.  min occurrence is {}, Max occurrence is {}", minOccurrences,
1144                     maxOccurrences);
1145                 throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES);
1146             }
1147         }
1148     }
1149
1150     public synchronized void init(ServletContext servletContext) {
1151         if (this.servletContext == null) {
1152             this.servletContext = servletContext;
1153             responseFormatManager = ResponseFormatManager.getInstance();
1154             resourceBusinessLogic = getResourceBL(servletContext);
1155         }
1156     }
1157
1158     public boolean isResourceExist(String resourceName) {
1159         return resourceBusinessLogic.isResourceExist(resourceName);
1160     }
1161
1162     private ResourceBusinessLogic getResourceBL(ServletContext context) {
1163         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
1164             .getAttribute(org.openecomp.sdc.common.api.Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
1165         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
1166         return webApplicationContext.getBean(ResourceBusinessLogic.class);
1167     }
1168
1169     public ServletContext getServletContext() {
1170         return servletContext;
1171     }
1172
1173     public AuditingManager getAuditingManager() {
1174         return auditingManager;
1175     }
1176
1177     public ResponseFormatManager getResponseFormatManager() {
1178         return responseFormatManager;
1179     }
1180
1181     public void setResponseFormatManager(ResponseFormatManager responseFormatManager) {
1182         this.responseFormatManager = responseFormatManager;
1183     }
1184
1185     public ResourceBusinessLogic getResourceBusinessLogic() {
1186         return resourceBusinessLogic;
1187     }
1188
1189     @Autowired
1190     public void setResourceBusinessLogic(ResourceBusinessLogic resourceBusinessLogic) {
1191         this.resourceBusinessLogic = resourceBusinessLogic;
1192     }
1193
1194     @Autowired
1195     public void setInterfaceOperationBusinessLogic(InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) {
1196         this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic;
1197     }
1198
1199     public IGraphLockOperation getGraphLockOperation() {
1200         return graphLockOperation;
1201     }
1202
1203     @Autowired
1204     public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
1205         this.graphLockOperation = graphLockOperation;
1206     }
1207
1208     public void setServletContext(ServletContext servletContext) {
1209         this.servletContext = servletContext;
1210     }
1211
1212     @Autowired
1213     public void setAuditingManager(AuditingManager auditingManager) {
1214         this.auditingManager = auditingManager;
1215     }
1216
1217     private List<DataTypeDefinition> extractDataTypeFromJson(final ResourceBusinessLogic resourceBusinessLogic,
1218                                                              final Map<String, Object> foundElements) {
1219         final List<DataTypeDefinition> dataTypeDefinitionList = new ArrayList<>();
1220         if (MapUtils.isNotEmpty(foundElements)) {
1221             final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeCacheAll =
1222                 resourceBusinessLogic.dataTypeCache.getAll();
1223             if (dataTypeCacheAll.isLeft()) {
1224                 for (final Entry<String, Object> attributeNameValue : foundElements.entrySet()) {
1225                     final Object value = attributeNameValue.getValue();
1226                     if (value instanceof Map) {
1227                         final DataTypeDefinition dataTypeDefinition =
1228                             createDataTypeDefinitionWithName(attributeNameValue);
1229                         final DataTypeDefinition dataTypeDefinitionParent =
1230                             dataTypeCacheAll.left().value().get(dataTypeDefinition.getDerivedFromName());
1231                         dataTypeDefinition.setDerivedFrom(dataTypeDefinitionParent);
1232
1233                         dataTypeDefinitionList.add(dataTypeDefinition);
1234                     } else {
1235                         dataTypeDefinitionList.add(createDataType(String.valueOf(value)));
1236                     }
1237                 }
1238             }
1239         }
1240         return dataTypeDefinitionList;
1241     }
1242 }