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