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