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