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