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