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