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