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