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