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