Fix check to restrict deletion for system deployed VFCs
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ResourceBusinessLogic.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 package org.openecomp.sdc.be.components.impl;
21
22 import com.google.common.annotations.VisibleForTesting;
23 import fj.data.Either;
24 import org.apache.commons.codec.binary.Base64;
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.collections.MapUtils;
27 import org.apache.commons.collections4.ListUtils;
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.commons.lang3.tuple.ImmutablePair;
30 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
31 import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic;
32 import org.openecomp.sdc.be.components.csar.CsarBusinessLogic;
33 import org.openecomp.sdc.be.components.csar.CsarInfo;
34 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
35 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
36 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
37 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
38 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
39 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
40 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
41 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
42 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
43 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
44 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
45 import org.openecomp.sdc.be.components.merge.TopologyComparator;
46 import org.openecomp.sdc.be.components.merge.property.PropertyDataValueMergeBusinessLogic;
47 import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic;
48 import org.openecomp.sdc.be.components.merge.utils.MergeInstanceUtils;
49 import org.openecomp.sdc.be.components.property.PropertyConstraintsUtils;
50 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
51 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
52 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
53 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
54 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
55 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
56 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
57 import org.openecomp.sdc.be.config.BeEcompErrorManager;
58 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
59 import org.openecomp.sdc.be.config.ConfigurationManager;
60 import org.openecomp.sdc.be.dao.api.ActionStatus;
61 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
62 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
63 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
64 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
65 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
73 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
74 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
75 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
76 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
77 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
78 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
79 import org.openecomp.sdc.be.impl.ComponentsUtils;
80 import org.openecomp.sdc.be.info.NodeTypeInfoToUpdateArtifacts;
81 import org.openecomp.sdc.be.model.ArtifactDefinition;
82 import org.openecomp.sdc.be.model.AttributeDefinition;
83 import org.openecomp.sdc.be.model.CapabilityDefinition;
84 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
85 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
86 import org.openecomp.sdc.be.model.Component;
87 import org.openecomp.sdc.be.model.ComponentInstance;
88 import org.openecomp.sdc.be.model.ComponentInstanceInput;
89 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
90 import org.openecomp.sdc.be.model.ComponentParametersView;
91 import org.openecomp.sdc.be.model.DataTypeDefinition;
92 import org.openecomp.sdc.be.model.GroupDefinition;
93 import org.openecomp.sdc.be.model.GroupProperty;
94 import org.openecomp.sdc.be.model.InputDefinition;
95 import org.openecomp.sdc.be.model.InterfaceDefinition;
96 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
97 import org.openecomp.sdc.be.model.LifecycleStateEnum;
98 import org.openecomp.sdc.be.model.Model;
99 import org.openecomp.sdc.be.model.NodeTypeInfo;
100 import org.openecomp.sdc.be.model.Operation;
101 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
102 import org.openecomp.sdc.be.model.PolicyDefinition;
103 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
104 import org.openecomp.sdc.be.model.PropertyDefinition;
105 import org.openecomp.sdc.be.model.RelationshipImpl;
106 import org.openecomp.sdc.be.model.RelationshipInfo;
107 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
108 import org.openecomp.sdc.be.model.RequirementDefinition;
109 import org.openecomp.sdc.be.model.Resource;
110 import org.openecomp.sdc.be.model.UploadArtifactInfo;
111 import org.openecomp.sdc.be.model.UploadCapInfo;
112 import org.openecomp.sdc.be.model.UploadComponentInstanceInfo;
113 import org.openecomp.sdc.be.model.UploadInfo;
114 import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
115 import org.openecomp.sdc.be.model.UploadPropInfo;
116 import org.openecomp.sdc.be.model.UploadReqInfo;
117 import org.openecomp.sdc.be.model.UploadResourceInfo;
118 import org.openecomp.sdc.be.model.User;
119 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
120 import org.openecomp.sdc.be.model.category.CategoryDefinition;
121 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
122 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
123 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
124 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
125 import org.openecomp.sdc.be.model.operations.StorageException;
126 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
127 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
128 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
129 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
130 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
131 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
132 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
133 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
134 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
135 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
136 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
137 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
138 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
139 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
140 import org.openecomp.sdc.be.tosca.CsarUtils;
141 import org.openecomp.sdc.be.tosca.CsarUtils.NonMetaArtifactInfo;
142 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
143 import org.openecomp.sdc.be.user.UserBusinessLogic;
144 import org.openecomp.sdc.be.utils.CommonBeUtils;
145 import org.openecomp.sdc.be.utils.TypeUtils;
146 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
147 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
148 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
149 import org.openecomp.sdc.common.api.Constants;
150 import org.openecomp.sdc.common.datastructure.Wrapper;
151 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
152 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
153 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
154 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
155 import org.openecomp.sdc.common.log.enums.StatusCode;
156 import org.openecomp.sdc.common.log.wrappers.Logger;
157 import org.openecomp.sdc.common.util.GeneralUtility;
158 import org.openecomp.sdc.common.util.ValidationUtils;
159 import org.openecomp.sdc.exception.ResponseFormat;
160 import org.springframework.beans.factory.annotation.Autowired;
161 import org.springframework.context.annotation.Lazy;
162 import org.yaml.snakeyaml.DumperOptions;
163 import org.yaml.snakeyaml.Yaml;
164
165 import java.util.ArrayList;
166 import java.util.Collection;
167 import java.util.Collections;
168 import java.util.EnumMap;
169 import java.util.HashMap;
170 import java.util.HashSet;
171 import java.util.Iterator;
172 import java.util.List;
173 import java.util.ListIterator;
174 import java.util.Map;
175 import java.util.Map.Entry;
176 import java.util.Objects;
177 import java.util.Optional;
178 import java.util.Set;
179 import java.util.function.Function;
180 import java.util.regex.Pattern;
181 import java.util.stream.Collectors;
182
183 import static java.util.stream.Collectors.toList;
184 import static java.util.stream.Collectors.toMap;
185 import static java.util.stream.Collectors.toSet;
186 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
187 import static org.apache.commons.collections.MapUtils.isEmpty;
188 import static org.apache.commons.collections.MapUtils.isNotEmpty;
189 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement;
190 import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue;
191 import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN;
192 import static org.openecomp.sdc.common.api.Constants.DEFAULT_GROUP_VF_MODULE;
193
194 @org.springframework.stereotype.Component("resourceBusinessLogic")
195 public class ResourceBusinessLogic extends ComponentBusinessLogic {
196
197     private static final String DELETE_RESOURCE = "Delete Resource";
198     private static final String IN_RESOURCE = "  in resource {} ";
199     private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
200     private static final String INITIAL_VERSION = "0.1";
201     private static final Logger log = Logger.getLogger(ResourceBusinessLogic.class);
202     private static final String CERTIFICATION_ON_IMPORT = "certification on import";
203     private static final String CREATE_RESOURCE = "Create Resource";
204     private static final String VALIDATE_DERIVED_BEFORE_UPDATE = "validate derived before update";
205     private static final String CATEGORY_IS_EMPTY = "Resource category is empty";
206     private static final String CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES = "Create Resource - validateCapabilityTypesCreate";
207     private static final String COMPONENT_INSTANCE_WITH_NAME = "component instance with name ";
208     private static final String COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE = "component instance with name {}  in resource {} ";
209     private static final String VALID_CHARACTERS_ARTIFACT_NAME = "'A-Z', 'a-z', '0-9', '.', '_', '-', '@' and space";
210     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourceBusinessLogic.class.getName());
211     private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
212     private final ResourceImportManager resourceImportManager;
213     private final InputsBusinessLogic inputsBusinessLogic;
214     private final OutputsBusinessLogic outputsBusinessLogic;
215     private final CompositionBusinessLogic compositionBusinessLogic;
216     private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic;
217     private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic;
218     private final MergeInstanceUtils mergeInstanceUtils;
219     private final UiComponentDataConverter uiComponentDataConverter;
220     private final CsarBusinessLogic csarBusinessLogic;
221     private final PropertyBusinessLogic propertyBusinessLogic;
222     private final PolicyBusinessLogic policyBusinessLogic;
223     private final ModelBusinessLogic modelBusinessLogic;
224     private IInterfaceLifecycleOperation interfaceTypeOperation;
225     private LifecycleBusinessLogic lifecycleBusinessLogic;
226     private final DataTypeBusinessLogic dataTypeBusinessLogic;
227     private final PolicyTypeBusinessLogic policyTypeBusinessLogic;
228     private final ModelOperation modelOperation;
229
230     @Autowired
231     private ICapabilityTypeOperation capabilityTypeOperation;
232     @Autowired
233     private TopologyComparator topologyComparator;
234     @Autowired
235     private ComponentValidator componentValidator;
236     @Autowired
237     private PropertyDataValueMergeBusinessLogic propertyDataValueMergeBusinessLogic;
238     @Autowired
239     private SoftwareInformationBusinessLogic softwareInformationBusinessLogic;
240
241
242     @Autowired
243     public ResourceBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
244                                  final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
245                                  final GroupBusinessLogic groupBusinessLogic, final InterfaceOperation interfaceOperation,
246                                  final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
247                                  final ArtifactsBusinessLogic artifactsBusinessLogic,
248                                  final ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
249                                  final @Lazy ResourceImportManager resourceImportManager, final InputsBusinessLogic inputsBusinessLogic,
250                                  final OutputsBusinessLogic outputsBusinessLogic, final CompositionBusinessLogic compositionBusinessLogic,
251                                  final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic,
252                                  final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic,
253                                  final MergeInstanceUtils mergeInstanceUtils, final UiComponentDataConverter uiComponentDataConverter,
254                                  final CsarBusinessLogic csarBusinessLogic, final ArtifactsOperations artifactToscaOperation,
255                                  final PropertyBusinessLogic propertyBusinessLogic, final ComponentContactIdValidator componentContactIdValidator,
256                                  final ComponentNameValidator componentNameValidator, final ComponentTagsValidator componentTagsValidator,
257                                  final ComponentValidator componentValidator, final ComponentIconValidator componentIconValidator,
258                                  final ComponentProjectCodeValidator componentProjectCodeValidator,
259                                  final ComponentDescriptionValidator componentDescriptionValidator, final PolicyBusinessLogic policyBusinessLogic,
260                                  final ModelBusinessLogic modelBusinessLogic,
261                                  final DataTypeBusinessLogic dataTypeBusinessLogic, final PolicyTypeBusinessLogic policyTypeBusinessLogic,
262                                  final ModelOperation modelOperation) {
263         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
264                 interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
265                 componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
266         this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
267         this.resourceImportManager = resourceImportManager;
268         this.inputsBusinessLogic = inputsBusinessLogic;
269         this.outputsBusinessLogic = outputsBusinessLogic;
270         this.compositionBusinessLogic = compositionBusinessLogic;
271         this.resourceDataMergeBusinessLogic = resourceDataMergeBusinessLogic;
272         this.csarArtifactsAndGroupsBusinessLogic = csarArtifactsAndGroupsBusinessLogic;
273         this.mergeInstanceUtils = mergeInstanceUtils;
274         this.uiComponentDataConverter = uiComponentDataConverter;
275         this.csarBusinessLogic = csarBusinessLogic;
276         this.propertyBusinessLogic = propertyBusinessLogic;
277         this.policyBusinessLogic = policyBusinessLogic;
278         this.modelBusinessLogic = modelBusinessLogic;
279         this.dataTypeBusinessLogic = dataTypeBusinessLogic;
280         this.policyTypeBusinessLogic = policyTypeBusinessLogic;
281         this.modelOperation = modelOperation;
282     }
283
284     static <T> Either<T, RuntimeException> rollbackWithEither(final JanusGraphDao janusGraphDao, final ActionStatus actionStatus,
285                                                               final String... params) {
286         if (janusGraphDao != null) {
287             janusGraphDao.rollback();
288         }
289         return Either.right(new ByActionStatusComponentException(actionStatus, params));
290     }
291
292     public LifecycleBusinessLogic getLifecycleBusinessLogic() {
293         return lifecycleBusinessLogic;
294     }
295
296     @Autowired
297     public void setLifecycleManager(LifecycleBusinessLogic lifecycleBusinessLogic) {
298         this.lifecycleBusinessLogic = lifecycleBusinessLogic;
299     }
300
301     @VisibleForTesting
302     protected void setComponentValidator(ComponentValidator componentValidator) {
303         this.componentValidator = componentValidator;
304     }
305
306     public IElementOperation getElementDao() {
307         return elementDao;
308     }
309
310     public void setElementDao(IElementOperation elementDao) {
311         this.elementDao = elementDao;
312     }
313
314     public UserBusinessLogic getUserAdmin() {
315         return this.userAdmin;
316     }
317
318     @Autowired
319     @Override
320     public void setUserAdmin(UserBusinessLogic userAdmin) {
321         this.userAdmin = userAdmin;
322     }
323
324     public ComponentsUtils getComponentsUtils() {
325         return this.componentsUtils;
326     }
327
328     @Autowired
329     @Override
330     public void setComponentsUtils(ComponentsUtils componentsUtils) {
331         this.componentsUtils = componentsUtils;
332     }
333
334     public ArtifactsBusinessLogic getArtifactsManager() {
335         return artifactsBusinessLogic;
336     }
337
338     public void setArtifactsManager(ArtifactsBusinessLogic artifactsManager) {
339         this.artifactsBusinessLogic = artifactsManager;
340     }
341
342     public ApplicationDataTypeCache getApplicationDataTypeCache() {
343         return applicationDataTypeCache;
344     }
345
346     @Autowired
347     @Override
348     public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) {
349         this.applicationDataTypeCache = applicationDataTypeCache;
350     }
351
352     @Autowired
353     public void setInterfaceTypeOperation(IInterfaceLifecycleOperation interfaceTypeOperation) {
354         this.interfaceTypeOperation = interfaceTypeOperation;
355     }
356
357     /**
358      * the method returns a list of all the resources that are certified, the returned resources are only abstract or only none abstract according to
359      * the given param
360      *
361      * @param getAbstract
362      * @param userId      TODO
363      * @return
364      */
365     public List<Resource> getAllCertifiedResources(boolean getAbstract, HighestFilterEnum highestFilter, String userId) {
366         User user = validateUserExists(userId);
367         Boolean isHighest = null;
368         switch (highestFilter) {
369             case ALL:
370                 break;
371             case HIGHEST_ONLY:
372                 isHighest = true;
373                 break;
374             case NON_HIGHEST_ONLY:
375                 isHighest = false;
376                 break;
377             default:
378                 break;
379         }
380         Either<List<Resource>, StorageOperationStatus> getResponse = toscaOperationFacade.getAllCertifiedResources(getAbstract, isHighest);
381         if (getResponse.isRight()) {
382             throw new StorageException(getResponse.right().value());
383         }
384         return getResponse.left().value();
385     }
386
387     public Either<Map<String, Boolean>, ResponseFormat> validateResourceNameExists(String resourceName, ResourceTypeEnum resourceTypeEnum,
388                                                                                    String userId) {
389         validateUserExists(userId);
390         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
391                 .validateComponentNameUniqueness(resourceName, resourceTypeEnum, ComponentTypeEnum.RESOURCE);
392         // DE242223
393         janusGraphDao.commit();
394         if (dataModelResponse.isLeft()) {
395             Map<String, Boolean> result = new HashMap<>();
396             result.put("isValid", dataModelResponse.left().value());
397             log.debug("validation was successfully performed.");
398             return Either.left(result);
399         }
400         ResponseFormat responseFormat = componentsUtils
401                 .getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
402         return Either.right(responseFormat);
403     }
404
405     public Resource createResource(Resource resource, AuditingActionEnum auditingAction, User user, Map<String, byte[]> csarUIPayload,
406                                    String payloadName) {
407         validateResourceBeforeCreate(resource, user, false);
408         String csarUUID = payloadName == null ? resource.getCsarUUID() : payloadName;
409         loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
410                 "Starting to create resource from CSAR by user {} ", user.getUserId());
411         if (StringUtils.isNotEmpty(csarUUID)) {
412             csarBusinessLogic.validateCsarBeforeCreate(resource, auditingAction, user, csarUUID);
413             log.debug("CsarUUID is {} - going to create resource from CSAR", csarUUID);
414             Resource createResourceFromCsar = createResourceFromCsar(resource, user, csarUIPayload, csarUUID);
415             return updateCatalog(createResourceFromCsar, ChangeTypeEnum.LIFECYCLE).left().map(Resource.class::cast).left().value();
416         }
417         final Resource createResourceByDao = createResourceByDao(resource, user, auditingAction, false, false);
418         return updateCatalog(createResourceByDao, ChangeTypeEnum.LIFECYCLE).left().map(Resource.class::cast).left().value();
419     }
420
421     public Resource validateAndUpdateResourceFromCsar(Resource resource, User user, Map<String, byte[]> csarUIPayload, String payloadName,
422                                                       String resourceUniqueId) {
423         String csarUUID = payloadName;
424         String csarVersion = null;
425         Resource updatedResource = null;
426         if (payloadName == null) {
427             csarUUID = resource.getCsarUUID();
428             csarVersion = resource.getCsarVersion();
429         }
430         if (csarUUID != null && !csarUUID.isEmpty()) {
431             Resource oldResource = getResourceByUniqueId(resourceUniqueId);
432             validateCsarUuidMatching(oldResource, resource, csarUUID, resourceUniqueId, user);
433             validateCsarIsNotAlreadyUsed(oldResource, resource, csarUUID, user);
434             if (oldResource != null && ValidationUtils.hasBeenCertified(oldResource.getVersion())) {
435                 overrideImmutableMetadata(oldResource, resource);
436             }
437             validateResourceBeforeCreate(resource, user, false);
438             String oldCsarVersion = oldResource != null ? oldResource.getCsarVersion() : null;
439             log.debug("CsarUUID is {} - going to update resource with UniqueId {} from CSAR", csarUUID, resourceUniqueId);
440             // (on boarding flow): If the update includes same csarUUID and
441
442             // same csarVersion as already in the VF - no need to import the
443
444             // csar (do only metadata changes if there are).
445             if (csarVersion != null && oldCsarVersion != null && oldCsarVersion.equals(csarVersion)) {
446                 updatedResource = updateResourceMetadata(resourceUniqueId, resource, oldResource, user, false);
447             } else {
448                 updatedResource = updateResourceFromCsar(oldResource, resource, user, AuditingActionEnum.UPDATE_RESOURCE_METADATA, false,
449                         csarUIPayload, csarUUID);
450             }
451         } else {
452             log.debug("Failed to update resource {}, csarUUID or payload name is missing", resource.getSystemName());
453             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CSAR_UUID, resource.getName());
454             componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.CREATE_RESOURCE);
455             throw new ByActionStatusComponentException(ActionStatus.MISSING_CSAR_UUID, resource.getName());
456         }
457         return updatedResource;
458     }
459
460     private void validateCsarIsNotAlreadyUsed(Resource oldResource, Resource resource, String csarUUID, User user) {
461         // (on boarding flow): If the update includes a csarUUID: verify this
462
463         // csarUUID is not in use by another VF, If it is - use same error as
464
465         // above:
466
467         // "Error: The VSP with UUID %1 was already imported for VF %2. Please
468
469         // select another or update the existing VF." %1 - csarUUID, %2 - VF
470
471         // name
472         Either<Resource, StorageOperationStatus> resourceLinkedToCsarRes = toscaOperationFacade
473                 .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUUID, resource.getSystemName());
474         if (resourceLinkedToCsarRes.isRight()) {
475             if (StorageOperationStatus.NOT_FOUND != resourceLinkedToCsarRes.right().value()) {
476                 log.debug("Failed to find previous resource by CSAR {} and system name {}", csarUUID, resource.getSystemName());
477                 throw new StorageException(resourceLinkedToCsarRes.right().value());
478             }
479         } else if (!resourceLinkedToCsarRes.left().value().getUniqueId().equals(oldResource.getUniqueId()) && !resourceLinkedToCsarRes.left().value()
480                 .getName().equals(oldResource.getName())) {
481             ResponseFormat errorResponse = componentsUtils
482                     .getResponseFormat(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, resourceLinkedToCsarRes.left().value().getName());
483             componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.UPDATE_RESOURCE_METADATA);
484             throw new ByActionStatusComponentException(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, resourceLinkedToCsarRes.left().value().getName());
485         }
486     }
487
488     private void validateCsarUuidMatching(Resource resource, Resource oldResource, String csarUUID, String resourceUniqueId, User user) {
489         // (on boarding flow): If the update includes csarUUID which is
490
491         // different from the csarUUID of the VF - fail with
492
493         // error: "Error: Resource %1 cannot be updated using since it is linked
494
495         // to a different VSP" %1 - VF name
496         String oldCsarUUID = oldResource.getCsarUUID();
497         if (oldCsarUUID != null && !oldCsarUUID.isEmpty() && !csarUUID.equals(oldCsarUUID)) {
498             log.debug("Failed to update resource with UniqueId {} using Csar {}, since the resource is linked to a different VSP {}",
499                     resourceUniqueId, csarUUID, oldCsarUUID);
500             ResponseFormat errorResponse = componentsUtils
501                     .getResponseFormat(ActionStatus.RESOURCE_LINKED_TO_DIFFERENT_VSP, resource.getName(), csarUUID, oldCsarUUID);
502             componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.UPDATE_RESOURCE_METADATA);
503             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_LINKED_TO_DIFFERENT_VSP, resource.getName(), csarUUID, oldCsarUUID);
504         }
505     }
506
507     private Resource getResourceByUniqueId(String resourceUniqueId) {
508         Either<Resource, StorageOperationStatus> oldResourceRes = toscaOperationFacade.getToscaFullElement(resourceUniqueId);
509         if (oldResourceRes.isRight()) {
510             log.debug("Failed to find previous resource by UniqueId {}, status: {}", resourceUniqueId, oldResourceRes.right().value());
511             throw new StorageException(oldResourceRes.right().value());
512         }
513         return oldResourceRes.left().value();
514     }
515
516     private void overrideImmutableMetadata(Resource oldResource, Resource resource) {
517         resource.setName(oldResource.getName());
518         resource.setIcon(oldResource.getIcon());
519         resource.setTags(oldResource.getTags());
520         resource.setCategories(oldResource.getCategories());
521         resource.setDerivedFrom(oldResource.getDerivedFrom());
522     }
523
524     private Resource updateResourceFromCsar(Resource oldResource, Resource newResource, User user, AuditingActionEnum updateResource,
525                                             boolean inTransaction, Map<String, byte[]> csarUIPayload, String csarUUID) {
526         Resource updatedResource = null;
527         validateLifecycleState(oldResource, user);
528         String lockedResourceId = oldResource.getUniqueId();
529         List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
530         CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(newResource, oldResource, user, csarUIPayload, csarUUID);
531         lockComponent(lockedResourceId, oldResource, "update Resource From Csar");
532         Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
533         Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
534                 nodeTypesInfo, csarInfo, oldResource);
535         if (findNodeTypesArtifactsToHandleRes.isRight()) {
536             log.debug("failed to find node types for update with artifacts during import csar {}. ", csarInfo.getCsarUUID());
537             throw new ByResponseFormatComponentException(findNodeTypesArtifactsToHandleRes.right().value());
538         }
539         Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = findNodeTypesArtifactsToHandleRes.left()
540                 .value();
541         try {
542             updatedResource = updateResourceFromYaml(oldResource, newResource, updateResource, createdArtifacts, csarInfo.getMainTemplateName(),
543                     csarInfo.getMainTemplateContent(), csarInfo, nodeTypesInfo, nodeTypesArtifactsToHandle, null, false);
544         } catch (ComponentException | StorageException e) {
545             rollback(inTransaction, newResource, createdArtifacts, null);
546             throw e;
547         } finally {
548             janusGraphDao.commit();
549             log.debug("unlock resource {}", lockedResourceId);
550             graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource);
551         }
552         return updatedResource;
553     }
554
555     private void validateLifecycleState(Resource oldResource, User user) {
556         if (LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == oldResource.getLifecycleState() && !oldResource.getLastUpdaterUserId()
557                 .equals(user.getUserId())) {
558             log.debug("#validateLifecycleState - Current user is not last updater, last updater userId: {}, current user userId: {}",
559                     oldResource.getLastUpdaterUserId(), user.getUserId());
560             throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
561         }
562     }
563
564     private Resource updateResourceFromYaml(Resource oldResource, Resource newResource, AuditingActionEnum actionEnum,
565                                             List<ArtifactDefinition> createdArtifacts, String yamlFileName, String yamlFileContent, CsarInfo csarInfo,
566                                             Map<String, NodeTypeInfo> nodeTypesInfo,
567                                             Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
568                                             String nodeName, boolean isNested) {
569         boolean inTransaction = true;
570         boolean shouldLock = false;
571         Resource preparedResource = null;
572         ParsedToscaYamlInfo uploadComponentInstanceInfoMap;
573         try {
574             uploadComponentInstanceInfoMap = csarBusinessLogic
575                     .getParsedToscaYamlInfo(yamlFileContent, yamlFileName, nodeTypesInfo, csarInfo, nodeName, oldResource);
576             Map<String, UploadComponentInstanceInfo> instances = uploadComponentInstanceInfoMap.getInstances();
577             if (MapUtils.isEmpty(instances) && newResource.getResourceType() != ResourceTypeEnum.PNF) {
578                 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlFileName);
579             }
580             preparedResource = updateExistingResourceByImport(newResource, oldResource, csarInfo.getModifier(), inTransaction, shouldLock,
581                     isNested).left;
582             log.trace("YAML topology file found in CSAR, file name: {}, contents: {}", yamlFileName, yamlFileContent);
583             handleResourceGenericType(preparedResource, yamlFileContent, uploadComponentInstanceInfoMap,
584                     uploadComponentInstanceInfoMap.getSubstitutionMappingNodeType());
585             handleNodeTypes(yamlFileName, preparedResource, yamlFileContent, shouldLock, nodeTypesArtifactsToHandle, createdArtifacts, nodeTypesInfo,
586                     csarInfo, nodeName, newResource.getModel());
587             preparedResource = createInputsOnResource(preparedResource, uploadComponentInstanceInfoMap.getInputs());
588             Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
589             final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(uploadComponentInstanceInfoMap,
590                     newResource.getModel());
591             preparedResource = createResourceInstances(yamlFileName, preparedResource, oldResource, instancesToCreate, csarInfo.getCreatedNodes(),
592                     existingNodeTypesByResourceNames);
593             preparedResource = createResourceInstancesRelations(csarInfo.getModifier(), yamlFileName, preparedResource, oldResource,
594                     instancesToCreate,
595                     existingNodeTypesByResourceNames);
596         } catch (ComponentException e) {
597             ResponseFormat responseFormat =
598                     e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
599             log.debug("#updateResourceFromYaml - failed to update newResource from yaml {} .The error is {}", yamlFileName, responseFormat);
600             componentsUtils
601                     .auditResource(responseFormat, csarInfo.getModifier(), preparedResource == null ? oldResource : preparedResource, actionEnum);
602             throw e;
603         } catch (StorageException e) {
604             ResponseFormat responseFormat = componentsUtils
605                     .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
606             log.debug("#updateResourceFromYaml - failed to update newResource from yaml {} .The error is {}", yamlFileName, responseFormat);
607             componentsUtils
608                     .auditResource(responseFormat, csarInfo.getModifier(), preparedResource == null ? oldResource : preparedResource, actionEnum);
609             throw e;
610         }
611         Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic
612                 .validateUpdateVfGroupNames(uploadComponentInstanceInfoMap.getGroups(), preparedResource.getSystemName());
613         if (validateUpdateVfGroupNamesRes.isRight()) {
614             throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value());
615         }
616         // add groups to newResource
617         Map<String, GroupDefinition> groups;
618         if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) {
619             groups = validateUpdateVfGroupNamesRes.left().value();
620         } else {
621             groups = uploadComponentInstanceInfoMap.getGroups();
622         }
623         handleGroupsProperties(preparedResource, groups);
624         Either<Boolean, ActionStatus> isTopologyChanged = topologyComparator.isTopologyChanged(oldResource, preparedResource);
625         preparedResource = updateGroupsOnResource(preparedResource, groups);
626         NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName, nodeTypesArtifactsToHandle);
627         Either<Resource, ResponseFormat> updateArtifactsEither = createOrUpdateArtifacts(ArtifactOperationEnum.UPDATE, createdArtifacts, yamlFileName,
628                 csarInfo, preparedResource, nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock);
629         if (updateArtifactsEither.isRight()) {
630             log.debug("failed to update artifacts {}", updateArtifactsEither.right().value());
631             throw new ByResponseFormatComponentException(updateArtifactsEither.right().value());
632         }
633         preparedResource = getResourceWithGroups(updateArtifactsEither.left().value().getUniqueId());
634         updateGroupsName(oldResource, preparedResource, isTopologyChanged.left().value());
635         updateResourceInstancesNames(oldResource, csarInfo, preparedResource, isTopologyChanged.left().value());
636         final String preparedResourceId = preparedResource != null ? preparedResource.getUniqueId() : "";
637         preparedResource = getResourceWithGroups(preparedResourceId);
638         updateVolumeGroup(preparedResource);
639         ActionStatus mergingPropsAndInputsStatus = resourceDataMergeBusinessLogic.mergeResourceEntities(oldResource, preparedResource);
640         if (mergingPropsAndInputsStatus != ActionStatus.OK) {
641             ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(mergingPropsAndInputsStatus, preparedResource);
642             throw new ByResponseFormatComponentException(responseFormat);
643         }
644         compositionBusinessLogic.setPositionsForComponentInstances(preparedResource, csarInfo.getModifier().getUserId());
645         return preparedResource;
646     }
647
648     protected void updateVolumeGroup(Resource preparedResource) {
649         List<GroupDefinition> groups = preparedResource.safeGetGroups();
650         for (GroupDefinition group : groups) {
651             Map<String, ArtifactDefinition> createdNewArtifacts = preparedResource.getDeploymentArtifacts();
652             if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
653                 List<PropertyDataDefinition> volumePropList = group.getProperties().stream().filter(p -> "volume_group".equals(p.getName()))
654                         .collect(Collectors.toList());
655                 if (!volumePropList.isEmpty()) {
656                     PropertyDataDefinition volumeProp = volumePropList.get(0);
657                     if (volumeProp != null) {
658                         boolean isVolumeGroup = isVolumeGroup(group.getArtifacts(), new ArrayList<>(createdNewArtifacts.values()));
659                         if (!volumePropList.get(0).getValue().equals(String.valueOf(isVolumeGroup))) {
660                             volumeProp.setValue(String.valueOf(isVolumeGroup));
661                             volumeProp.setDefaultValue(String.valueOf(isVolumeGroup));
662                         }
663                     }
664                 }
665             }
666         }
667     }
668
669     private void updateGroupsName(Resource oldResource, Resource preparedResource, boolean isTopologyChanged) {
670         if (oldResource == null || preparedResource == null) {
671             log.debug("Failed to update groups name : oldResource or preparedResource is null");
672         } else if (CollectionUtils.isNotEmpty(oldResource.getGroups()) && CollectionUtils.isNotEmpty(preparedResource.getGroups())) {
673             Map<String, String> oldGroups = oldResource.getGroups().stream()
674                     .collect(toMap(GroupDataDefinition::getInvariantName, GroupDataDefinition::getName));
675             List<GroupDefinition> updatedGroups = preparedResource.getGroups().stream()
676                     .filter(group -> oldGroups.containsKey(group.getInvariantName()) && !group.getName().equals(oldGroups.get(group.getInvariantName())))
677                     .collect(toList());
678             if (CollectionUtils.isNotEmpty(updatedGroups)) {
679                 if (isTopologyChanged) {
680                     updatedGroups.stream().filter(group -> !group.isVspOriginated())
681                             .forEach(group -> group.setName(oldGroups.get(group.getInvariantName())));
682                 } else {
683                     updatedGroups.forEach(group -> group.setName(oldGroups.get(group.getInvariantName())));
684                 }
685                 groupBusinessLogic.updateGroups(preparedResource, updatedGroups, false);
686             }
687         }
688     }
689
690     private void updateResourceInstancesNames(Resource oldResource, CsarInfo csarInfo, Resource preparedResource, boolean isTopologyChanged) {
691         if (oldResource == null || preparedResource == null) {
692             log.debug("Failed to update resource instances names : oldResource or preparedResource is null");
693         } else {
694             if (CollectionUtils.isNotEmpty(oldResource.getComponentInstances())) {
695                 Map<String, String> oldInstances = oldResource.getComponentInstances().stream()
696                         .collect(toMap(ComponentInstance::getInvariantName, ComponentInstance::getName));
697                 List<ComponentInstance> updatedInstances = preparedResource.getComponentInstances().stream()
698                         .filter(i -> oldInstances.containsKey(i.getInvariantName()) && !i.getName().equals(oldInstances.get(i.getInvariantName())))
699                         .collect(toList());
700                 if (CollectionUtils.isNotEmpty(updatedInstances)) {
701                     if (isTopologyChanged) {
702                         updatedInstances.stream().filter(i -> !i.isCreatedFromCsar()).forEach(i -> i.setName(oldInstances.get(i.getInvariantName())));
703                     } else {
704                         updatedInstances.forEach(i -> i.setName(oldInstances.get(i.getInvariantName())));
705                     }
706                 }
707             }
708             componentInstanceBusinessLogic.updateComponentInstance(ComponentTypeEnum.RESOURCE_PARAM_NAME, null, preparedResource.getUniqueId(),
709                     csarInfo.getModifier().getUserId(), preparedResource.getComponentInstances(), false);
710         }
711     }
712
713     private Either<Resource, ResponseFormat> createOrUpdateArtifacts(ArtifactOperationEnum operation, List<ArtifactDefinition> createdArtifacts,
714                                                                      String yamlFileName, CsarInfo csarInfo, Resource preparedResource,
715                                                                      NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts,
716                                                                      boolean inTransaction, boolean shouldLock) {
717         String nodeName = nodeTypeInfoToUpdateArtifacts.getNodeName();
718         Resource resource = preparedResource;
719         Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = nodeTypeInfoToUpdateArtifacts
720                 .getNodeTypesArtifactsToHandle();
721         if (preparedResource.getResourceType() == ResourceTypeEnum.CVFC) {
722             if (nodeName != null && nodeTypesArtifactsToHandle.get(nodeName) != null && !nodeTypesArtifactsToHandle.get(nodeName).isEmpty()) {
723                 Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes = handleNodeTypeArtifacts(preparedResource,
724                         nodeTypesArtifactsToHandle.get(nodeName), createdArtifacts, csarInfo.getModifier(), inTransaction, true);
725                 if (handleNodeTypeArtifactsRes.isRight()) {
726                     return Either.right(handleNodeTypeArtifactsRes.right().value());
727                 }
728             }
729         } else {
730             Either<Resource, ResponseFormat> createdCsarArtifactsEither = handleVfCsarArtifacts(preparedResource, csarInfo, createdArtifacts,
731                     new ArtifactOperationInfo(false, false, operation), shouldLock, inTransaction);
732             log.trace("************* Finished to add artifacts from yaml {}", yamlFileName);
733             if (createdCsarArtifactsEither.isRight()) {
734                 return createdCsarArtifactsEither;
735             }
736             resource = createdCsarArtifactsEither.left().value();
737         }
738         return Either.left(resource);
739     }
740
741     private Resource handleResourceGenericType(Resource resource) {
742         Resource genericResource = fetchAndSetDerivedFromGenericType(resource);
743
744         if (resource.shouldGenerateInputs()) {
745             generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
746         }
747         return genericResource;
748     }
749
750     private Resource handleResourceGenericType(final Resource resource, final String topologyTemplateYaml,
751                                                final ParsedToscaYamlInfo parsedToscaYamlInfo, final String substitutionMappingNodeType) {
752         if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
753             final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
754                     (Map<String, Object>) new Yaml().load(topologyTemplateYaml), substitutionMappingNodeType);
755             final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
756                     (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
757
758             generatePropertiesFromGenericType(resource, genericResource);
759             generatePropertiesFromNodeType(resource, substitutableAsNodeType);
760             final String resourceId = resource.getUniqueId();
761             resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
762                     UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
763             createResourcePropertiesOnGraph(resource);
764             return genericResource;
765         }
766         return handleResourceGenericType(resource);
767     }
768
769     private Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandle(
770             final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo, final Resource oldResource) {
771         final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = new HashMap<>();
772         Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> nodeTypesArtifactsToHandleRes = Either
773                 .left(nodeTypesArtifactsToHandle);
774         try {
775             final Map<String, List<ArtifactDefinition>> extractedVfcsArtifacts = CsarUtils.extractVfcsArtifactsFromCsar(csarInfo.getCsar());
776             final Map<String, ImmutablePair<String, String>> extractedVfcToscaNames = extractVfcToscaNames(nodeTypesInfo, oldResource.getName(),
777                     csarInfo);
778             log.debug("Going to fetch node types for resource with name {} during import csar with UUID {}. ", oldResource.getName(),
779                     csarInfo.getCsarUUID());
780             extractedVfcToscaNames.forEach(
781                     (namespace, vfcToscaNames) -> findAddNodeTypeArtifactsToHandle(csarInfo, nodeTypesArtifactsToHandle, oldResource,
782                             extractedVfcsArtifacts, namespace, vfcToscaNames));
783         } catch (Exception e) {
784             final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
785             nodeTypesArtifactsToHandleRes = Either.right(responseFormat);
786             log.debug("Exception occurred when findNodeTypesUpdatedArtifacts, error is:{}", e.getMessage(), e);
787         }
788         return nodeTypesArtifactsToHandleRes;
789     }
790
791     private void findAddNodeTypeArtifactsToHandle(CsarInfo csarInfo,
792                                                   Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
793                                                   Resource resource, Map<String, List<ArtifactDefinition>> extractedVfcsArtifacts, String namespace,
794                                                   ImmutablePair<String, String> vfcToscaNames) {
795         EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> curNodeTypeArtifactsToHandle = null;
796         log.debug("Going to fetch node type with tosca name {}. ", vfcToscaNames.getLeft());
797         Resource curNodeType = findVfcResource(csarInfo, resource, vfcToscaNames.getLeft(), vfcToscaNames.getRight(), null);
798         if (!isEmpty(extractedVfcsArtifacts)) {
799             List<ArtifactDefinition> currArtifacts = new ArrayList<>();
800             if (extractedVfcsArtifacts.containsKey(namespace)) {
801                 handleAndAddExtractedVfcsArtifacts(currArtifacts, extractedVfcsArtifacts.get(namespace));
802             }
803             curNodeTypeArtifactsToHandle = findNodeTypeArtifactsToHandle(curNodeType, currArtifacts);
804         } else if (curNodeType != null) {
805             // delete all artifacts if have not received artifacts from
806
807             // csar
808             curNodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
809             List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
810             // delete all informational artifacts
811             artifactsToDelete.addAll(
812                     curNodeType.getArtifacts().values().stream().filter(a -> a.getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL)
813                             .collect(toList()));
814             // delete all deployment artifacts
815             artifactsToDelete.addAll(curNodeType.getDeploymentArtifacts().values());
816             if (!artifactsToDelete.isEmpty()) {
817                 curNodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
818             }
819         }
820         if (isNotEmpty(curNodeTypeArtifactsToHandle)) {
821             nodeTypesArtifactsToHandle.put(namespace, curNodeTypeArtifactsToHandle);
822         }
823     }
824
825     private Resource findVfcResource(CsarInfo csarInfo, Resource resource, String currVfcToscaName, String previousVfcToscaName,
826                                      StorageOperationStatus status) {
827         if (status != null && status != StorageOperationStatus.NOT_FOUND) {
828             log.debug("Error occurred during fetching node type with tosca name {}, error: {}", currVfcToscaName, status);
829             ResponseFormat responseFormat = componentsUtils
830                     .getResponseFormat(componentsUtils.convertFromStorageResponse(status), csarInfo.getCsarUUID());
831             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.CREATE_RESOURCE);
832             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), csarInfo.getCsarUUID());
833         } else if (StringUtils.isNotEmpty(currVfcToscaName)) {
834             return (Resource) toscaOperationFacade.getLatestByToscaResourceName(currVfcToscaName, resource.getModel()).left()
835                     .on(st -> findVfcResource(csarInfo, resource, previousVfcToscaName, null, st));
836         }
837         return null;
838     }
839
840     private EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> findNodeTypeArtifactsToHandle(Resource curNodeType,
841                                                                                                    List<ArtifactDefinition> extractedArtifacts) {
842         try {
843             List<ArtifactDefinition> artifactsToUpload = new ArrayList<>(extractedArtifacts);
844             List<ArtifactDefinition> artifactsToUpdate = new ArrayList<>();
845             List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
846             processExistingNodeTypeArtifacts(extractedArtifacts, artifactsToUpload, artifactsToUpdate, artifactsToDelete,
847                     collectExistingArtifacts(curNodeType));
848             return putFoundArtifacts(artifactsToUpload, artifactsToUpdate, artifactsToDelete);
849         } catch (Exception e) {
850             log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
851             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
852         }
853     }
854
855     private EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> putFoundArtifacts(List<ArtifactDefinition> artifactsToUpload,
856                                                                                        List<ArtifactDefinition> artifactsToUpdate,
857                                                                                        List<ArtifactDefinition> artifactsToDelete) {
858         EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle = null;
859         if (!artifactsToUpload.isEmpty() || !artifactsToUpdate.isEmpty() || !artifactsToDelete.isEmpty()) {
860             nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
861             if (!artifactsToUpload.isEmpty()) {
862                 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
863             }
864             if (!artifactsToUpdate.isEmpty()) {
865                 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
866             }
867             if (!artifactsToDelete.isEmpty()) {
868                 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
869             }
870         }
871         return nodeTypeArtifactsToHandle;
872     }
873
874     private void processExistingNodeTypeArtifacts(List<ArtifactDefinition> extractedArtifacts, List<ArtifactDefinition> artifactsToUpload,
875                                                   List<ArtifactDefinition> artifactsToUpdate, List<ArtifactDefinition> artifactsToDelete,
876                                                   Map<String, ArtifactDefinition> existingArtifacts) {
877         if (!existingArtifacts.isEmpty()) {
878             extractedArtifacts.forEach(a -> processNodeTypeArtifact(artifactsToUpload, artifactsToUpdate, existingArtifacts, a));
879             artifactsToDelete.addAll(existingArtifacts.values());
880         }
881     }
882
883     private void processNodeTypeArtifact(List<ArtifactDefinition> artifactsToUpload, List<ArtifactDefinition> artifactsToUpdate,
884                                          Map<String, ArtifactDefinition> existingArtifacts, ArtifactDefinition currNewArtifact) {
885         Optional<ArtifactDefinition> foundArtifact = existingArtifacts.values().stream()
886                 .filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName())).findFirst();
887         if (foundArtifact.isPresent()) {
888             if (foundArtifact.get().getArtifactType().equals(currNewArtifact.getArtifactType())) {
889                 updateFoundArtifact(artifactsToUpdate, currNewArtifact, foundArtifact.get());
890                 existingArtifacts.remove(foundArtifact.get().getArtifactLabel());
891                 artifactsToUpload.remove(currNewArtifact);
892             } else {
893                 log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
894                 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR,
895                         currNewArtifact.getArtifactName(), currNewArtifact.getArtifactType(), foundArtifact.get().getArtifactType());
896             }
897         }
898     }
899
900     private void updateFoundArtifact(List<ArtifactDefinition> artifactsToUpdate, ArtifactDefinition currNewArtifact,
901                                      ArtifactDefinition foundArtifact) {
902         if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
903             foundArtifact.setPayload(currNewArtifact.getPayloadData());
904             foundArtifact.setPayloadData(Base64.encodeBase64String(currNewArtifact.getPayloadData()));
905             foundArtifact.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(currNewArtifact.getPayloadData()));
906             artifactsToUpdate.add(foundArtifact);
907         }
908     }
909
910     private Map<String, ArtifactDefinition> collectExistingArtifacts(Resource curNodeType) {
911         Map<String, ArtifactDefinition> existingArtifacts = new HashMap<>();
912         if (curNodeType == null) {
913             return existingArtifacts;
914         }
915         if (MapUtils.isNotEmpty(curNodeType.getDeploymentArtifacts())) {
916             existingArtifacts.putAll(curNodeType.getDeploymentArtifacts());
917         }
918         if (MapUtils.isNotEmpty(curNodeType.getArtifacts())) {
919             existingArtifacts.putAll(
920                     curNodeType.getArtifacts().entrySet().stream().filter(e -> e.getValue().getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL)
921                             .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)));
922         }
923         return existingArtifacts;
924     }
925
926     /**
927      * Changes resource life cycle state to checked out
928      *
929      * @param resource
930      * @param user
931      * @param inTransaction
932      * @return
933      */
934     private Either<Resource, ResponseFormat> checkoutResource(Resource resource, User user, boolean inTransaction) {
935         Either<Resource, ResponseFormat> checkoutResourceRes;
936         try {
937             if (!resource.getComponentMetadataDefinition().getMetadataDataDefinition().getState()
938                     .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
939                 log.debug("************* Going to change life cycle state of resource {} to not certified checked out. ", resource.getName());
940                 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
941                         .changeComponentState(resource.getComponentType(), resource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT,
942                                 new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT, LifecycleChanceActionEnum.CREATE_FROM_CSAR), inTransaction, true);
943                 if (checkoutRes.isRight()) {
944                     log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ",
945                             resource.getComponentType().getNodeType(), resource.getUniqueId(), checkoutRes.right().value().getStatus());
946                     checkoutResourceRes = Either.right(checkoutRes.right().value());
947                 } else {
948                     checkoutResourceRes = Either.left((Resource) checkoutRes.left().value());
949                 }
950             } else {
951                 checkoutResourceRes = Either.left(resource);
952             }
953         } catch (Exception e) {
954             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
955             checkoutResourceRes = Either.right(responseFormat);
956             log.debug("Exception occurred when checkoutResource {} , error is:{}", resource.getName(), e.getMessage(), e);
957         }
958         return checkoutResourceRes;
959     }
960
961     /**
962      * Handles Artifacts of NodeType
963      *
964      * @param nodeTypeResource
965      * @param nodeTypeArtifactsToHandle
966      * @param user
967      * @param inTransaction
968      * @return
969      */
970     public Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifacts(Resource nodeTypeResource,
971                                                                                     Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
972                                                                                     List<ArtifactDefinition> createdArtifacts, User user,
973                                                                                     boolean inTransaction, boolean ignoreLifecycleState) {
974         List<ArtifactDefinition> handleNodeTypeArtifactsRequestRes;
975         Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes = null;
976         Either<Resource, ResponseFormat> changeStateResponse;
977         try {
978             changeStateResponse = checkoutResource(nodeTypeResource, user, inTransaction);
979             if (changeStateResponse.isRight()) {
980                 return Either.right(changeStateResponse.right().value());
981             }
982             nodeTypeResource = changeStateResponse.left().value();
983             List<ArtifactDefinition> handledNodeTypeArtifacts = new ArrayList<>();
984             log.debug("************* Going to handle artifacts of node type resource {}. ", nodeTypeResource.getName());
985             for (Entry<ArtifactOperationEnum, List<ArtifactDefinition>> curOperationEntry : nodeTypeArtifactsToHandle.entrySet()) {
986                 ArtifactOperationEnum curOperation = curOperationEntry.getKey();
987                 List<ArtifactDefinition> curArtifactsToHandle = curOperationEntry.getValue();
988                 if (curArtifactsToHandle != null && !curArtifactsToHandle.isEmpty()) {
989                     log.debug("************* Going to {} artifact to vfc {}", curOperation.name(), nodeTypeResource.getName());
990                     handleNodeTypeArtifactsRequestRes = artifactsBusinessLogic
991                             .handleArtifactsRequestForInnerVfcComponent(curArtifactsToHandle, nodeTypeResource, user, createdArtifacts,
992                                     new ArtifactOperationInfo(false, ignoreLifecycleState, curOperation), false, inTransaction);
993                     if (ArtifactOperationEnum.isCreateOrLink(curOperation)) {
994                         createdArtifacts.addAll(handleNodeTypeArtifactsRequestRes);
995                     }
996                     handledNodeTypeArtifacts.addAll(handleNodeTypeArtifactsRequestRes);
997                 }
998             }
999             handleNodeTypeArtifactsRes = Either.left(handledNodeTypeArtifacts);
1000         } catch (Exception e) {
1001             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1002             handleNodeTypeArtifactsRes = Either.right(responseFormat);
1003             log.debug("Exception occurred when handleVfcArtifacts, error is:{}", e.getMessage(), e);
1004         }
1005         return handleNodeTypeArtifactsRes;
1006     }
1007
1008     private Map<String, ImmutablePair<String, String>> extractVfcToscaNames(final Map<String, NodeTypeInfo> nodeTypesInfo,
1009                                                                             final String vfResourceName, final CsarInfo csarInfo) {
1010         final Map<String, ImmutablePair<String, String>> vfcToscaNames = new HashMap<>();
1011         final Map<String, Object> nodes = extractAllNodes(nodeTypesInfo, csarInfo);
1012         if (!nodes.isEmpty()) {
1013             for (Entry<String, Object> nodeType : nodes.entrySet()) {
1014                 final ImmutablePair<String, String> toscaResourceName = buildNestedToscaResourceName(ResourceTypeEnum.VFC.name(), vfResourceName,
1015                         nodeType.getKey());
1016                 vfcToscaNames.put(nodeType.getKey(), toscaResourceName);
1017             }
1018         }
1019         for (final NodeTypeInfo cvfc : nodeTypesInfo.values()) {
1020             vfcToscaNames.put(cvfc.getType(), buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), vfResourceName, cvfc.getType()));
1021         }
1022         return vfcToscaNames;
1023     }
1024
1025     private Map<String, Object> extractAllNodes(Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo) {
1026         Map<String, Object> nodes = new HashMap<>();
1027         for (NodeTypeInfo nodeTypeInfo : nodeTypesInfo.values()) {
1028             extractNodeTypes(nodes, nodeTypeInfo.getMappedToscaTemplate());
1029         }
1030         extractNodeTypes(nodes, csarInfo.getMappedToscaMainTemplate());
1031         return nodes;
1032     }
1033
1034     private void extractNodeTypes(Map<String, Object> nodes, Map<String, Object> mappedToscaTemplate) {
1035         Either<Map<String, Object>, ResultStatusEnum> eitherNodeTypes = ImportUtils
1036                 .findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
1037         if (eitherNodeTypes.isLeft()) {
1038             nodes.putAll(eitherNodeTypes.left().value());
1039         }
1040     }
1041
1042     public Resource createResourceFromCsar(Resource resource, User user, Map<String, byte[]> csarUIPayload, String csarUUID) {
1043         log.trace("************* created successfully from YAML, resource TOSCA ");
1044         loggerSupportability
1045                 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.STARTED, "Starting to create Resource From Csar by user {}",
1046                         user.getUserId());
1047         CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID);
1048         Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
1049         final String model = resource.getModel();
1050         if (StringUtils.isNotEmpty(model)) {
1051             final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(model, csarInfo.getDataTypes());
1052             final Map<String, Object> policyTypesToCreate = getPolicytypesToCreate(model, csarInfo.getPolicyTypes());
1053             if (MapUtils.isNotEmpty(dataTypesToCreate) || MapUtils.isNotEmpty(policyTypesToCreate)) {
1054                 createModel(resource, csarInfo.getVfResourceName());
1055             }
1056             if (MapUtils.isNotEmpty(dataTypesToCreate)) {
1057                 dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), model, true);
1058             }
1059             if (MapUtils.isNotEmpty(policyTypesToCreate)) {
1060                 policyTypeBusinessLogic.createPolicyTypeFromYaml(new Yaml().dump(policyTypesToCreate), model, true);
1061             }
1062         }
1063
1064         Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
1065                 nodeTypesInfo, csarInfo, resource);
1066         if (findNodeTypesArtifactsToHandleRes.isRight()) {
1067             log.debug("failed to find node types for update with artifacts during import csar {}. ", csarInfo.getCsarUUID());
1068             loggerSupportability
1069                     .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1070                             "error: {}", findNodeTypesArtifactsToHandleRes.right().value());
1071             throw new ByResponseFormatComponentException(findNodeTypesArtifactsToHandleRes.right().value());
1072         }
1073         Resource vfResource = createResourceFromYaml(resource, csarInfo.getMainTemplateContent(), csarInfo.getMainTemplateName(), nodeTypesInfo,
1074                 csarInfo, findNodeTypesArtifactsToHandleRes.left().value(), true, false, null);
1075         log.trace("*************VF Resource created successfully from YAML, resource TOSCA name: {}", vfResource.getToscaResourceName());
1076         loggerSupportability
1077                 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.COMPLETE, "Ended create Resource From Csar by user {}",
1078                         user.getUserId());
1079         return vfResource;
1080     }
1081
1082     private Resource validateResourceBeforeCreate(Resource resource, User user, boolean inTransaction) {
1083         log.trace("validating resource before create");
1084         user.copyData(validateUser(user, CREATE_RESOURCE, resource, AuditingActionEnum.CREATE_RESOURCE, false));
1085         // validate user role
1086         validateUserRole(user, resource, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
1087         // VF / PNF "derivedFrom" should be null (or ignored)
1088         if (ModelConverter.isAtomicComponent(resource)) {
1089             validateDerivedFromNotEmpty(user, resource, AuditingActionEnum.CREATE_RESOURCE);
1090         }
1091         return validateResourceBeforeCreate(resource, user, AuditingActionEnum.CREATE_RESOURCE, inTransaction, null);
1092     }
1093
1094     private Resource createResourceFromYaml(Resource resource, String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo,
1095                                             CsarInfo csarInfo,
1096                                             Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1097                                             boolean shouldLock, boolean inTransaction, String nodeName) {
1098         List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
1099         Resource createdResource;
1100         try {
1101             ParsedToscaYamlInfo parsedToscaYamlInfo = csarBusinessLogic
1102                     .getParsedToscaYamlInfo(topologyTemplateYaml, yamlName, nodeTypesInfo, csarInfo, nodeName, resource);
1103             if (MapUtils.isEmpty(parsedToscaYamlInfo.getInstances()) && resource.getResourceType() != ResourceTypeEnum.PNF) {
1104                 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
1105             }
1106             log.debug("#createResourceFromYaml - Going to create resource {} and RIs ", resource.getName());
1107             loggerSupportability
1108                     .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED, "");
1109             createdResource = createResourceAndRIsFromYaml(yamlName, resource, parsedToscaYamlInfo, AuditingActionEnum.IMPORT_RESOURCE, false,
1110                     createdArtifacts, topologyTemplateYaml, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, shouldLock, inTransaction, nodeName);
1111             log.debug("#createResourceFromYaml - The resource {} has been created ", resource.getName());
1112             loggerSupportability
1113                     .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1114                             "The resource has been created: {}", resource.getName());
1115         } catch (ComponentException e) {
1116             ResponseFormat responseFormat =
1117                     e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
1118             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
1119             throw e;
1120         } catch (StorageException e) {
1121             ResponseFormat responseFormat = componentsUtils
1122                     .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
1123             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
1124             throw e;
1125         }
1126         return createdResource;
1127     }
1128
1129     public Map<String, Resource> createResourcesFromYamlNodeTypesList(String yamlName, Resource resource, Map<String, Object> mappedToscaTemplate,
1130                                                                       boolean needLock,
1131                                                                       Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
1132                                                                       List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1133                                                                       Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1134                                                                       final String substitutableAsNodeType) {
1135         Either<String, ResultStatusEnum> toscaVersion = findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
1136         if (toscaVersion.isRight()) {
1137             throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE);
1138         }
1139         Map<String, Object> mapToConvert = new HashMap<>();
1140         mapToConvert.put(TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION.getElementName(), toscaVersion.left().value());
1141         final Map<String, Object> nodeTypes = getNodeTypesFromTemplate(mappedToscaTemplate, substitutableAsNodeType);
1142         createNodeTypes(yamlName, resource, needLock, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, mapToConvert,
1143                 nodeTypes);
1144         return csarInfo.getCreatedNodes();
1145     }
1146
1147     private Map<String, Object> getNodeTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, final String substitutableAsNodeType) {
1148         final Map<String, Object> nodeTypes = getAllNodeTypesInTemplate(mappedToscaTemplate);
1149         if (StringUtils.isNotEmpty(substitutableAsNodeType)) {
1150             nodeTypes.remove(substitutableAsNodeType);
1151         }
1152         return nodeTypes;
1153     }
1154
1155     @SuppressWarnings("unchecked")
1156     private Map<String, Object> getSubstitutableAsNodeTypeFromTemplate(final Map<String, Object> mappedToscaTemplate,
1157                                                                        final String substitutableAsNodeType) {
1158         return (Map<String, Object>) getAllNodeTypesInTemplate(mappedToscaTemplate).get(substitutableAsNodeType);
1159     }
1160
1161     private Map<String, Object> getAllNodeTypesInTemplate(final Map<String, Object> mappedToscaTemplate) {
1162         return ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES).left().orValue(HashMap::new);
1163     }
1164
1165     private void createModel(final Resource resource, final String vfResourcename) {
1166         final String nameForGeneratedModel = resource.getModel() + "_" + vfResourcename + resource.getCsarVersion();
1167         Model model = new Model(nameForGeneratedModel, resource.getModel(), ModelTypeEnum.NORMATIVE_EXTENSION);
1168         modelBusinessLogic.createModel(model);
1169         resource.setModel(nameForGeneratedModel);
1170     }
1171
1172     private Map<String, Object> getDatatypesToCreate(final String model, final Map<String, Object> dataTypes) {
1173         final Map<String, Object> dataTypesToCreate = new HashMap<>();
1174         for (final String dataType : dataTypes.keySet()) {
1175             final Either<DataTypeDefinition, StorageOperationStatus> result =
1176                     propertyOperation.getDataTypeByName(dataType, model);
1177             if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
1178                 dataTypesToCreate.put(dataType, dataTypes.get(dataType));
1179             }
1180         }
1181         return dataTypesToCreate;
1182     }
1183
1184     private Map<String, Object> getPolicytypesToCreate(final String model, final Map<String, Object> policyTypes) {
1185         final Map<String, Object> policyTypesToCreate = new HashMap<>();
1186         for (final String policyType : policyTypes.keySet()) {
1187             final Either<PolicyTypeDefinition, StorageOperationStatus> result =
1188                     policyTypeOperation.getLatestPolicyTypeByType(policyType, model);
1189             if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
1190                 policyTypesToCreate.put(policyType, policyTypes.get(policyType));
1191             }
1192         }
1193         return policyTypesToCreate;
1194     }
1195
1196     private void createNodeTypes(String yamlName, Resource resource, boolean needLock,
1197                                  Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
1198                                  List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1199                                  Map<String, Object> mapToConvert, Map<String, Object> nodeTypes) {
1200         Iterator<Entry<String, Object>> nodesNameValueIter = nodeTypes.entrySet().iterator();
1201         Resource vfcCreated = null;
1202         while (nodesNameValueIter.hasNext()) {
1203             Entry<String, Object> nodeType = nodesNameValueIter.next();
1204             Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle =
1205                     nodeTypesArtifactsToHandle == null || nodeTypesArtifactsToHandle.isEmpty() ? null : nodeTypesArtifactsToHandle.get(nodeType.getKey());
1206             if (nodeTypesInfo.containsKey(nodeType.getKey())) {
1207                 log.trace("************* Going to handle nested vfc {}", nodeType.getKey());
1208                 vfcCreated = handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
1209                         nodeType.getKey());
1210                 log.trace("************* Finished to handle nested vfc {}", nodeType.getKey());
1211             } else if (csarInfo.getCreatedNodesToscaResourceNames() != null && !csarInfo.getCreatedNodesToscaResourceNames()
1212                     .containsKey(nodeType.getKey())) {
1213                 log.trace("************* Going to create node {}", nodeType.getKey());
1214                 ImmutablePair<Resource, ActionStatus> resourceCreated = createNodeTypeResourceFromYaml(yamlName, nodeType, csarInfo.getModifier(),
1215                         mapToConvert, resource, needLock, nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, true, csarInfo, true);
1216                 log.debug("************* Finished to create node {}", nodeType.getKey());
1217                 vfcCreated = resourceCreated.getLeft();
1218                 csarInfo.getCreatedNodesToscaResourceNames().put(nodeType.getKey(), vfcCreated.getToscaResourceName());
1219             }
1220             if (vfcCreated != null) {
1221                 csarInfo.getCreatedNodes().put(nodeType.getKey(), vfcCreated);
1222             }
1223             mapToConvert.remove(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName());
1224         }
1225     }
1226
1227     private Resource handleNestedVfc(Resource resource, Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1228                                      List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1229                                      String nodeName) {
1230         String yamlName = nodesInfo.get(nodeName).getTemplateFileName();
1231         Map<String, Object> nestedVfcJsonMap = nodesInfo.get(nodeName).getMappedToscaTemplate();
1232         log.debug("************* Going to create node types from yaml {}", yamlName);
1233         createResourcesFromYamlNodeTypesList(yamlName, resource, nestedVfcJsonMap, false, nodesArtifactsToHandle, createdArtifacts,
1234                 Collections.emptyMap(), csarInfo, resource.getModel());
1235         log.debug("************* Finished to create node types from yaml {}", yamlName);
1236         if (nestedVfcJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE.getElementName())) {
1237             log.debug("************* Going to handle complex VFC from yaml {}", yamlName);
1238             resource = handleComplexVfc(resource, nodesArtifactsToHandle, createdArtifacts, nodesInfo, csarInfo, nodeName, yamlName);
1239         }
1240         return resource;
1241     }
1242
1243     private Resource handleComplexVfc(final Resource resource,
1244                                       final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1245                                       final List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1246                                       final String nodeName, final String yamlName) {
1247         Resource oldComplexVfc = null;
1248         Resource newComplexVfc = buildValidComplexVfc(resource, csarInfo, nodeName, nodesInfo);
1249         Either<Resource, StorageOperationStatus> oldComplexVfcRes = toscaOperationFacade
1250                 .getFullLatestComponentByToscaResourceName(newComplexVfc.getToscaResourceName());
1251         if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() == StorageOperationStatus.NOT_FOUND) {
1252             oldComplexVfcRes = toscaOperationFacade.getFullLatestComponentByToscaResourceName(
1253                     buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getRight());
1254         }
1255         if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() != StorageOperationStatus.NOT_FOUND) {
1256             log.debug("Failed to fetch previous complex VFC by tosca resource name {}. Status is {}. ", newComplexVfc.getToscaResourceName(),
1257                     oldComplexVfcRes.right().value());
1258             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1259         } else if (oldComplexVfcRes.isLeft()) {
1260             log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
1261             final Either<Boolean, ResponseFormat> eitherValidation = validateNestedDerivedFromDuringUpdate(oldComplexVfcRes.left().value(),
1262                     newComplexVfc, ValidationUtils.hasBeenCertified(oldComplexVfcRes.left().value().getVersion()));
1263             if (eitherValidation.isLeft()) {
1264                 oldComplexVfc = oldComplexVfcRes.left().value();
1265             }
1266         }
1267         newComplexVfc = handleComplexVfc(nodesArtifactsToHandle, createdArtifacts, nodesInfo, csarInfo, nodeName, yamlName, oldComplexVfc,
1268                 newComplexVfc);
1269         csarInfo.getCreatedNodesToscaResourceNames().put(nodeName, newComplexVfc.getToscaResourceName());
1270         final LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT,
1271                 LifecycleChanceActionEnum.CREATE_FROM_CSAR);
1272         log.debug("Going to certify cvfc {}. ", newComplexVfc.getName());
1273         final Resource result = propagateStateToCertified(csarInfo.getModifier(), newComplexVfc, lifecycleChangeInfo, true, false, true);
1274         csarInfo.getCreatedNodes().put(nodeName, result);
1275         csarInfo.removeNodeFromQueue();
1276         return result;
1277     }
1278
1279     private Resource handleComplexVfc(Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1280                                       List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1281                                       String nodeName, String yamlName, Resource oldComplexVfc, Resource newComplexVfc) {
1282         Resource handleComplexVfcRes;
1283         Map<String, Object> mappedToscaTemplate = nodesInfo.get(nodeName).getMappedToscaTemplate();
1284         String yamlContent = new String(csarInfo.getCsar().get(yamlName));
1285         Map<String, NodeTypeInfo> newNodeTypesInfo = nodesInfo.entrySet().stream().collect(toMap(Entry::getKey, e -> e.getValue().getUnmarkedCopy()));
1286         CsarInfo.markNestedVfc(mappedToscaTemplate, newNodeTypesInfo);
1287         if (oldComplexVfc == null) {
1288             handleComplexVfcRes = createResourceFromYaml(newComplexVfc, yamlContent, yamlName, newNodeTypesInfo, csarInfo, nodesArtifactsToHandle,
1289                     false, true, nodeName);
1290         } else {
1291             handleComplexVfcRes = updateResourceFromYaml(oldComplexVfc, newComplexVfc, AuditingActionEnum.UPDATE_RESOURCE_METADATA, createdArtifacts,
1292                     yamlContent, yamlName, csarInfo, newNodeTypesInfo, nodesArtifactsToHandle, nodeName, true);
1293         }
1294         return handleComplexVfcRes;
1295     }
1296
1297     private Resource buildValidComplexVfc(Resource resource, CsarInfo csarInfo, String nodeName, Map<String, NodeTypeInfo> nodesInfo) {
1298         Resource complexVfc = buildComplexVfcMetadata(resource, csarInfo, nodeName, nodesInfo);
1299         log.debug("************* Going to validate complex VFC from yaml {}", complexVfc.getName());
1300         csarInfo.addNodeToQueue(nodeName);
1301         return validateResourceBeforeCreate(complexVfc, csarInfo.getModifier(), AuditingActionEnum.IMPORT_RESOURCE, true, csarInfo);
1302     }
1303
1304     private String getNodeTypeActualName(final String nodeTypefullName, final String nodeTypeNamePrefix) {
1305         final String nameWithouNamespacePrefix = nodeTypefullName.substring(nodeTypeNamePrefix.length());
1306         final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
1307         if (findTypes.length > 1) {
1308             final String resourceType = findTypes[0];
1309             return nameWithouNamespacePrefix.substring(resourceType.length());
1310         }
1311         return nameWithouNamespacePrefix;
1312     }
1313
1314     private ImmutablePair<Resource, ActionStatus> createNodeTypeResourceFromYaml(final String yamlName, final Entry<String, Object> nodeNameValue,
1315                                                                                  User user, final Map<String, Object> mapToConvert,
1316                                                                                  final Resource resourceVf, final boolean needLock,
1317                                                                                  final Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
1318                                                                                  final List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1319                                                                                  final boolean forceCertificationAllowed, final CsarInfo csarInfo,
1320                                                                                  final boolean isNested) {
1321         final UploadResourceInfo resourceMetaData = fillResourceMetadata(yamlName, resourceVf, nodeNameValue.getKey(), user);
1322         final String singleVfcYaml = buildNodeTypeYaml(nodeNameValue, mapToConvert, resourceMetaData.getResourceType(), csarInfo);
1323         user = validateUser(user, "CheckIn Resource", resourceVf, AuditingActionEnum.CHECKIN_RESOURCE, true);
1324         return createResourceFromNodeType(singleVfcYaml, resourceMetaData, user, true, needLock, nodeTypeArtifactsToHandle,
1325                 nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeNameValue.getKey(), isNested);
1326     }
1327
1328     private String buildNodeTypeYaml(final Entry<String, Object> nodeNameValue, final Map<String, Object> mapToConvert, final String nodeResourceType,
1329                                      final CsarInfo csarInfo) {
1330         // We need to create a Yaml from each node_types in order to create
1331
1332         // resource from each node type using import normative flow.
1333         final DumperOptions options = new DumperOptions();
1334         options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
1335         final Yaml yaml = new Yaml(options);
1336         final Map<String, Object> node = new HashMap<>();
1337         node.put(buildNestedToscaResourceName(nodeResourceType, csarInfo.getVfResourceName(), nodeNameValue.getKey()).getLeft(),
1338                 nodeNameValue.getValue());
1339         mapToConvert.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), node);
1340         return yaml.dumpAsMap(mapToConvert);
1341     }
1342
1343     public Boolean validateResourceCreationFromNodeType(Resource resource, User creator) {
1344         validateDerivedFromNotEmpty(creator, resource, AuditingActionEnum.CREATE_RESOURCE);
1345         return true;
1346     }
1347
1348     public ImmutablePair<Resource, ActionStatus> createResourceFromNodeType(String nodeTypeYaml, UploadResourceInfo resourceMetaData, User creator,
1349                                                                             boolean isInTransaction, boolean needLock,
1350                                                                             Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
1351                                                                             List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1352                                                                             boolean forceCertificationAllowed, CsarInfo csarInfo, String nodeName,
1353                                                                             boolean isNested) {
1354         LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT,
1355                 LifecycleChanceActionEnum.CREATE_FROM_CSAR);
1356         Function<Resource, Boolean> validator = resource -> validateResourceCreationFromNodeType(resource, creator);
1357         return resourceImportManager
1358                 .importCertifiedResource(nodeTypeYaml, resourceMetaData, creator, validator, lifecycleChangeInfo, isInTransaction, true, needLock,
1359                         nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeName, isNested);
1360     }
1361
1362     /**
1363      * Validates if a given node type name has a valid prefix.
1364      *
1365      * @param nodeName                     node name from definition file
1366      * @param definedResourceNamespaceList is a list of all node type name prefix allowed
1367      * @return a valid node type name prefix if it`s found
1368      */
1369     public Optional<String> validateNodeTypeNamePrefix(final String nodeName, final List<String> definedResourceNamespaceList) {
1370         for (final String validNamespace : definedResourceNamespaceList) {
1371             if (nodeName.startsWith(validNamespace)) {
1372                 return Optional.of(validNamespace);
1373             }
1374         }
1375         return Optional.empty();
1376     }
1377
1378     private List<String> getDefinedNodeTypeNamespaceList() {
1379         return ConfigurationManager.getConfigurationManager().getConfiguration().getDefinedResourceNamespace();
1380     }
1381
1382     private UploadResourceInfo fillResourceMetadata(final String yamlName, final Resource resourceVf, final String nodeName, final User user) {
1383         final UploadResourceInfo resourceMetaData = new UploadResourceInfo();
1384         final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeName);
1385         log.debug("Node type Name prefix {}", nodeTypeNamePrefix);
1386         if (!nodeName.startsWith(nodeTypeNamePrefix)) {
1387             log.debug("invalid nodeName:{} does not start with {}.", nodeName, getDefinedNodeTypeNamespaceList());
1388             throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeName);
1389         }
1390         final String actualName = this.getNodeTypeActualName(nodeName, nodeTypeNamePrefix);
1391         final String namePrefix = nodeName.replace(actualName, "");
1392         String resourceType = namePrefix.substring(nodeTypeNamePrefix.length());
1393         log.debug("initial  namePrefix:{} resourceType {}. nodeName {} , actualName {} prefix {}", namePrefix, resourceType, nodeName, actualName,
1394                 nodeTypeNamePrefix);
1395         // if we import from csar, the node_type name can be
1396
1397         // org.openecomp.resource.abstract.node_name - in this case we always
1398
1399         // create a vfc
1400         if (resourceType.equals(Constants.ABSTRACT)) {
1401             resourceType = ResourceTypeEnum.VFC.name().toLowerCase();
1402         }
1403         if (!ResourceTypeEnum.containsIgnoreCase(resourceType)) {
1404             resourceType = ResourceTypeEnum.VFC.name().toLowerCase();
1405         }
1406         // validating type
1407         if (!ResourceTypeEnum.containsName(resourceType.toUpperCase())) {
1408             log.debug("invalid resourceType:{} the type is not one of the valide types:{}.", resourceType.toUpperCase(), ResourceTypeEnum.values());
1409             throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeName);
1410         }
1411         // Setting name
1412         resourceMetaData.setName(resourceVf.getSystemName() + actualName);
1413         // Setting type from name
1414         final String type = resourceType.toUpperCase();
1415         resourceMetaData.setResourceType(type);
1416         resourceMetaData.setDescription(ImportUtils.Constants.INNER_VFC_DESCRIPTION);
1417         resourceMetaData.setIcon(ImportUtils.Constants.DEFAULT_ICON);
1418         resourceMetaData.setContactId(user.getUserId());
1419         resourceMetaData.setVendorName(resourceVf.getVendorName());
1420         resourceMetaData.setVendorRelease(resourceVf.getVendorRelease());
1421         resourceMetaData.setModel(resourceVf.getModel());
1422         // Setting tag
1423         final List<String> tags = new ArrayList<>();
1424         tags.add(resourceMetaData.getName());
1425         resourceMetaData.setTags(tags);
1426         // Setting category
1427         final CategoryDefinition category = new CategoryDefinition();
1428         category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME);
1429         final SubCategoryDefinition subCategory = new SubCategoryDefinition();
1430         subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY);
1431         category.addSubCategory(subCategory);
1432         final List<CategoryDefinition> categories = new ArrayList<>();
1433         categories.add(category);
1434         resourceMetaData.setCategories(categories);
1435         return resourceMetaData;
1436     }
1437
1438     private Resource buildComplexVfcMetadata(final Resource resourceVf, final CsarInfo csarInfo, final String nodeName,
1439                                              final Map<String, NodeTypeInfo> nodesInfo) {
1440         final Resource cvfc = new Resource();
1441         final NodeTypeInfo nodeTypeInfo = nodesInfo.get(nodeName);
1442         cvfc.setName(buildCvfcName(csarInfo.getVfResourceName(), nodeName));
1443         cvfc.setNormalizedName(ValidationUtils.normaliseComponentName(cvfc.getName()));
1444         cvfc.setSystemName(ValidationUtils.convertToSystemName(cvfc.getName()));
1445         cvfc.setResourceType(ResourceTypeEnum.CVFC);
1446         cvfc.setAbstract(true);
1447         cvfc.setDerivedFrom(nodeTypeInfo.getDerivedFrom());
1448         cvfc.setDescription(ImportUtils.Constants.CVFC_DESCRIPTION);
1449         cvfc.setIcon(ImportUtils.Constants.DEFAULT_ICON);
1450         cvfc.setContactId(csarInfo.getModifier().getUserId());
1451         cvfc.setCreatorUserId(csarInfo.getModifier().getUserId());
1452         cvfc.setVendorName(resourceVf.getVendorName());
1453         cvfc.setVendorRelease(resourceVf.getVendorRelease());
1454         cvfc.setModel(resourceVf.getModel());
1455         cvfc.setResourceVendorModelNumber(resourceVf.getResourceVendorModelNumber());
1456         cvfc.setToscaResourceName(buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getLeft());
1457         cvfc.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
1458         final List<String> tags = new ArrayList<>();
1459         tags.add(cvfc.getName());
1460         cvfc.setTags(tags);
1461         final CategoryDefinition category = new CategoryDefinition();
1462         category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME);
1463         SubCategoryDefinition subCategory = new SubCategoryDefinition();
1464         subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY);
1465         category.addSubCategory(subCategory);
1466         final List<CategoryDefinition> categories = new ArrayList<>();
1467         categories.add(category);
1468         cvfc.setCategories(categories);
1469         cvfc.setVersion(ImportUtils.Constants.FIRST_NON_CERTIFIED_VERSION);
1470         cvfc.setLifecycleState(ImportUtils.Constants.NORMATIVE_TYPE_LIFE_CYCLE_NOT_CERTIFIED_CHECKOUT);
1471         cvfc.setHighestVersion(ImportUtils.Constants.NORMATIVE_TYPE_HIGHEST_VERSION);
1472         return cvfc;
1473     }
1474
1475     private String buildCvfcName(final String resourceVfName, final String nodeName) {
1476         String nameWithouNamespacePrefix = nodeName.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length());
1477         String[] findTypes = nameWithouNamespacePrefix.split("\\.");
1478         String resourceType = findTypes[0];
1479         String resourceName = resourceVfName + "-" + nameWithouNamespacePrefix.substring(resourceType.length() + 1);
1480         return addCvfcSuffixToResourceName(resourceName);
1481     }
1482
1483     private Resource createResourceAndRIsFromYaml(final String yamlName, Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo,
1484                                                   final AuditingActionEnum actionEnum, final boolean isNormative,
1485                                                   final List<ArtifactDefinition> createdArtifacts, final String topologyTemplateYaml,
1486                                                   final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo,
1487                                                   final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1488                                                   final boolean shouldLock, final boolean inTransaction, final String nodeName) {
1489         final List<ArtifactDefinition> nodeTypesNewCreatedArtifacts = new ArrayList<>();
1490         if (shouldLock) {
1491             final Either<Boolean, ResponseFormat> lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE);
1492             if (lockResult.isRight()) {
1493                 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1494                 throw new ByResponseFormatComponentException(lockResult.right().value());
1495             }
1496             log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult);
1497         }
1498         try {
1499             log.trace("************* createResourceFromYaml before full create resource {}", yamlName);
1500             loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1501                     "Starting to add inputs from yaml: {}", yamlName);
1502             if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
1503                 final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
1504                         (Map<String, Object>) new Yaml().load(topologyTemplateYaml), parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1505                 resource.setToscaResourceName(parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1506                 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
1507                         (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
1508                 resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
1509                 generatePropertiesFromGenericType(resource, genericResource);
1510                 generatePropertiesFromNodeType(resource, substitutableAsNodeType);
1511                 final String resourceId = resource.getUniqueId();
1512                 resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
1513                         UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
1514
1515                 createResourcePropertiesOnGraph(resource);
1516                 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo, resource.getModel());
1517
1518                 log.trace("************* Going to create nodes, RI's and Relations  from yaml {}", yamlName);
1519                 loggerSupportability
1520                         .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1521                                 "Start create nodes, RI and Relations  from yaml: {}", yamlName);
1522                 resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
1523                         nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName,
1524                         parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1525             } else {
1526                 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource, null);
1527                 resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
1528                 log.trace("************* createResourceFromYaml after full create resource {}", yamlName);
1529                 log.trace("************* Going to add inputs from yaml {}", yamlName);
1530                 if (resource.shouldGenerateInputs()) {
1531                     generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
1532                 }
1533                 final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs();
1534                 resource = createInputsOnResource(resource, inputs);
1535
1536                 log.trace("************* Finish to add inputs from yaml {}", yamlName);
1537                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1538                         "Finish to add inputs from yaml: {}", yamlName);
1539                 if (resource.getResourceType() == ResourceTypeEnum.PNF) {
1540                     log.trace("************* Adding generic properties to PNF");
1541                     resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties());
1542                     log.trace("************* Adding software information to PNF");
1543                     softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo);
1544                     log.trace("************* Removing non-mano software information file from PNF");
1545                     if (csarInfo.getSoftwareInformationPath().isPresent() && !softwareInformationBusinessLogic.removeSoftwareInformationFile(
1546                             csarInfo)) {
1547                         log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), "catalog-be",
1548                                 "Could not remove the software information file.");
1549                     }
1550                 }
1551                 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo);
1552
1553                 log.trace("************* Going to create nodes, RI's and Relations  from yaml {}", yamlName);
1554                 loggerSupportability
1555                         .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1556                                 "Start create nodes, RI and Relations  from yaml: {}", yamlName);
1557                 resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
1558                         nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName, null);
1559             }
1560             log.trace("************* Finished to create nodes, RI and Relation  from yaml {}", yamlName);
1561             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1562                     "Finished to create nodes, RI and Relation  from yaml: {}", yamlName);
1563             // validate update vf module group names
1564             Optional<Map<String, GroupDefinition>> asdGroups = checkAndCreateAsdTypeVfModules(parsedToscaYamlInfo.getInstances());
1565             Map<String, GroupDefinition> parsedGroups = parsedToscaYamlInfo.getGroups();
1566             if (asdGroups.isPresent()) {
1567                 parsedGroups.putAll(asdGroups.get());
1568             }
1569             final Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic
1570                     .validateUpdateVfGroupNames(parsedGroups, resource.getSystemName());
1571             if (validateUpdateVfGroupNamesRes.isRight()) {
1572                 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1573                 throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value());
1574             }
1575             // add groups to resource
1576             final Map<String, GroupDefinition> groups;
1577             log.trace("************* Going to add groups from yaml {}", yamlName);
1578             loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1579                     "Start to add groups from yaml: {}", yamlName);
1580             if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) {
1581                 groups = validateUpdateVfGroupNamesRes.left().value();
1582             } else {
1583                 groups = parsedGroups;
1584             }
1585             final Either<Resource, ResponseFormat> createGroupsOnResource = createGroupsOnResource(resource, groups);
1586             if (createGroupsOnResource.isRight()) {
1587                 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1588                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1589                         "ERROR while adding groups from yaml: {}", yamlName);
1590                 throw new ByResponseFormatComponentException(createGroupsOnResource.right().value());
1591             }
1592             resource = createGroupsOnResource.left().value();
1593             log.trace("************* Finished to add groups from yaml {}", yamlName);
1594             loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1595                     "Finished to add groups from yaml: {}", yamlName);
1596             log.trace("************* Going to add artifacts from yaml {}", yamlName);
1597             loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1598                     "Started to add artifacts from yaml: {}", yamlName);
1599             log.trace("************* Starting to add policies from yaml {}", yamlName);
1600             Map<String, PolicyDefinition> policies = parsedToscaYamlInfo.getPolicies();
1601             if (MapUtils.isNotEmpty(policies)) {
1602                 resource = createPoliciesOnResource(resource, policies);
1603             }
1604             log.trace("************* Finished to add policies from yaml {}", yamlName);
1605             final NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName,
1606                     nodeTypesArtifactsToCreate);
1607             final Either<Resource, ResponseFormat> createArtifactsEither = createOrUpdateArtifacts(ArtifactOperationEnum.CREATE, createdArtifacts,
1608                     yamlName, csarInfo, resource, nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock);
1609             if (createArtifactsEither.isRight()) {
1610                 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1611                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1612                         "error happened {}", createArtifactsEither.right().value());
1613                 throw new ByResponseFormatComponentException(createArtifactsEither.right().value());
1614             }
1615             loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1616                     "Finished to add artifacts from yaml: " + resource.getToscaResourceName());
1617             final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
1618             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, actionEnum);
1619             ASDCKpiApi.countCreatedResourcesKPI();
1620             return resource;
1621         } catch (final BusinessLogicException e) {
1622             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(),
1623                     "An error has occurred during resource and resource instance creation", e);
1624             rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1625             throw new ByResponseFormatComponentException(e.getResponseFormat());
1626         } catch (final ComponentException e) {
1627             log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ResourceBusinessLogic.class.getName(),
1628                     "An error has occurred during resource and resource instance creation", e);
1629             rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1630             throw new ByResponseFormatComponentException(e.getResponseFormat());
1631         } catch (final Exception e) {
1632             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(),
1633                     "An error has occurred during resource and resource instance creation", e);
1634             rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1635             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1636         } finally {
1637             if (!inTransaction) {
1638                 janusGraphDao.commit();
1639             }
1640             if (shouldLock) {
1641                 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
1642             }
1643         }
1644     }
1645
1646     private Optional<Map<String, GroupDefinition>> checkAndCreateAsdTypeVfModules(Map<String, UploadComponentInstanceInfo> instances) {
1647         Map<String, GroupDefinition> addAsdGroups = new HashMap<>();
1648         if (isNotEmpty(instances) || instances != null) {
1649             for (Map.Entry<String, UploadComponentInstanceInfo> instance : instances.entrySet()) {
1650                 if (isNotEmpty(instance.getValue().getArtifacts()) || instance.getValue().getArtifacts() != null) {
1651                     Map<String, UploadArtifactInfo> artifactsMap = instance.getValue().getArtifacts()
1652                             .get(ToscaTagNamesEnum.ARTIFACTS.getElementName());
1653                     if (isNotEmpty(artifactsMap) || artifactsMap != null) {
1654                         for (Map.Entry<String , UploadArtifactInfo> artifact : artifactsMap.entrySet()) {
1655                             if (artifact.getValue().getType().equals(Constants.ASD_DEPLOYMENT_ITEM)) {
1656                                 GroupDefinition groupDefinition = new GroupDefinition();
1657                                 groupDefinition.setName(artifact.getKey());
1658                                 groupDefinition.setType(Constants.DEFAULT_GROUP_VF_MODULE);
1659                                 addAsdTypeProperties(groupDefinition);
1660                                 addAsdGroups.put(groupDefinition.getName(), groupDefinition);
1661                             }
1662                         }
1663                     }
1664                 }
1665             }
1666         }
1667         return Optional.of(addAsdGroups);
1668     }
1669
1670     private void addAsdTypeProperties(GroupDefinition groupDefinition) {
1671         List<GroupProperty> properties = new ArrayList<>();
1672         GroupProperty propIsBase = new GroupProperty();
1673         propIsBase.setName(Constants.IS_BASE);
1674         propIsBase.setValue("true");
1675         properties.add(propIsBase);
1676         GroupProperty propVfModuleLabel = new GroupProperty();
1677         propVfModuleLabel.setName(Constants.VF_MODULE_LABEL);
1678         propVfModuleLabel.setValue(groupDefinition.getName());
1679         properties.add(propVfModuleLabel);
1680         GroupProperty propVfModuleDescription = new GroupProperty();
1681         propVfModuleDescription.setName(Constants.VF_MODULE_DESCRIPTION);
1682         propVfModuleDescription.setValue("VF Module representing deployment item " + groupDefinition.getName());
1683         properties.add(propVfModuleDescription);
1684         GroupProperty propMinVfModuleInstances = new GroupProperty();
1685         propMinVfModuleInstances.setName(Constants.MIN_VF_MODULE_INSTANCES);
1686         propMinVfModuleInstances.setValue("1");
1687         properties.add(propMinVfModuleInstances);
1688         GroupProperty propMaxVfModuleInstances = new GroupProperty();
1689         propMaxVfModuleInstances.setName(Constants.MAX_VF_MODULE_INSTANCES);
1690         propMaxVfModuleInstances.setValue("1");
1691         properties.add(propMaxVfModuleInstances);
1692         GroupProperty propInitialCount = new GroupProperty();
1693         propInitialCount.setName(Constants.INITIAL_COUNT);
1694         propInitialCount.setValue("1");
1695         properties.add(propInitialCount);
1696         GroupProperty propVfModuleType = new GroupProperty();
1697         propVfModuleType.setName(Constants.VF_MODULE_TYPE);
1698         propVfModuleType.setValue("Base");
1699         properties.add(propVfModuleType);
1700         GroupProperty propVolumeGroup = new GroupProperty();
1701         propVolumeGroup.setName(Constants.VOLUME_GROUP);
1702         propVolumeGroup.setValue("false");
1703         properties.add(propVolumeGroup);
1704         groupDefinition.convertFromGroupProperties(properties);
1705     }
1706
1707     private boolean processSubstitutableAsNodeType(final Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo) {
1708         return !resource.getResourceType().isAtomicType() && StringUtils.isNotEmpty(resource.getModel())
1709                 && parsedToscaYamlInfo.getSubstitutionMappingNodeType() != null;
1710     }
1711
1712     private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo) {
1713         return getInstancesToCreate(parsedToscaYamlInfo, null);
1714     }
1715
1716     private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo, final String model) {
1717         if (StringUtils.isEmpty(model) || StringUtils.isEmpty(parsedToscaYamlInfo.getSubstitutionMappingNodeType())) {
1718             return parsedToscaYamlInfo.getInstances();
1719         }
1720         return parsedToscaYamlInfo.getInstances().entrySet().stream()
1721                 .filter(entry -> !parsedToscaYamlInfo.getSubstitutionMappingNodeType().equals(entry.getValue().getType()))
1722                 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
1723     }
1724
1725     private void rollback(boolean inTransaction, Resource resource, List<ArtifactDefinition> createdArtifacts,
1726                           List<ArtifactDefinition> nodeTypesNewCreatedArtifacts) {
1727         if (!inTransaction) {
1728             janusGraphDao.rollback();
1729         }
1730         if (isNotEmpty(createdArtifacts) && isNotEmpty(nodeTypesNewCreatedArtifacts)) {
1731             createdArtifacts.addAll(nodeTypesNewCreatedArtifacts);
1732             log.debug("Found {} newly created artifacts to deleted, the component name: {}", createdArtifacts.size(), resource.getName());
1733         }
1734     }
1735
1736     private Resource getResourceWithGroups(String resourceId) {
1737         ComponentParametersView filter = new ComponentParametersView();
1738         filter.setIgnoreGroups(false);
1739         Either<Resource, StorageOperationStatus> updatedResource = toscaOperationFacade.getToscaElement(resourceId, filter);
1740         if (updatedResource.isRight()) {
1741             rollbackWithException(componentsUtils.convertFromStorageResponse(updatedResource.right().value()), resourceId);
1742         }
1743         return updatedResource.left().value();
1744     }
1745
1746     private Either<Resource, ResponseFormat> createGroupsOnResource(Resource resource, Map<String, GroupDefinition> groups) {
1747         if (groups != null && !groups.isEmpty()) {
1748             List<GroupDefinition> groupsAsList = updateGroupsMembersUsingResource(groups, resource);
1749             handleGroupsProperties(resource, groups);
1750             fillGroupsFinalFields(groupsAsList);
1751             Either<List<GroupDefinition>, ResponseFormat> createGroups = groupBusinessLogic.createGroups(resource, groupsAsList, true);
1752             if (createGroups.isRight()) {
1753                 return Either.right(createGroups.right().value());
1754             }
1755         }
1756         return Either.left(resource);
1757     }
1758
1759     private void handleGroupsProperties(Resource resource, Map<String, GroupDefinition> groups) {
1760         List<InputDefinition> inputs = resource.getInputs();
1761         if (MapUtils.isNotEmpty(groups)) {
1762             groups.values().stream().filter(g -> isNotEmpty(g.getProperties())).flatMap(g -> g.getProperties().stream())
1763                     .forEach(p -> handleGetInputs(p, inputs));
1764         }
1765     }
1766
1767     private Resource createPoliciesOnResource(Resource resource, Map<String, PolicyDefinition> policies) {
1768         policyBusinessLogic.createPoliciesFromParsedCsar(resource, policies);
1769         return resource;
1770     }
1771
1772     private void handleGetInputs(PropertyDataDefinition property, List<InputDefinition> inputs) {
1773         if (isNotEmpty(property.getGetInputValues())) {
1774             if (inputs == null || inputs.isEmpty()) {
1775                 log.debug("Failed to add property {} to group. Inputs list is empty ", property);
1776                 rollbackWithException(ActionStatus.INPUTS_NOT_FOUND,
1777                         property.getGetInputValues().stream().map(GetInputValueDataDefinition::getInputName).collect(toList()).toString());
1778             }
1779             ListIterator<GetInputValueDataDefinition> getInputValuesIter = property.getGetInputValues().listIterator();
1780             while (getInputValuesIter.hasNext()) {
1781                 GetInputValueDataDefinition getInput = getInputValuesIter.next();
1782                 Either<InputDefinition, RuntimeException> inputEither = findInputByName(inputs, getInput);
1783                 if (inputEither.isRight()) {
1784                     throw inputEither.right().value();
1785                 } else {
1786                     InputDefinition input = inputEither.left().value();
1787                     getInput.setInputId(input.getUniqueId());
1788                     if (getInput.getGetInputIndex() != null) {
1789                         GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
1790                         Either<InputDefinition, RuntimeException> newInputEither = findInputByName(inputs, getInputIndex);
1791                         if (newInputEither.isRight()) {
1792                             throw newInputEither.right().value();
1793                         } else {
1794                             InputDefinition newInput = newInputEither.left().value();
1795                             getInputIndex.setInputId(newInput.getUniqueId());
1796                         }
1797                         getInputValuesIter.add(getInputIndex);
1798                     }
1799                 }
1800             }
1801         }
1802     }
1803
1804     <T> Either<T, RuntimeException> rollbackWithEither(final ActionStatus actionStatus, final String... params) {
1805         return rollbackWithEither(janusGraphDao, actionStatus, params);
1806     }
1807
1808     private Either<InputDefinition, RuntimeException> findInputByName(List<InputDefinition> inputs, GetInputValueDataDefinition getInput) {
1809         final String inputName = getInput != null ? getInput.getInputName() : "";
1810         if (inputs == null || inputs.isEmpty()) {
1811             log.debug("#findInputByName - Inputs list is empty");
1812             return rollbackWithEither(ActionStatus.INPUTS_NOT_FOUND, inputName);
1813         } else {
1814             Optional<InputDefinition> inputOpt = inputs.stream().filter(p -> p.getName().equals(inputName)).findFirst();
1815             if (inputOpt.isEmpty()) {
1816                 log.debug("#findInputByName - Failed to find the input {} ", inputName);
1817                 return rollbackWithEither(ActionStatus.INPUTS_NOT_FOUND, inputName);
1818             } else {
1819                 return Either.left(inputOpt.get());
1820             }
1821         }
1822     }
1823
1824     private void fillGroupsFinalFields(List<GroupDefinition> groupsAsList) {
1825         groupsAsList.forEach(groupDefinition -> {
1826             groupDefinition.setInvariantName(groupDefinition.getName());
1827             groupDefinition.setCreatedFrom(CreatedFrom.CSAR);
1828         });
1829     }
1830
1831     private Resource updateGroupsOnResource(Resource resource, Map<String, GroupDefinition> groups) {
1832         if (isEmpty(groups)) {
1833             return resource;
1834         }
1835         return updateOrCreateGroups(resource, groups);
1836     }
1837
1838     private Resource updateOrCreateGroups(Resource resource, Map<String, GroupDefinition> groups) {
1839         List<GroupDefinition> groupsFromResource = resource.getGroups();
1840         List<GroupDefinition> groupsAsList = updateGroupsMembersUsingResource(groups, resource);
1841         List<GroupDefinition> groupsToUpdate = new ArrayList<>();
1842         List<GroupDefinition> groupsToDelete = new ArrayList<>();
1843         List<GroupDefinition> groupsToCreate = new ArrayList<>();
1844         if (isNotEmpty(groupsFromResource)) {
1845             addGroupsToCreateOrUpdate(groupsFromResource, groupsAsList, groupsToUpdate, groupsToCreate);
1846             addGroupsToDelete(groupsFromResource, groupsAsList, groupsToDelete);
1847         } else {
1848             groupsToCreate.addAll(groupsAsList);
1849         }
1850         if (isNotEmpty(groupsToCreate)) {
1851             fillGroupsFinalFields(groupsToCreate);
1852             if (isNotEmpty(groupsFromResource)) {
1853                 groupBusinessLogic.addGroups(resource, groupsToCreate, true).left().on(this::throwComponentException);
1854             } else {
1855                 groupBusinessLogic.createGroups(resource, groupsToCreate, true).left().on(this::throwComponentException);
1856             }
1857         }
1858         if (isNotEmpty(groupsToDelete)) {
1859             groupBusinessLogic.deleteGroups(resource, groupsToDelete).left().on(this::throwComponentException);
1860         }
1861         if (isNotEmpty(groupsToUpdate)) {
1862             groupBusinessLogic.updateGroups(resource, groupsToUpdate, true).left().on(this::throwComponentException);
1863         }
1864         return resource;
1865     }
1866
1867     private void addGroupsToDelete(List<GroupDefinition> groupsFromResource, List<GroupDefinition> groupsAsList,
1868                                    List<GroupDefinition> groupsToDelete) {
1869         for (GroupDefinition group : groupsFromResource) {
1870             Optional<GroupDefinition> op = groupsAsList.stream().filter(p -> p.getInvariantName().equalsIgnoreCase(group.getInvariantName()))
1871                     .findAny();
1872             if (op.isEmpty() && (group.getArtifacts() == null || group.getArtifacts().isEmpty())) {
1873                 groupsToDelete.add(group);
1874             }
1875         }
1876     }
1877
1878     private void addGroupsToCreateOrUpdate(List<GroupDefinition> groupsFromResource, List<GroupDefinition> groupsAsList,
1879                                            List<GroupDefinition> groupsToUpdate, List<GroupDefinition> groupsToCreate) {
1880         for (GroupDefinition group : groupsAsList) {
1881             Optional<GroupDefinition> op = groupsFromResource.stream().filter(p -> p.getInvariantName().equalsIgnoreCase(group.getInvariantName()))
1882                     .findAny();
1883             if (op.isPresent()) {
1884                 GroupDefinition groupToUpdate = op.get();
1885                 groupToUpdate.setMembers(group.getMembers());
1886                 groupToUpdate.setCapabilities(group.getCapabilities());
1887                 groupToUpdate.setProperties(group.getProperties());
1888                 groupsToUpdate.add(groupToUpdate);
1889             } else {
1890                 groupsToCreate.add(group);
1891             }
1892         }
1893     }
1894
1895     private Resource createInputsOnResource(Resource resource, Map<String, InputDefinition> inputs) {
1896         List<InputDefinition> resourceProperties = resource.getInputs();
1897         if (MapUtils.isNotEmpty(inputs) || isNotEmpty(resourceProperties)) {
1898             Either<List<InputDefinition>, ResponseFormat> createInputs = inputsBusinessLogic.createInputsInGraph(inputs, resource);
1899             if (createInputs.isRight()) {
1900                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1901                         "failed to add inputs from yaml: {}", createInputs.right().value());
1902                 throw new ByResponseFormatComponentException(createInputs.right().value());
1903             }
1904             resource.setInputs(createInputs.left().value());
1905         }
1906         return resource;
1907     }
1908
1909     private Resource generatePropertiesFromNodeType(final Resource resource, final Map<String, Object> nodeType) {
1910         final Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils.getProperties(nodeType);
1911         if (properties.isLeft()) {
1912             final List<PropertyDefinition> propertiesList = new ArrayList<>();
1913             final Map<String, PropertyDefinition> value = properties.left().value();
1914             if (value != null) {
1915                 for (Entry<String, PropertyDefinition> entry : value.entrySet()) {
1916                     final String name = entry.getKey();
1917                     final PropertyDefinition propertyDefinition = entry.getValue();
1918                     propertyDefinition.setName(name);
1919                     propertiesList.add(propertyDefinition);
1920                     resource.getProperties().removeIf(p -> p.getName().equals(name));
1921                 }
1922             }
1923             resource.getProperties().addAll(propertiesList);
1924         }
1925         return resource;
1926     }
1927
1928     private Resource createResourcePropertiesOnGraph(final Resource resource) {
1929         final List<PropertyDefinition> resourceProperties = resource.getProperties();
1930         for (PropertyDefinition propertyDefinition : resourceProperties) {
1931             final Either<PropertyDefinition, StorageOperationStatus> addPropertyEither = toscaOperationFacade
1932                     .addPropertyToComponent(propertyDefinition.getName(), propertyDefinition, resource);
1933
1934             if (addPropertyEither.isRight()) {
1935                 final String error = String.format("failed to add properties from yaml: {}", addPropertyEither.right().value());
1936                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_PROPERTIES, resource.getComponentMetadataForSupportLog(),
1937                         StatusCode.ERROR,
1938                         error);
1939                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addPropertyEither.right().value()), error);
1940             }
1941         }
1942         return resource;
1943     }
1944
1945     private List<GroupDefinition> updateGroupsMembersUsingResource(Map<String, GroupDefinition> groups, Resource component) {
1946         List<GroupDefinition> result = new ArrayList<>();
1947         List<ComponentInstance> componentInstances = component.getComponentInstances();
1948         if (groups != null) {
1949             Either<Boolean, ResponseFormat> validateCyclicGroupsDependencies = validateCyclicGroupsDependencies(groups);
1950             if (validateCyclicGroupsDependencies.isRight()) {
1951                 throw new ByResponseFormatComponentException(validateCyclicGroupsDependencies.right().value());
1952             }
1953             for (Entry<String, GroupDefinition> entry : groups.entrySet()) {
1954                 String groupName = entry.getKey();
1955                 GroupDefinition groupDefinition = entry.getValue();
1956                 GroupDefinition updatedGroupDefinition = new GroupDefinition(groupDefinition);
1957                 updatedGroupDefinition.setMembers(null);
1958                 Map<String, String> members = groupDefinition.getMembers();
1959                 if (members != null) {
1960                     updateGroupMembers(groups, updatedGroupDefinition, component, componentInstances, groupName, members);
1961                 }
1962                 result.add(updatedGroupDefinition);
1963             }
1964         }
1965         return result;
1966     }
1967
1968     private void updateGroupMembers(Map<String, GroupDefinition> groups, GroupDefinition updatedGroupDefinition, Resource component,
1969                                     List<ComponentInstance> componentInstances, String groupName, Map<String, String> members) {
1970         Set<String> compInstancesNames = members.keySet();
1971         if (CollectionUtils.isEmpty(componentInstances)) {
1972             String membersAstString = String.join(",", compInstancesNames);
1973             log.debug("The members: {}, in group: {}, cannot be found in component {}. There are no component instances.", membersAstString,
1974                     groupName, component.getNormalizedName());
1975             throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1976                     component.getNormalizedName(), getComponentTypeForResponse(component));
1977         }
1978         // Find all component instances with the member names
1979         Map<String, String> memberNames = componentInstances.stream().collect(toMap(ComponentInstance::getName, ComponentInstance::getUniqueId));
1980         memberNames.putAll(groups.keySet().stream().collect(toMap(g -> g, g -> "")));
1981         Map<String, String> relevantInstances = memberNames.entrySet().stream().filter(n -> compInstancesNames.contains(n.getKey()))
1982                 .collect(toMap(Entry::getKey, Entry::getValue));
1983         if (relevantInstances.size() != compInstancesNames.size()) {
1984             List<String> foundMembers = new ArrayList<>(relevantInstances.keySet());
1985             foundMembers.forEach(compInstancesNames::remove);
1986             String membersAstString = String.join(",", compInstancesNames);
1987             log.debug("The members: {}, in group: {}, cannot be found in component: {}", membersAstString, groupName, component.getNormalizedName());
1988             throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1989                     component.getNormalizedName(), getComponentTypeForResponse(component));
1990         }
1991         updatedGroupDefinition.setMembers(relevantInstances);
1992     }
1993
1994     /**
1995      * This Method validates that there is no cyclic group dependencies. meaning group A as member in group B which is member in group A
1996      *
1997      * @param allGroups
1998      * @return
1999      */
2000     private Either<Boolean, ResponseFormat> validateCyclicGroupsDependencies(Map<String, GroupDefinition> allGroups) {
2001         Either<Boolean, ResponseFormat> result = Either.left(true);
2002         try {
2003             Iterator<Entry<String, GroupDefinition>> allGroupsItr = allGroups.entrySet().iterator();
2004             while (allGroupsItr.hasNext() && result.isLeft()) {
2005                 Entry<String, GroupDefinition> groupAEntry = allGroupsItr.next();
2006                 // Fetches a group member A
2007                 String groupAName = groupAEntry.getKey();
2008                 // Finds all group members in group A
2009                 Set<String> allGroupAMembersNames = new HashSet<>();
2010                 fillAllGroupMemebersRecursivly(groupAEntry.getKey(), allGroups, allGroupAMembersNames);
2011                 // If A is a group member of itself found cyclic dependency
2012                 if (allGroupAMembersNames.contains(groupAName)) {
2013                     ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GROUP_HAS_CYCLIC_DEPENDENCY, groupAName);
2014                     result = Either.right(responseFormat);
2015                 }
2016             }
2017         } catch (Exception e) {
2018             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2019             result = Either.right(responseFormat);
2020             log.debug("Exception occurred when validateCyclicGroupsDependencies, error is:{}", e.getMessage(), e);
2021         }
2022         return result;
2023     }
2024
2025     /**
2026      * This Method fills recursively the set groupMembers with all the members of the given group which are also of type group.
2027      *
2028      * @param groupName
2029      * @param allGroups
2030      * @param allGroupMembers
2031      * @return
2032      */
2033     private void fillAllGroupMemebersRecursivly(String groupName, Map<String, GroupDefinition> allGroups, Set<String> allGroupMembers) {
2034         // Found Cyclic dependency
2035         if (isfillGroupMemebersRecursivlyStopCondition(groupName, allGroups, allGroupMembers)) {
2036             return;
2037         }
2038         GroupDefinition groupDefinition = allGroups.get(groupName);
2039         // All Members Of Current Group Resource Instances & Other Groups
2040         Set<String> currGroupMembers = groupDefinition.getMembers().keySet();
2041         // Filtered Members Of Current Group containing only members which
2042
2043         // are groups
2044         List<String> currGroupFilteredMembers = currGroupMembers.stream().
2045                 // Keep Only Elements of type group and not Resource Instances
2046                         filter(allGroups::containsKey).
2047                 // Add Filtered Elements to main Set
2048                         peek(allGroupMembers::add).
2049                 // Collect results
2050                         collect(toList());
2051         // Recursively call the method for all the filtered group members
2052         for (String innerGroupName : currGroupFilteredMembers) {
2053             fillAllGroupMemebersRecursivly(innerGroupName, allGroups, allGroupMembers);
2054         }
2055     }
2056
2057     private boolean isfillGroupMemebersRecursivlyStopCondition(String groupName, Map<String, GroupDefinition> allGroups,
2058                                                                Set<String> allGroupMembers) {
2059         boolean stop = !allGroups.containsKey(groupName);
2060         // In Case Not Group Stop
2061         // In Case Group Has no members stop
2062         if (!stop) {
2063             GroupDefinition groupDefinition = allGroups.get(groupName);
2064             stop = isEmpty(groupDefinition.getMembers());
2065         }
2066         // In Case all group members already contained stop
2067         if (!stop) {
2068             final Set<String> allMembers = allGroups.get(groupName).getMembers().keySet();
2069             Set<String> membersOfTypeGroup = allMembers.stream().
2070                     // Filter In Only Group members
2071                             filter(allGroups::containsKey).
2072                     // Collect
2073                             collect(toSet());
2074             stop = allGroupMembers.containsAll(membersOfTypeGroup);
2075         }
2076         return stop;
2077     }
2078
2079     private Resource createRIAndRelationsFromYaml(String yamlName, Resource resource,
2080                                                   Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap,
2081                                                   String topologyTemplateYaml, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
2082                                                   Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
2083                                                   Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
2084                                                   String nodeName, final String substitutableAsNodeType) {
2085         log.debug("************* Going to create all nodes {}", yamlName);
2086         handleNodeTypes(yamlName, resource, topologyTemplateYaml, false, nodeTypesArtifactsToCreate, nodeTypesNewCreatedArtifacts, nodeTypesInfo,
2087                 csarInfo, nodeName, substitutableAsNodeType);
2088         log.debug("************* Finished to create all nodes {}", yamlName);
2089         log.debug("************* Going to create all resource instances {}", yamlName);
2090         Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
2091         resource = createResourceInstances(yamlName, resource, null, uploadComponentInstanceInfoMap, csarInfo.getCreatedNodes(),
2092                 existingNodeTypesByResourceNames);
2093         log.debug("************* Finished to create all resource instances {}", yamlName);
2094         log.debug("************* Going to create all relations {}", yamlName);
2095         resource = createResourceInstancesRelations(csarInfo.getModifier(), yamlName, resource, null, uploadComponentInstanceInfoMap,
2096                 existingNodeTypesByResourceNames);
2097         log.debug("************* Finished to create all relations {}", yamlName);
2098         log.debug("************* Going to create positions {}", yamlName);
2099         compositionBusinessLogic.setPositionsForComponentInstances(resource, csarInfo.getModifier().getUserId());
2100         log.debug("************* Finished to set positions {}", yamlName);
2101         return resource;
2102     }
2103
2104     private void handleAndAddExtractedVfcsArtifacts(List<ArtifactDefinition> vfcArtifacts, List<ArtifactDefinition> artifactsToAdd) {
2105         List<String> vfcArtifactNames = vfcArtifacts.stream().map(ArtifactDataDefinition::getArtifactName).collect(toList());
2106         artifactsToAdd.forEach(a -> {
2107             if (!vfcArtifactNames.contains(a.getArtifactName())) {
2108                 vfcArtifacts.add(a);
2109             } else {
2110                 log.debug("Can't upload two artifact with the same name {}. ", a.getArtifactName());
2111             }
2112         });
2113     }
2114
2115     @SuppressWarnings("unchecked")
2116     private void handleNodeTypes(String yamlName, Resource resource, String topologyTemplateYaml, boolean needLock,
2117                                  Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
2118                                  List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
2119                                  String nodeName, String substitutableAsNodeType) {
2120         try {
2121             for (Entry<String, NodeTypeInfo> nodeTypeEntry : nodeTypesInfo.entrySet()) {
2122                 if (nodeTypeEntry.getValue().isNested() && !nodeTypeAlreadyExists(nodeTypeEntry.getKey(), resource.getModel())) {
2123                     handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
2124                             nodeTypeEntry.getKey());
2125                     log.trace("************* finished to create node {}", nodeTypeEntry.getKey());
2126                 }
2127             }
2128             Map<String, Object> mappedToscaTemplate = null;
2129             if (StringUtils.isNotEmpty(nodeName) && isNotEmpty(nodeTypesInfo) && nodeTypesInfo.containsKey(nodeName)) {
2130                 mappedToscaTemplate = nodeTypesInfo.get(nodeName).getMappedToscaTemplate();
2131             }
2132             if (isEmpty(mappedToscaTemplate)) {
2133                 mappedToscaTemplate = (Map<String, Object>) new Yaml().load(topologyTemplateYaml);
2134             }
2135             createResourcesFromYamlNodeTypesList(yamlName, resource, mappedToscaTemplate, needLock, nodeTypesArtifactsToHandle,
2136                     nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, substitutableAsNodeType);
2137         } catch (ComponentException e) {
2138             ResponseFormat responseFormat =
2139                     e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2140             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2141             throw e;
2142         } catch (StorageException e) {
2143             ResponseFormat responseFormat = componentsUtils
2144                     .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
2145             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2146             throw e;
2147         }
2148     }
2149
2150     private boolean nodeTypeAlreadyExists(final String toscaResourceName, String modelName) {
2151         return toscaOperationFacade.getLatestByToscaResourceName(toscaResourceName, modelName).isLeft();
2152     }
2153
2154     private Either<Resource, ResponseFormat> handleVfCsarArtifacts(Resource resource, CsarInfo csarInfo, List<ArtifactDefinition> createdArtifacts,
2155                                                                    ArtifactOperationInfo artifactOperation, boolean shouldLock,
2156                                                                    boolean inTransaction) {
2157         if (csarInfo.getCsar() != null) {
2158             String vendorLicenseModelId = null;
2159             String vfLicenseModelId = null;
2160             if (artifactOperation.isUpdate()) {
2161                 Map<String, ArtifactDefinition> deploymentArtifactsMap = resource.getDeploymentArtifacts();
2162                 if (deploymentArtifactsMap != null && !deploymentArtifactsMap.isEmpty()) {
2163                     for (Entry<String, ArtifactDefinition> artifactEntry : deploymentArtifactsMap.entrySet()) {
2164                         if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VENDOR_LICENSE_MODEL)) {
2165                             vendorLicenseModelId = artifactEntry.getValue().getUniqueId();
2166                         }
2167                         if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VF_LICENSE_MODEL)) {
2168                             vfLicenseModelId = artifactEntry.getValue().getUniqueId();
2169                         }
2170                     }
2171                 }
2172             }
2173             // Specific Behavior for license artifacts
2174             createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VENDOR_LICENSE_MODEL,
2175                     Constants.VENDOR_LICENSE_MODEL, ArtifactTypeEnum.VENDOR_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT,
2176                     Constants.VENDOR_LICENSE_LABEL, Constants.VENDOR_LICENSE_DISPLAY_NAME, Constants.VENDOR_LICENSE_DESCRIPTION, vendorLicenseModelId,
2177                     artifactOperation, null, true, shouldLock, inTransaction);
2178             createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VF_LICENSE_MODEL, Constants.VF_LICENSE_MODEL,
2179                     ArtifactTypeEnum.VF_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT, Constants.VF_LICENSE_LABEL,
2180                     Constants.VF_LICENSE_DISPLAY_NAME, Constants.VF_LICENSE_DESCRIPTION, vfLicenseModelId, artifactOperation, null, true, shouldLock,
2181                     inTransaction);
2182             Either<Resource, ResponseFormat> eitherCreateResult = createOrUpdateNonMetaArtifacts(csarInfo, resource, createdArtifacts, shouldLock,
2183                     inTransaction, artifactOperation);
2184             if (eitherCreateResult.isRight()) {
2185                 return Either.right(eitherCreateResult.right().value());
2186             }
2187             Either<ImmutablePair<String, String>, ResponseFormat> artifacsMetaCsarStatus = CsarValidationUtils
2188                     .getArtifactsMeta(csarInfo.getCsar(), csarInfo.getCsarUUID(), componentsUtils);
2189             if (artifacsMetaCsarStatus.isLeft()) {
2190                 String artifactsFileName = artifacsMetaCsarStatus.left().value().getKey();
2191                 String artifactsContents = artifacsMetaCsarStatus.left().value().getValue();
2192                 Either<Resource, ResponseFormat> createArtifactsFromCsar;
2193                 if (artifactOperation.isCreateOrLink()) {
2194                     createArtifactsFromCsar = csarArtifactsAndGroupsBusinessLogic
2195                             .createResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts);
2196                 } else {
2197                     Either<Component, ResponseFormat> result = csarArtifactsAndGroupsBusinessLogic
2198                             .updateResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts, shouldLock,
2199                                     inTransaction);
2200                     if ((result.left().value() instanceof Resource) && result.isLeft()) {
2201                         Resource service1 = (Resource) result.left().value();
2202                         createArtifactsFromCsar = Either.left(service1);
2203                     } else {
2204                         createArtifactsFromCsar = Either.right(result.right().value());
2205                     }
2206                 }
2207                 if (createArtifactsFromCsar.isRight()) {
2208                     log.debug("Couldn't create artifacts from artifacts.meta");
2209                     return Either.right(createArtifactsFromCsar.right().value());
2210                 }
2211                 return Either.left(createArtifactsFromCsar.left().value());
2212             }
2213         }
2214         return Either.left(resource);
2215     }
2216
2217     private Either<Boolean, ResponseFormat> createOrUpdateSingleNonMetaArtifact(Resource resource, CsarInfo csarInfo, String artifactPath,
2218                                                                                 String artifactFileName, String artifactType,
2219                                                                                 ArtifactGroupTypeEnum artifactGroupType, String artifactLabel,
2220                                                                                 String artifactDisplayName, String artifactDescription,
2221                                                                                 String artifactId, ArtifactOperationInfo operation,
2222                                                                                 List<ArtifactDefinition> createdArtifacts, boolean isFromCsar,
2223                                                                                 boolean shouldLock, boolean inTransaction) {
2224         byte[] artifactFileBytes = null;
2225         if (csarInfo.getCsar().containsKey(artifactPath)) {
2226             artifactFileBytes = csarInfo.getCsar().get(artifactPath);
2227         }
2228         Either<Boolean, ResponseFormat> result = Either.left(true);
2229         if (operation.isUpdate() || operation.isDelete()) {
2230             if (isArtifactDeletionRequired(artifactId, artifactFileBytes, isFromCsar)) {
2231                 Either<ArtifactDefinition, ResponseFormat> handleDelete = artifactsBusinessLogic
2232                         .handleDelete(resource.getUniqueId(), artifactId, csarInfo.getModifier(), resource, shouldLock, inTransaction);
2233                 if (handleDelete.isRight()) {
2234                     result = Either.right(handleDelete.right().value());
2235                 } else {
2236                     ArtifactDefinition value = handleDelete.left().value();
2237                     String updatedArtifactId = value.getUniqueId();
2238                     if (artifactGroupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
2239                         resource.getDeploymentArtifacts().remove(updatedArtifactId);
2240                     } else {
2241                         resource.getArtifacts().remove(updatedArtifactId);
2242                     }
2243                 }
2244                 return result;
2245             }
2246             if (StringUtils.isEmpty(artifactId) && artifactFileBytes != null) {
2247                 operation = new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE);
2248             }
2249         }
2250         if (artifactFileBytes != null) {
2251             Map<String, Object> vendorLicenseModelJson = ArtifactUtils
2252                     .buildJsonForUpdateArtifact(artifactId, artifactFileName, artifactType, artifactGroupType, artifactLabel, artifactDisplayName,
2253                             artifactDescription, artifactFileBytes, null, isFromCsar);
2254             Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts = csarArtifactsAndGroupsBusinessLogic
2255                     .createOrUpdateCsarArtifactFromJson(resource, csarInfo.getModifier(), vendorLicenseModelJson, operation);
2256             addNonMetaCreatedArtifactsToSupportRollback(operation, createdArtifacts, eitherNonMetaArtifacts);
2257             if (eitherNonMetaArtifacts.isRight()) {
2258                 BeEcompErrorManager.getInstance().logInternalFlowError("UploadLicenseArtifact",
2259                         "Failed to upload license artifact: " + artifactFileName + "With csar uuid: " + csarInfo.getCsarUUID(), ErrorSeverity.WARNING);
2260                 return Either.right(eitherNonMetaArtifacts.right().value());
2261             }
2262             ArtifactDefinition artifactDefinition = eitherNonMetaArtifacts.left().value().left().value();
2263             createOrUpdateResourceWithUpdatedArtifact(artifactDefinition, resource, artifactGroupType);
2264         }
2265         return result;
2266     }
2267
2268     private void createOrUpdateResourceWithUpdatedArtifact(ArtifactDefinition artifact, Resource resource, ArtifactGroupTypeEnum groupTypeEnum) {
2269         if (groupTypeEnum == ArtifactGroupTypeEnum.DEPLOYMENT) {
2270             resource.getDeploymentArtifacts().put(artifact.getArtifactLabel(), artifact);
2271         } else {
2272             resource.getArtifacts().put(artifact.getArtifactLabel(), artifact);
2273         }
2274     }
2275
2276     private boolean isArtifactDeletionRequired(String artifactId, byte[] artifactFileBytes, boolean isFromCsar) {
2277         return !StringUtils.isEmpty(artifactId) && artifactFileBytes == null && isFromCsar;
2278     }
2279
2280     private void addNonMetaCreatedArtifactsToSupportRollback(ArtifactOperationInfo operation, List<ArtifactDefinition> createdArtifacts,
2281                                                              Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts) {
2282         if (operation.isCreateOrLink() && createdArtifacts != null && eitherNonMetaArtifacts.isLeft()) {
2283             Either<ArtifactDefinition, Operation> eitherResult = eitherNonMetaArtifacts.left().value();
2284             if (eitherResult.isLeft()) {
2285                 createdArtifacts.add(eitherResult.left().value());
2286             }
2287         }
2288     }
2289
2290     private Either<Resource, ResponseFormat> createOrUpdateNonMetaArtifacts(CsarInfo csarInfo, Resource resource,
2291                                                                             List<ArtifactDefinition> createdArtifacts, boolean shouldLock,
2292                                                                             boolean inTransaction, ArtifactOperationInfo artifactOperation) {
2293         Either<Resource, ResponseFormat> resStatus = null;
2294         Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
2295         try {
2296             Either<List<NonMetaArtifactInfo>, String> artifactPathAndNameList = getValidArtifactNames(csarInfo, collectedWarningMessages);
2297             if (artifactPathAndNameList.isRight()) {
2298                 return Either.right(
2299                         getComponentsUtils().getResponseFormatByArtifactId(ActionStatus.ARTIFACT_NAME_INVALID, artifactPathAndNameList.right().value(),
2300                                 VALID_CHARACTERS_ARTIFACT_NAME));
2301             }
2302             EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle = null;
2303             if (artifactOperation.isCreateOrLink()) {
2304                 vfCsarArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
2305                 vfCsarArtifactsToHandle.put(artifactOperation.getArtifactOperationEnum(), artifactPathAndNameList.left().value());
2306             } else {
2307                 Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandleRes = findVfCsarArtifactsToHandle(
2308                         resource, artifactPathAndNameList.left().value(), csarInfo.getModifier());
2309                 if (findVfCsarArtifactsToHandleRes.isRight()) {
2310                     resStatus = Either.right(findVfCsarArtifactsToHandleRes.right().value());
2311                 }
2312                 if (resStatus == null) {
2313                     vfCsarArtifactsToHandle = findVfCsarArtifactsToHandleRes.left().value();
2314                 }
2315             }
2316             if (resStatus == null && vfCsarArtifactsToHandle != null) {
2317                 resStatus = processCsarArtifacts(csarInfo, resource, createdArtifacts, shouldLock, inTransaction, resStatus, vfCsarArtifactsToHandle);
2318             }
2319             if (resStatus == null) {
2320                 resStatus = Either.left(resource);
2321             }
2322         } catch (Exception e) {
2323             resStatus = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2324             log.debug("Exception occurred in createNonMetaArtifacts, message:{}", e.getMessage(), e);
2325         } finally {
2326             CsarUtils.handleWarningMessages(collectedWarningMessages);
2327         }
2328         return resStatus;
2329     }
2330
2331     private Either<Resource, ResponseFormat> processCsarArtifacts(CsarInfo csarInfo, Resource resource, List<ArtifactDefinition> createdArtifacts,
2332                                                                   boolean shouldLock, boolean inTransaction,
2333                                                                   Either<Resource, ResponseFormat> resStatus,
2334                                                                   EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle) {
2335         for (Entry<ArtifactOperationEnum, List<NonMetaArtifactInfo>> currArtifactOperationPair : vfCsarArtifactsToHandle.entrySet()) {
2336             Optional<ResponseFormat> optionalCreateInDBError =
2337                     // Stream of artifacts to be created
2338                     currArtifactOperationPair.getValue().stream()
2339                             // create each artifact
2340                             .map(e -> createOrUpdateSingleNonMetaArtifact(resource, csarInfo, e.getPath(), e.getArtifactName(), e.getArtifactType(),
2341                                     e.getArtifactGroupType(), e.getArtifactLabel(), e.getDisplayName(), CsarUtils.ARTIFACT_CREATED_FROM_CSAR,
2342                                     e.getArtifactUniqueId(), new ArtifactOperationInfo(false, false, currArtifactOperationPair.getKey()), createdArtifacts,
2343                                     e.isFromCsar(), shouldLock, inTransaction))
2344                             // filter in only error
2345                             .filter(Either::isRight).
2346                             // Convert the error from either to
2347
2348                             // ResponseFormat
2349                                     map(e -> e.right().value()).
2350                             // Check if an error occurred
2351                                     findAny();
2352             // Error found on artifact Creation
2353             if (optionalCreateInDBError.isPresent()) {
2354                 resStatus = Either.right(optionalCreateInDBError.get());
2355                 break;
2356             }
2357         }
2358         return resStatus;
2359     }
2360
2361     private Either<List<NonMetaArtifactInfo>, String> getValidArtifactNames(CsarInfo csarInfo,
2362                                                                             Map<String, Set<List<String>>> collectedWarningMessages) {
2363         List<NonMetaArtifactInfo> artifactPathAndNameList =
2364                 // Stream of file paths contained in csar
2365                 csarInfo.getCsar().entrySet().stream()
2366                         // Filter in only VF artifact path location
2367                         .filter(e -> Pattern.compile(VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
2368                         // Validate and add warnings
2369                         .map(e -> CsarUtils.validateNonMetaArtifact(e.getKey(), e.getValue(), collectedWarningMessages))
2370                         // Filter in Non Warnings
2371                         .filter(Either::isLeft)
2372                         // Convert from Either to NonMetaArtifactInfo
2373                         .map(e -> e.left().value())
2374                         // collect to List
2375                         .collect(toList());
2376         Pattern englishNumbersAndUnderScoresOnly = Pattern.compile(CsarUtils.VALID_ENGLISH_ARTIFACT_NAME);
2377         for (NonMetaArtifactInfo nonMetaArtifactInfo : artifactPathAndNameList) {
2378             if (!englishNumbersAndUnderScoresOnly.matcher(nonMetaArtifactInfo.getDisplayName()).matches()) {
2379                 return Either.right(nonMetaArtifactInfo.getArtifactName());
2380             }
2381         }
2382         return Either.left(artifactPathAndNameList);
2383     }
2384
2385     private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandle(Resource resource,
2386                                                                                                                           List<NonMetaArtifactInfo> artifactPathAndNameList,
2387                                                                                                                           User user) {
2388         List<ArtifactDefinition> existingArtifacts = new ArrayList<>();
2389         // collect all Deployment and Informational artifacts of VF
2390         if (resource.getDeploymentArtifacts() != null && !resource.getDeploymentArtifacts().isEmpty()) {
2391             existingArtifacts.addAll(resource.getDeploymentArtifacts().values());
2392         }
2393         if (resource.getArtifacts() != null && !resource.getArtifacts().isEmpty()) {
2394             existingArtifacts.addAll(resource.getArtifacts().values());
2395         }
2396         existingArtifacts = existingArtifacts.stream()
2397                 // filter MANDATORY artifacts, LICENSE artifacts and artifacts
2398
2399                 // was created from HEAT.meta
2400                 .filter(this::isNonMetaArtifact).collect(toList());
2401         List<String> artifactsToIgnore = new ArrayList<>();
2402         // collect IDs of Artifacts of VF which belongs to any group
2403         if (resource.getGroups() != null) {
2404             resource.getGroups().forEach(g -> {
2405                 if (g.getArtifacts() != null && !g.getArtifacts().isEmpty()) {
2406                     artifactsToIgnore.addAll(g.getArtifacts());
2407                 }
2408             });
2409         }
2410         existingArtifacts = existingArtifacts.stream()
2411                 // filter artifacts which belongs to any group
2412                 .filter(a -> !artifactsToIgnore.contains(a.getUniqueId())).collect(toList());
2413         return organizeVfCsarArtifactsByArtifactOperation(artifactPathAndNameList, existingArtifacts, resource, user);
2414     }
2415
2416     private boolean isNonMetaArtifact(ArtifactDefinition artifact) {
2417         return !artifact.getMandatory() && artifact.getArtifactName() != null && isValidArtifactType(artifact);
2418     }
2419
2420     private boolean isValidArtifactType(ArtifactDefinition artifact) {
2421         return artifact.getArtifactType() != null && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VENDOR_LICENSE
2422                 && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VF_LICENSE;
2423     }
2424
2425     private Resource createResourceInstancesRelations(User user, String yamlName, Resource resource, Resource oldResource,
2426                                                       Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2427                                                       Map<String, Resource> existingNodeTypesByResourceNames) {
2428         log.debug("#createResourceInstancesRelations - Going to create relations ");
2429         loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2430                 "Start to create relations");
2431         List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2432         if (isEmpty(uploadResInstancesMap) || CollectionUtils.isEmpty(componentInstancesList) &&
2433                 resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances {
2434             log.debug("#createResourceInstancesRelations - No instances found in the resource {} is empty, yaml template file name {}, ",
2435                     resource.getUniqueId(), yamlName);
2436             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2437                     "No instances found in the resource: {}, is empty, yaml template file name: {}", resource.getName(), yamlName);
2438             BeEcompErrorManager.getInstance()
2439                     .logInternalDataError("createResourceInstancesRelations", "No instances found in a resource or nn yaml template. ",
2440                             ErrorSeverity.ERROR);
2441             throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2442         }
2443         Map<String, List<ComponentInstanceProperty>> instProperties = new HashMap<>();
2444         Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities = new HashMap<>();
2445         Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements = new HashMap<>();
2446         Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts = new HashMap<>();
2447         Map<String, Map<String, ArtifactDefinition>> instArtifacts = new HashMap<>();
2448         Map<String, List<AttributeDefinition>> instAttributes = new HashMap<>();
2449         List<RequirementCapabilityRelDef> relations = new ArrayList<>();
2450         Map<String, List<ComponentInstanceInput>> instInputs = new HashMap<>();
2451         Resource finalResource = resource;
2452         uploadResInstancesMap.values().forEach(
2453                 i -> processComponentInstance(yamlName, finalResource, componentInstancesList,
2454                         componentsUtils.getAllDataTypes(applicationDataTypeCache, resource.getModel()), instProperties, instCapabilities,
2455                         instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, existingNodeTypesByResourceNames, instInputs, i));
2456         resource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar()).forEach(
2457                 i -> processUiComponentInstance(oldResource, i, instCapabilities, instRequirements, instDeploymentArtifacts, instArtifacts,
2458                         instProperties, instInputs, instAttributes));
2459         associateComponentInstancePropertiesToComponent(yamlName, resource, instProperties);
2460         associateComponentInstanceInputsToComponent(yamlName, resource, instInputs);
2461         associateDeploymentArtifactsToInstances(user, yamlName, resource, instDeploymentArtifacts);
2462         associateArtifactsToInstances(yamlName, resource, instArtifacts);
2463         associateOrAddCalculatedCapReq(yamlName, resource, instCapabilities, instRequirements);
2464         associateInstAttributeToComponentToInstances(yamlName, resource, instAttributes);
2465         addRelationsToRI(yamlName, resource, uploadResInstancesMap, componentInstancesList, relations);
2466         associateResourceInstances(yamlName, resource, relations);
2467         handleSubstitutionMappings(resource, uploadResInstancesMap);
2468         log.debug("************* in create relations, getResource start");
2469         loggerSupportability
2470                 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, "create relations");
2471         Either<Resource, StorageOperationStatus> eitherGetResource = toscaOperationFacade.getToscaFullElement(resource.getUniqueId());
2472         log.debug("************* in create relations, getResource end");
2473         if (eitherGetResource.isRight()) {
2474             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2475                     "ERROR while create relations");
2476             throw new ByResponseFormatComponentException(
2477                     componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGetResource.right().value()), resource));
2478         }
2479         return eitherGetResource.left().value();
2480     }
2481
2482     private void processUiComponentInstance(Resource oldResource, ComponentInstance instance,
2483                                             Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2484                                             Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2485                                             Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2486                                             Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2487                                             Map<String, List<ComponentInstanceProperty>> instProperties,
2488                                             Map<String, List<ComponentInstanceInput>> instInputs,
2489                                             Map<String, List<AttributeDefinition>> instAttributes) {
2490         Optional<ComponentInstance> foundInstance = findInstance(oldResource, instance);
2491         if (foundInstance.isPresent()) {
2492             if (MapUtils.isNotEmpty(foundInstance.get().getCapabilities())) {
2493                 instCapabilities.put(instance, foundInstance.get().getCapabilities());
2494             }
2495             if (MapUtils.isNotEmpty(foundInstance.get().getRequirements())) {
2496                 instRequirements.put(instance, foundInstance.get().getRequirements());
2497             }
2498             if (MapUtils.isNotEmpty(foundInstance.get().getDeploymentArtifacts())) {
2499                 instDeploymentArtifacts.put(instance.getUniqueId(), foundInstance.get().getDeploymentArtifacts());
2500             }
2501             if (MapUtils.isNotEmpty(foundInstance.get().getArtifacts())) {
2502                 instArtifacts.put(instance.getUniqueId(), foundInstance.get().getArtifacts());
2503             }
2504             if (MapUtils.isNotEmpty(oldResource.getComponentInstancesProperties()) && CollectionUtils
2505                     .isNotEmpty(oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()))) {
2506                 instProperties.put(instance.getUniqueId(), oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()));
2507             }
2508             if (MapUtils.isNotEmpty(oldResource.getComponentInstancesInputs()) && CollectionUtils
2509                     .isNotEmpty(oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()))) {
2510                 instInputs.put(instance.getUniqueId(), oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()));
2511             }
2512             if (MapUtils.isNotEmpty(oldResource.getComponentInstancesAttributes()) && CollectionUtils
2513                     .isNotEmpty(oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()))) {
2514                 instAttributes.put(instance.getUniqueId(),
2515                         oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()).stream().map(AttributeDefinition::new)
2516                                 .collect(toList()));
2517             }
2518         }
2519     }
2520
2521     private Optional<ComponentInstance> findInstance(Resource oldResource, ComponentInstance instance) {
2522         if (oldResource != null && CollectionUtils.isNotEmpty(oldResource.getComponentInstances())) {
2523             return oldResource.getComponentInstances().stream().filter(i -> i.getName().equals(instance.getName())).findFirst();
2524         }
2525         return Optional.empty();
2526     }
2527
2528     private void associateResourceInstances(String yamlName, Resource resource, List<RequirementCapabilityRelDef> relations) {
2529         Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> relationsEither = toscaOperationFacade
2530                 .associateResourceInstances(resource, resource.getUniqueId(), relations);
2531         if (relationsEither.isRight() && relationsEither.right().value() != StorageOperationStatus.NOT_FOUND) {
2532             StorageOperationStatus status = relationsEither.right().value();
2533             log.debug("failed to associate instances of resource {} status is {}", resource.getUniqueId(), status);
2534             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), yamlName);
2535         } else {
2536             setResourceInstanceRelationsOnComponent(resource, relationsEither.left().value());
2537         }
2538     }
2539
2540     private void associateInstAttributeToComponentToInstances(String yamlName, Resource resource,
2541                                                               Map<String, List<AttributeDefinition>> instAttributes) {
2542         StorageOperationStatus addArtToInst;
2543         addArtToInst = toscaOperationFacade.associateInstAttributeToComponentToInstances(instAttributes, resource);
2544         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2545             log.debug("failed to associate attributes of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2546             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2547         }
2548     }
2549
2550     private void associateOrAddCalculatedCapReq(String yamlName, Resource resource,
2551                                                 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2552                                                 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements) {
2553         StorageOperationStatus addArtToInst;
2554         addArtToInst = toscaOperationFacade.associateOrAddCalculatedCapReq(instCapabilities, instRequirements, resource);
2555         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2556             log.debug("failed to associate cap and req of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2557             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2558         }
2559     }
2560
2561     private void associateArtifactsToInstances(String yamlName, Resource resource, Map<String, Map<String, ArtifactDefinition>> instArtifacts) {
2562         StorageOperationStatus addArtToInst;
2563         addArtToInst = toscaOperationFacade.associateArtifactsToInstances(instArtifacts, resource);
2564         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2565             log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2566             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2567         }
2568     }
2569
2570     private void associateDeploymentArtifactsToInstances(User user, String yamlName, Resource resource,
2571                                                          Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts) {
2572         StorageOperationStatus addArtToInst = toscaOperationFacade.associateDeploymentArtifactsToInstances(instDeploymentArtifacts, resource, user);
2573         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2574             log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2575             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2576         }
2577     }
2578
2579     private void associateComponentInstanceInputsToComponent(String yamlName, Resource resource,
2580                                                              Map<String, List<ComponentInstanceInput>> instInputs) {
2581         if (MapUtils.isNotEmpty(instInputs)) {
2582             Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addInputToInst = toscaOperationFacade
2583                     .associateComponentInstanceInputsToComponent(instInputs, resource.getUniqueId());
2584             if (addInputToInst.isRight()) {
2585                 StorageOperationStatus addInputToInstError = addInputToInst.right().value();
2586                 log.debug("failed to associate inputs value of resource {} status is {}", resource.getUniqueId(), addInputToInstError);
2587                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addInputToInstError), yamlName);
2588             }
2589             setComponentInstanceInputsOnComponent(resource, instInputs);
2590         }
2591     }
2592
2593     private void setComponentInstanceInputsOnComponent(Resource resource, Map<String, List<ComponentInstanceInput>> instInputs) {
2594         Map<String, List<ComponentInstanceInput>> componentInstancesInputs = resource.getComponentInstancesInputs();
2595         if (componentInstancesInputs == null) {
2596             componentInstancesInputs = new HashMap<>();
2597         }
2598         componentInstancesInputs.putAll(instInputs);
2599         resource.setComponentInstancesInputs(componentInstancesInputs);
2600     }
2601
2602     private void associateComponentInstancePropertiesToComponent(String yamlName, Resource resource,
2603                                                                  Map<String, List<ComponentInstanceProperty>> instProperties) {
2604         Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addPropToInst = toscaOperationFacade
2605                 .associateComponentInstancePropertiesToComponent(instProperties, resource.getUniqueId());
2606         if (addPropToInst.isRight()) {
2607             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2608                     "ERROR while  associate compnent insatnce properties of resource: {} status is: {}", resource.getName(),
2609                     addPropToInst.right().value());
2610             StorageOperationStatus storageOperationStatus = addPropToInst.right().value();
2611             log.debug("failed to associate properties of resource {} status is {}", resource.getUniqueId(), storageOperationStatus);
2612             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageOperationStatus), yamlName);
2613         }
2614         setComponentInstancePropertiesOnComponent(resource, instProperties);
2615     }
2616
2617     private void setComponentInstancePropertiesOnComponent(Resource resource, Map<String, List<ComponentInstanceProperty>> instProperties) {
2618         Map<String, List<ComponentInstanceProperty>> componentInstanceProps = resource.getComponentInstancesProperties();
2619         if (componentInstanceProps == null) {
2620             componentInstanceProps = new HashMap<>();
2621         }
2622         componentInstanceProps.putAll(instProperties);
2623         resource.setComponentInstancesProperties(componentInstanceProps);
2624     }
2625
2626     private void handleSubstitutionMappings(Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2627         Either<Resource, StorageOperationStatus> getResourceRes = null;
2628         if (resource.getResourceType() == ResourceTypeEnum.CVFC) {
2629             getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap);
2630         } else if (StringUtils.isNotEmpty(resource.getModel()) && resource.getResourceType() == ResourceTypeEnum.VF) {
2631             getResourceRes = updateCalculatedCapReqWithSubstitutionMappingsForVf(resource, uploadResInstancesMap);
2632         }
2633         if (getResourceRes != null && getResourceRes.isRight()) {
2634             ResponseFormat responseFormat = componentsUtils
2635                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource);
2636             throw new ByResponseFormatComponentException(responseFormat);
2637         }
2638
2639     }
2640
2641     private void addRelationsToRI(String yamlName, Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2642                                   List<ComponentInstance> componentInstancesList, List<RequirementCapabilityRelDef> relations) {
2643         for (Entry<String, UploadComponentInstanceInfo> entry : uploadResInstancesMap.entrySet()) {
2644             UploadComponentInstanceInfo uploadComponentInstanceInfo = entry.getValue();
2645             ComponentInstance currentCompInstance = null;
2646             for (ComponentInstance compInstance : componentInstancesList) {
2647                 if (compInstance.getName().equals(uploadComponentInstanceInfo.getName())) {
2648                     currentCompInstance = compInstance;
2649                     break;
2650                 }
2651             }
2652             if (currentCompInstance == null) {
2653                 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2654                 BeEcompErrorManager.getInstance()
2655                         .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2656                                 ErrorSeverity.ERROR);
2657                 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2658             }
2659             ResponseFormat addRelationToRiRes = addRelationToRI(yamlName, resource, entry.getValue(), relations);
2660             if (addRelationToRiRes.getStatus() != 200) {
2661                 throw new ByResponseFormatComponentException(addRelationToRiRes);
2662             }
2663         }
2664     }
2665
2666     private void setResourceInstanceRelationsOnComponent(Resource resource, List<RequirementCapabilityRelDef> relations) {
2667         if (resource.getComponentInstancesRelations() != null) {
2668             resource.getComponentInstancesRelations().addAll(relations);
2669         } else {
2670             resource.setComponentInstancesRelations(relations);
2671         }
2672     }
2673
2674     private void processComponentInstance(String yamlName, Resource resource, List<ComponentInstance> componentInstancesList,
2675                                           Map<String, DataTypeDefinition> allDataTypes,
2676                                           Map<String, List<ComponentInstanceProperty>> instProperties,
2677                                           Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2678                                           Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2679                                           Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2680                                           Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2681                                           Map<String, List<AttributeDefinition>> instAttributes, Map<String, Resource> originCompMap,
2682                                           Map<String, List<ComponentInstanceInput>> instInputs,
2683                                           UploadComponentInstanceInfo uploadComponentInstanceInfo) {
2684         Optional<ComponentInstance> currentCompInstanceOpt = componentInstancesList.stream()
2685                 .filter(i -> i.getName().equals(uploadComponentInstanceInfo.getName())).findFirst();
2686         if (currentCompInstanceOpt.isEmpty()) {
2687             log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2688             BeEcompErrorManager.getInstance()
2689                     .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2690                             ErrorSeverity.ERROR);
2691             throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2692         }
2693         ComponentInstance currentCompInstance = currentCompInstanceOpt.get();
2694         String resourceInstanceId = currentCompInstance.getUniqueId();
2695         Resource originResource = getOriginResource(originCompMap, currentCompInstance);
2696         if (isNotEmpty(originResource.getRequirements())) {
2697             instRequirements.put(currentCompInstance, originResource.getRequirements());
2698         }
2699         if (isNotEmpty(originResource.getCapabilities())) {
2700             processComponentInstanceCapabilities(allDataTypes, instCapabilties, uploadComponentInstanceInfo, currentCompInstance, originResource);
2701         }
2702         if (originResource.getDeploymentArtifacts() != null && !originResource.getDeploymentArtifacts().isEmpty()) {
2703             instDeploymentArtifacts.put(resourceInstanceId, originResource.getDeploymentArtifacts());
2704         }
2705         if (originResource.getArtifacts() != null && !originResource.getArtifacts().isEmpty()) {
2706             instArtifacts.put(resourceInstanceId, originResource.getArtifacts());
2707         }
2708         if (originResource.getAttributes() != null && !originResource.getAttributes().isEmpty()) {
2709             instAttributes.put(resourceInstanceId, originResource.getAttributes());
2710         }
2711         if (originResource.getResourceType() != ResourceTypeEnum.CVFC) {
2712             ResponseFormat addPropertiesValueToRiRes = addPropertyValuesToRi(uploadComponentInstanceInfo, resource, originResource,
2713                     currentCompInstance, instProperties, allDataTypes);
2714             if (addPropertiesValueToRiRes.getStatus() != 200) {
2715                 throw new ByResponseFormatComponentException(addPropertiesValueToRiRes);
2716             }
2717         } else {
2718             addInputsValuesToRi(uploadComponentInstanceInfo, resource, originResource, currentCompInstance, instInputs, allDataTypes);
2719         }
2720     }
2721
2722     private Resource getOriginResource(Map<String, Resource> originCompMap, ComponentInstance currentCompInstance) {
2723         Resource originResource;
2724         if (!originCompMap.containsKey(currentCompInstance.getComponentUid())) {
2725             Either<Resource, StorageOperationStatus> getOriginResourceRes = toscaOperationFacade
2726                     .getToscaFullElement(currentCompInstance.getComponentUid());
2727             if (getOriginResourceRes.isRight()) {
2728                 log.debug("failed to fetch resource with uniqueId {} and tosca component name {} status is {}", currentCompInstance.getComponentUid(),
2729                         currentCompInstance.getToscaComponentName(), getOriginResourceRes);
2730                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getOriginResourceRes.right().value()),
2731                         currentCompInstance.getComponentUid());
2732             }
2733             originResource = getOriginResourceRes.left().value();
2734             originCompMap.put(originResource.getUniqueId(), originResource);
2735         } else {
2736             originResource = originCompMap.get(currentCompInstance.getComponentUid());
2737         }
2738         return originResource;
2739     }
2740
2741     private void processComponentInstanceCapabilities(Map<String, DataTypeDefinition> allDataTypes,
2742                                                       Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2743                                                       UploadComponentInstanceInfo uploadComponentInstanceInfo, ComponentInstance currentCompInstance,
2744                                                       Resource originResource) {
2745         Map<String, List<CapabilityDefinition>> originCapabilities;
2746         if (isNotEmpty(uploadComponentInstanceInfo.getCapabilities())) {
2747             originCapabilities = new HashMap<>();
2748             Map<String, Map<String, UploadPropInfo>> newPropertiesMap = new HashMap<>();
2749             originResource.getCapabilities().forEach((k, v) -> addCapabilities(originCapabilities, k, v));
2750             uploadComponentInstanceInfo.getCapabilities().values().forEach(l -> addCapabilitiesProperties(newPropertiesMap, l));
2751             updateCapabilityPropertiesValues(originCapabilities, newPropertiesMap, allDataTypes);
2752         } else {
2753             originCapabilities = originResource.getCapabilities();
2754         }
2755         instCapabilties.put(currentCompInstance, originCapabilities);
2756     }
2757
2758     private void updateCapabilityPropertiesValues(Map<String, List<CapabilityDefinition>> originCapabilities,
2759                                                   Map<String, Map<String, UploadPropInfo>> newPropertiesMap,
2760                                                   Map<String, DataTypeDefinition> allDataTypes) {
2761         originCapabilities.values().stream().flatMap(Collection::stream).filter(c -> newPropertiesMap.containsKey(c.getName()))
2762                 .forEach(c -> updatePropertyValues(c.getProperties(), newPropertiesMap.get(c.getName()), allDataTypes));
2763     }
2764
2765     private void addCapabilitiesProperties(Map<String, Map<String, UploadPropInfo>> newPropertiesMap, List<UploadCapInfo> capabilities) {
2766         for (UploadCapInfo capability : capabilities) {
2767             if (isNotEmpty(capability.getProperties())) {
2768                 newPropertiesMap.put(capability.getName(), capability.getProperties().stream().collect(toMap(UploadInfo::getName, p -> p)));
2769             }
2770         }
2771     }
2772
2773     private void addCapabilities(Map<String, List<CapabilityDefinition>> originCapabilities, String type, List<CapabilityDefinition> capabilities) {
2774         List<CapabilityDefinition> list = capabilities.stream().map(CapabilityDefinition::new).collect(toList());
2775         originCapabilities.put(type, list);
2776     }
2777
2778     private void updatePropertyValues(List<ComponentInstanceProperty> properties, Map<String, UploadPropInfo> newProperties,
2779                                       Map<String, DataTypeDefinition> allDataTypes) {
2780         properties.forEach(p -> updatePropertyValue(p, newProperties.get(p.getName()), allDataTypes));
2781     }
2782
2783     private String updatePropertyValue(ComponentInstanceProperty property, UploadPropInfo propertyInfo,
2784                                        Map<String, DataTypeDefinition> allDataTypes) {
2785         String value = null;
2786         List<GetInputValueDataDefinition> getInputs = null;
2787         boolean isValidate = true;
2788         if (null != propertyInfo && propertyInfo.getValue() != null) {
2789             getInputs = propertyInfo.getGet_input();
2790             isValidate = getInputs == null || getInputs.isEmpty();
2791             if (isValidate) {
2792                 value = getPropertyJsonStringValue(propertyInfo.getValue(), property.getType());
2793             } else {
2794                 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
2795             }
2796         }
2797         property.setValue(value);
2798         return validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
2799     }
2800
2801     private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappings(Resource resource,
2802                                                                                                     Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2803         Either<Resource, StorageOperationStatus> updateRes = null;
2804         Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2805         Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2806
2807         StorageOperationStatus status = toscaOperationFacade.deleteAllCalculatedCapabilitiesRequirements(resource.getUniqueId());
2808         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2809             log.debug("Failed to delete all calculated capabilities and requirements of resource {} upon update. Status is {}",
2810                     resource.getUniqueId(), status);
2811             updateRes = Either.right(status);
2812         }
2813         if (updateRes == null) {
2814             fillUpdatedInstCapabilitiesRequirements(resource.getComponentInstances(), uploadResInstancesMap, updatedInstCapabilities,
2815                     updatedInstRequirements);
2816             status = toscaOperationFacade.associateOrAddCalculatedCapReq(updatedInstCapabilities, updatedInstRequirements, resource);
2817             if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2818                 log.debug(
2819                         "Failed to associate capabilities and requirementss of resource {}, updated according to a substitution mapping. Status is {}",
2820                         resource.getUniqueId(), status);
2821                 updateRes = Either.right(status);
2822             }
2823         }
2824         if (updateRes == null) {
2825             updateRes = Either.left(resource);
2826         }
2827         return updateRes;
2828     }
2829
2830     private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappingsForVf(final Resource resource,
2831                                                                                                          final Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2832         Either<Resource, StorageOperationStatus> updateRes = null;
2833         final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2834         final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2835
2836         resource.getComponentInstances().forEach(i -> {
2837             setExternalCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2838             setExternalRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2839         });
2840
2841         final StorageOperationStatus status = toscaOperationFacade.updateCalculatedCapabilitiesRequirements(updatedInstCapabilities,
2842                 updatedInstRequirements, resource);
2843         if (status != StorageOperationStatus.OK) {
2844             log.debug(
2845                     "Failed to update capabilities and requirements of resource {}. Status is {}",
2846                     resource.getUniqueId(), status);
2847             updateRes = Either.right(status);
2848         }
2849
2850         if (updateRes == null) {
2851             updateRes = Either.left(resource);
2852         }
2853         return updateRes;
2854     }
2855
2856     private void fillUpdatedInstCapabilitiesRequirements(List<ComponentInstance> componentInstances,
2857                                                          Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2858                                                          Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities,
2859                                                          Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements) {
2860         componentInstances.forEach(i -> {
2861             fillUpdatedInstCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2862             fillUpdatedInstRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2863         });
2864     }
2865
2866     private void fillUpdatedInstRequirements(Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2867                                              ComponentInstance instance, Map<String, String> requirementsNamesToUpdate) {
2868         Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2869         Set<String> updatedReqNames = new HashSet<>();
2870         if (isNotEmpty(requirementsNamesToUpdate)) {
2871             for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2872                 updatedRequirements.put(requirements.getKey(), requirements.getValue().stream().filter(
2873                                 r -> requirementsNamesToUpdate.containsKey(r.getName()) && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2874                         .map(r -> {
2875                             r.setParentName(r.getName());
2876                             r.setName(requirementsNamesToUpdate.get(r.getName()));
2877                             updatedReqNames.add(r.getName());
2878                             return r;
2879                         }).collect(toList()));
2880             }
2881         }
2882         if (isNotEmpty(updatedRequirements)) {
2883             updatedInstRequirements.put(instance, updatedRequirements);
2884         }
2885     }
2886
2887     private void setExternalRequirements(
2888             final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2889             final ComponentInstance instance, final Map<String, String> requirementsNamesToUpdate) {
2890         final Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2891         final Set<String> updatedReqNames = new HashSet<>();
2892         if (isNotEmpty(requirementsNamesToUpdate)) {
2893             for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2894                 updatedRequirements.put(requirements.getKey(),
2895                         requirements.getValue().stream()
2896                                 .filter(r -> requirementsNamesToUpdate.containsKey(r.getName())
2897                                         && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2898                                 .map(r -> {
2899                                     r.setExternal(true);
2900                                     r.setExternalName(requirementsNamesToUpdate.get(r.getName()));
2901                                     updatedReqNames.add(r.getName());
2902                                     return r;
2903                                 }).collect(toList()));
2904             }
2905         }
2906         if (isNotEmpty(updatedRequirements)) {
2907             updatedInstRequirements.put(instance, updatedRequirements);
2908         }
2909     }
2910
2911     private void setExternalCapabilities(
2912             final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2913             final ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2914         final Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2915         final Set<String> updatedCapNames = new HashSet<>();
2916         if (isNotEmpty(capabilitiesNamesToUpdate)) {
2917             for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2918                 updatedCapabilities.put(requirements.getKey(),
2919                         requirements.getValue().stream()
2920                                 .filter(c -> capabilitiesNamesToUpdate.containsKey(c.getName())
2921                                         && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2922                                 .map(c -> {
2923                                     c.setExternal(true);
2924                                     c.setExternalName(capabilitiesNamesToUpdate.get(c.getName()));
2925                                     updatedCapNames.add(c.getName());
2926                                     return c;
2927                                 }).collect(toList()));
2928             }
2929         }
2930         if (isNotEmpty(updatedCapabilities)) {
2931             updatedInstCapabilties.put(instance, updatedCapabilities);
2932         }
2933     }
2934
2935     private void fillUpdatedInstCapabilities(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2936                                              ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2937         Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2938         Set<String> updatedCapNames = new HashSet<>();
2939         if (isNotEmpty(capabilitiesNamesToUpdate)) {
2940             for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2941                 updatedCapabilities.put(requirements.getKey(), requirements.getValue().stream().filter(
2942                                 c -> capabilitiesNamesToUpdate.containsKey(c.getName()) && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2943                         .map(c -> {
2944                             c.setParentName(c.getName());
2945                             c.setName(capabilitiesNamesToUpdate.get(c.getName()));
2946                             updatedCapNames.add(c.getName());
2947                             return c;
2948                         }).collect(toList()));
2949             }
2950         }
2951         if (isNotEmpty(updatedCapabilities)) {
2952             updatedInstCapabilties.put(instance, updatedCapabilities);
2953         }
2954     }
2955
2956     private ResponseFormat addRelationToRI(String yamlName, Resource resource, UploadComponentInstanceInfo nodesInfoValue,
2957                                            List<RequirementCapabilityRelDef> relations) {
2958         List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2959         ComponentInstance currentCompInstance = null;
2960         for (ComponentInstance compInstance : componentInstancesList) {
2961             if (compInstance.getName().equals(nodesInfoValue.getName())) {
2962                 currentCompInstance = compInstance;
2963                 break;
2964             }
2965         }
2966         if (currentCompInstance == null) {
2967             log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, nodesInfoValue.getName(), resource.getUniqueId());
2968             BeEcompErrorManager.getInstance()
2969                     .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + nodesInfoValue.getName() + IN_RESOURCE, resource.getUniqueId(),
2970                             ErrorSeverity.ERROR);
2971             return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2972         }
2973         String resourceInstanceId = currentCompInstance.getUniqueId();
2974         Map<String, List<UploadReqInfo>> regMap = nodesInfoValue.getRequirements();
2975         if (regMap != null) {
2976             for (Entry<String, List<UploadReqInfo>> nodesRegInfoEntry : regMap.entrySet()) {
2977                 List<UploadReqInfo> uploadRegInfoList = nodesRegInfoEntry.getValue();
2978                 for (UploadReqInfo uploadRegInfo : uploadRegInfoList) {
2979                     log.debug("Going to create  relation {}", uploadRegInfo.getName());
2980                     loggerSupportability
2981                             .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2982                                     "Started to create relations on instance: {}", uploadRegInfo.getName());
2983                     String regName = uploadRegInfo.getName();
2984                     RequirementCapabilityRelDef regCapRelDef = new RequirementCapabilityRelDef();
2985                     regCapRelDef.setFromNode(resourceInstanceId);
2986                     log.debug("try to find available requirement {} ", regName);
2987                     Either<RequirementDefinition, ResponseFormat> eitherReqStatus = findAviableRequiremen(regName, yamlName, nodesInfoValue,
2988                             currentCompInstance, uploadRegInfo.getCapabilityName());
2989                     if (eitherReqStatus.isRight()) {
2990                         log.debug("failed to find available requirement {} status is {}", regName, eitherReqStatus.right().value());
2991                         loggerSupportability
2992                                 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2993                                         "ERROR while search available requirement {} status is: {}", regName, eitherReqStatus.right().value());
2994                         return eitherReqStatus.right().value();
2995                     }
2996                     RequirementDefinition validReq = eitherReqStatus.left().value();
2997                     List<CapabilityRequirementRelationship> reqAndRelationshipPairList = regCapRelDef.getRelationships();
2998                     if (reqAndRelationshipPairList == null) {
2999                         reqAndRelationshipPairList = new ArrayList<>();
3000                     }
3001                     RelationshipInfo reqAndRelationshipPair = new RelationshipInfo();
3002                     reqAndRelationshipPair.setRequirement(regName);
3003                     reqAndRelationshipPair.setRequirementOwnerId(validReq.getOwnerId());
3004                     reqAndRelationshipPair.setRequirementUid(validReq.getUniqueId());
3005                     RelationshipImpl relationship = new RelationshipImpl();
3006                     relationship.setType(validReq.getCapability());
3007                     reqAndRelationshipPair.setRelationships(relationship);
3008                     ComponentInstance currentCapCompInstance = null;
3009                     for (ComponentInstance compInstance : componentInstancesList) {
3010                         if (compInstance.getName().equals(uploadRegInfo.getNode())) {
3011                             currentCapCompInstance = compInstance;
3012                             break;
3013                         }
3014                     }
3015                     if (currentCapCompInstance == null) {
3016                         log.debug("The component instance  with name {} not found on resource {} ", uploadRegInfo.getNode(), resource.getUniqueId());
3017                         loggerSupportability
3018                                 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3019                                         "ERROR component instance  with name: {} not found on resource: {}", uploadRegInfo.getNode(), resource.getUniqueId());
3020                         BeEcompErrorManager.getInstance()
3021                                 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadRegInfo.getNode() + IN_RESOURCE, resource.getUniqueId(),
3022                                         ErrorSeverity.ERROR);
3023                         return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
3024                     }
3025                     regCapRelDef.setToNode(currentCapCompInstance.getUniqueId());
3026                     log.debug("try to find aviable Capability  req name is {} ", validReq.getName());
3027                     CapabilityDefinition aviableCapForRel = findAvailableCapabilityByTypeOrName(validReq, currentCapCompInstance, uploadRegInfo);
3028                     if (aviableCapForRel == null) {
3029                         log.debug("aviable capability was not found. req name is {} component instance is {}", validReq.getName(),
3030                                 currentCapCompInstance.getUniqueId());
3031                         loggerSupportability
3032                                 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3033                                         "ERROR available capability was not found. req name is: {} component instance is: {}", validReq.getName(),
3034                                         currentCapCompInstance.getUniqueId());
3035                         BeEcompErrorManager.getInstance().logInternalDataError(
3036                                 "aviable capability was not found. req name is " + validReq.getName() + " component instance is " + currentCapCompInstance
3037                                         .getUniqueId(), resource.getUniqueId(), ErrorSeverity.ERROR);
3038                         return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
3039                     }
3040                     reqAndRelationshipPair.setCapability(aviableCapForRel.getName());
3041                     reqAndRelationshipPair.setCapabilityUid(aviableCapForRel.getUniqueId());
3042                     reqAndRelationshipPair.setCapabilityOwnerId(aviableCapForRel.getOwnerId());
3043                     CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
3044                     capReqRel.setRelation(reqAndRelationshipPair);
3045                     reqAndRelationshipPairList.add(capReqRel);
3046                     regCapRelDef.setRelationships(reqAndRelationshipPairList);
3047                     relations.add(regCapRelDef);
3048                 }
3049             }
3050         } else if (resource.getResourceType() != ResourceTypeEnum.CVFC) {
3051             return componentsUtils.getResponseFormat(ActionStatus.OK, yamlName);
3052         }
3053         return componentsUtils.getResponseFormat(ActionStatus.OK);
3054     }
3055
3056     private void addInputsValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
3057                                      ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceInput>> instInputs,
3058                                      Map<String, DataTypeDefinition> allDataTypes) {
3059         Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
3060         if (MapUtils.isNotEmpty(propMap)) {
3061             Map<String, InputDefinition> currPropertiesMap = new HashMap<>();
3062             List<ComponentInstanceInput> instPropList = new ArrayList<>();
3063             if (CollectionUtils.isEmpty(originResource.getInputs())) {
3064                 log.debug("failed to find properties ");
3065                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3066                         "ERROR while try to find properties");
3067                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND);
3068             }
3069             originResource.getInputs().forEach(p -> addInput(currPropertiesMap, p));
3070             for (List<UploadPropInfo> propertyList : propMap.values()) {
3071                 processProperty(resource, currentCompInstance, allDataTypes, currPropertiesMap, instPropList, propertyList);
3072             }
3073             currPropertiesMap.values().forEach(p -> instPropList.add(new ComponentInstanceInput(p)));
3074             instInputs.put(currentCompInstance.getUniqueId(), instPropList);
3075         }
3076     }
3077
3078     private void processProperty(Resource resource, ComponentInstance currentCompInstance, Map<String, DataTypeDefinition> allDataTypes,
3079                                  Map<String, InputDefinition> currPropertiesMap, List<ComponentInstanceInput> instPropList,
3080                                  List<UploadPropInfo> propertyList) {
3081         UploadPropInfo propertyInfo = propertyList.get(0);
3082         String propName = propertyInfo.getName();
3083         if (!currPropertiesMap.containsKey(propName)) {
3084             loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3085                     "ERROR failed to find property: {}", propName);
3086             log.debug("failed to find property {} ", propName);
3087             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, propName);
3088         }
3089         InputDefinition curPropertyDef = currPropertiesMap.get(propName);
3090         ComponentInstanceInput property = null;
3091         String value = null;
3092         List<GetInputValueDataDefinition> getInputs = null;
3093         boolean isValidate = true;
3094         if (propertyInfo.getValue() != null) {
3095             getInputs = propertyInfo.getGet_input();
3096             isValidate = getInputs == null || getInputs.isEmpty();
3097             if (isValidate) {
3098                 value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3099             } else {
3100                 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3101             }
3102         }
3103         property = new ComponentInstanceInput(curPropertyDef, value, null);
3104         String validPropertyVAlue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3105         property.setValue(validPropertyVAlue);
3106         if (isNotEmpty(getInputs)) {
3107             List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3108             for (GetInputValueDataDefinition getInput : getInputs) {
3109                 List<InputDefinition> inputs = resource.getInputs();
3110                 if (CollectionUtils.isEmpty(inputs)) {
3111                     loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3112                             "ERROR Failed to add property: " + propName + " to resource instance: {}. Inputs list is empty ",
3113                             currentCompInstance.getUniqueId());
3114                     log.debug("Failed to add property {} to resource instance {}. Inputs list is empty ", property,
3115                             currentCompInstance.getUniqueId());
3116                     throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3117                 }
3118                 Optional<InputDefinition> optional = inputs.stream().filter(p -> p.getName().equals(getInput.getInputName())).findAny();
3119                 if (optional.isEmpty()) {
3120                     loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3121                             "ERROR Failed to find input: " + getInput.getInputName());
3122                     log.debug("Failed to find input {} ", getInput.getInputName());
3123                     // @@TODO error message
3124                     throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3125                 }
3126                 InputDefinition input = optional.get();
3127                 getInput.setInputId(input.getUniqueId());
3128                 getInputValues.add(getInput);
3129                 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3130                 processGetInput(getInputValues, inputs, getInputIndex);
3131             }
3132             property.setGetInputValues(getInputValues);
3133         }
3134         instPropList.add(property);
3135         // delete overriden property
3136         currPropertiesMap.remove(property.getName());
3137     }
3138
3139     private void processGetInput(List<GetInputValueDataDefinition> getInputValues, List<InputDefinition> inputs,
3140                                  GetInputValueDataDefinition getInputIndex) {
3141         Optional<InputDefinition> optional;
3142         if (getInputIndex != null) {
3143             optional = inputs.stream().filter(p -> p.getName().equals(getInputIndex.getInputName())).findAny();
3144             if (optional.isEmpty()) {
3145                 log.debug("Failed to find input {} ", getInputIndex.getInputName());
3146                 // @@TODO error message
3147                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3148             }
3149             InputDefinition inputIndex = optional.get();
3150             getInputIndex.setInputId(inputIndex.getUniqueId());
3151             getInputValues.add(getInputIndex);
3152         }
3153     }
3154
3155     private void addInput(Map<String, InputDefinition> currPropertiesMap, InputDefinition prop) {
3156         String propName = prop.getName();
3157         if (!currPropertiesMap.containsKey(propName)) {
3158             currPropertiesMap.put(propName, prop);
3159         }
3160     }
3161
3162     private ResponseFormat addPropertyValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
3163                                                  ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceProperty>> instProperties,
3164                                                  Map<String, DataTypeDefinition> allDataTypes) {
3165         Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
3166         Map<String, PropertyDefinition> currPropertiesMap = new HashMap<>();
3167         List<PropertyDefinition> listFromMap = originResource.getProperties();
3168         if ((propMap != null && !propMap.isEmpty()) && (listFromMap == null || listFromMap.isEmpty())) {
3169             loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3170                     "ERROR Failed to find properties");
3171             log.debug("failed to find properties");
3172             return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND);
3173         }
3174         if (listFromMap == null || listFromMap.isEmpty()) {
3175             return componentsUtils.getResponseFormat(ActionStatus.OK);
3176         }
3177         for (PropertyDefinition prop : listFromMap) {
3178             String propName = prop.getName();
3179             if (!currPropertiesMap.containsKey(propName)) {
3180                 currPropertiesMap.put(propName, prop);
3181             }
3182         }
3183         List<ComponentInstanceProperty> instPropList = new ArrayList<>();
3184         if (propMap != null && propMap.size() > 0) {
3185             for (List<UploadPropInfo> propertyList : propMap.values()) {
3186                 UploadPropInfo propertyInfo = propertyList.get(0);
3187                 String propName = propertyInfo.getName();
3188                 if (!currPropertiesMap.containsKey(propName)) {
3189                     log.debug("failed to find property {} ", propName);
3190                     loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3191                             "ERROR Failed to find property: {}", propName);
3192                     return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, propName);
3193                 }
3194                 PropertyDefinition curPropertyDef = currPropertiesMap.get(propName);
3195                 ComponentInstanceProperty property = null;
3196                 String value = null;
3197                 List<GetInputValueDataDefinition> getInputs = null;
3198                 boolean isValidate = true;
3199                 if (propertyInfo.getValue() != null) {
3200                     getInputs = propertyInfo.getGet_input();
3201                     isValidate = getInputs == null || getInputs.isEmpty();
3202                     if (isValidate) {
3203                         value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3204                     } else {
3205                         value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3206                     }
3207                 }
3208                 property = new ComponentInstanceProperty(curPropertyDef, value, null);
3209                 String validatePropValue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3210                 property.setValue(validatePropValue);
3211                 if (getInputs != null && !getInputs.isEmpty()) {
3212                     List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3213                     for (GetInputValueDataDefinition getInput : getInputs) {
3214                         List<InputDefinition> inputs = resource.getInputs();
3215                         if (inputs == null || inputs.isEmpty()) {
3216                             log.debug("Failed to add property {} to instance. Inputs list is empty ", property);
3217                             loggerSupportability
3218                                     .log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3219                                             "Failed to add property: {} to instance. Inputs list is empty", propName);
3220                             rollbackWithException(ActionStatus.INPUTS_NOT_FOUND,
3221                                     property.getGetInputValues().stream().map(GetInputValueDataDefinition::getInputName).collect(toList()).toString());
3222                         }
3223                         Either<InputDefinition, RuntimeException> inputEither = findInputByName(inputs, getInput);
3224                         if (inputEither.isRight()) {
3225                             throw inputEither.right().value();
3226                         } else {
3227                             InputDefinition input = inputEither.left().value();
3228                             getInput.setInputId(input.getUniqueId());
3229                             getInputValues.add(getInput);
3230                             GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3231                             if (getInputIndex != null) {
3232                                 Either<InputDefinition, RuntimeException> newInputEither = findInputByName(inputs, getInputIndex);
3233                                 if (inputEither.isRight()) {
3234                                     throw newInputEither.right().value();
3235                                 } else {
3236                                     InputDefinition newInput = newInputEither.left().value();
3237                                     getInputIndex.setInputId(newInput.getUniqueId());
3238                                 }
3239                                 getInputValues.add(getInputIndex);
3240                             }
3241                         }
3242                     }
3243                     property.setGetInputValues(getInputValues);
3244                 }
3245                 instPropList.add(property);
3246                 // delete overriden property
3247                 currPropertiesMap.remove(property.getName());
3248             }
3249         }
3250         // add rest of properties
3251         if (!currPropertiesMap.isEmpty()) {
3252             for (PropertyDefinition value : currPropertiesMap.values()) {
3253                 instPropList.add(new ComponentInstanceProperty(value));
3254             }
3255         }
3256         instProperties.put(currentCompInstance.getUniqueId(), instPropList);
3257         return componentsUtils.getResponseFormat(ActionStatus.OK);
3258     }
3259
3260     // US740820 Relate RIs according to capability name
3261     private CapabilityDefinition findAvailableCapabilityByTypeOrName(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3262                                                                      UploadReqInfo uploadReqInfo) {
3263         if (null == uploadReqInfo.getCapabilityName() || validReq.getCapability()
3264                 .equals(uploadReqInfo.getCapabilityName())) {// get
3265
3266             // by
3267
3268             // capability
3269
3270             // type
3271             return findAvailableCapability(validReq, currentCapCompInstance);
3272         }
3273         return findAvailableCapability(validReq, currentCapCompInstance, uploadReqInfo);
3274     }
3275
3276     private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3277                                                          UploadReqInfo uploadReqInfo) {
3278         CapabilityDefinition cap = null;
3279         Map<String, List<CapabilityDefinition>> capMap = currentCapCompInstance.getCapabilities();
3280         if (!capMap.containsKey(validReq.getCapability())) {
3281             return null;
3282         }
3283         Optional<CapabilityDefinition> capByName = capMap.get(validReq.getCapability()).stream()
3284                 .filter(p -> p.getName().equals(uploadReqInfo.getCapabilityName())).findAny();
3285         if (capByName.isEmpty()) {
3286             return null;
3287         }
3288         cap = capByName.get();
3289         if (isBoundedByOccurrences(cap)) {
3290             String leftOccurrences = cap.getLeftOccurrences();
3291             int left = Integer.parseInt(leftOccurrences);
3292             if (left > 0) {
3293                 --left;
3294                 cap.setLeftOccurrences(String.valueOf(left));
3295             }
3296         }
3297         return cap;
3298     }
3299
3300     private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance instance) {
3301         Map<String, List<CapabilityDefinition>> capMap = instance.getCapabilities();
3302         if (capMap.containsKey(validReq.getCapability())) {
3303             List<CapabilityDefinition> capList = capMap.get(validReq.getCapability());
3304             for (CapabilityDefinition cap : capList) {
3305                 if (isBoundedByOccurrences(cap)) {
3306                     String leftOccurrences = cap.getLeftOccurrences() != null ? cap.getLeftOccurrences() : cap.getMaxOccurrences();
3307                     int left = Integer.parseInt(leftOccurrences);
3308                     if (left > 0) {
3309                         --left;
3310                         cap.setLeftOccurrences(String.valueOf(left));
3311                         return cap;
3312                     }
3313                 } else {
3314                     return cap;
3315                 }
3316             }
3317         }
3318         return null;
3319     }
3320
3321     private boolean isBoundedByOccurrences(CapabilityDefinition cap) {
3322         return cap.getMaxOccurrences() != null && !cap.getMaxOccurrences().equals(CapabilityDataDefinition.MAX_OCCURRENCES);
3323     }
3324
3325     private Either<RequirementDefinition, ResponseFormat> findAviableRequiremen(String regName, String yamlName,
3326                                                                                 UploadComponentInstanceInfo uploadComponentInstanceInfo,
3327                                                                                 ComponentInstance currentCompInstance, String capName) {
3328         Map<String, List<RequirementDefinition>> comInstRegDefMap = currentCompInstance.getRequirements();
3329         List<RequirementDefinition> list = comInstRegDefMap.get(capName);
3330         RequirementDefinition validRegDef = null;
3331         if (list == null) {
3332             for (Entry<String, List<RequirementDefinition>> entry : comInstRegDefMap.entrySet()) {
3333                 for (RequirementDefinition reqDef : entry.getValue()) {
3334                     if (reqDef.getName().equals(regName)) {
3335                         if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3336                             String leftOccurrences = reqDef.getLeftOccurrences();
3337                             if (leftOccurrences == null) {
3338                                 leftOccurrences = reqDef.getMaxOccurrences();
3339                             }
3340                             int left = Integer.parseInt(leftOccurrences);
3341                             if (left > 0) {
3342                                 --left;
3343                                 reqDef.setLeftOccurrences(String.valueOf(left));
3344                                 validRegDef = reqDef;
3345                                 break;
3346                             } else {
3347                                 continue;
3348                             }
3349                         } else {
3350                             validRegDef = reqDef;
3351                             break;
3352                         }
3353                     }
3354                 }
3355                 if (validRegDef != null) {
3356                     break;
3357                 }
3358             }
3359         } else {
3360             for (RequirementDefinition reqDef : list) {
3361                 if (reqDef.getName().equals(regName)) {
3362                     if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3363                         String leftOccurrences = reqDef.getLeftOccurrences();
3364                         if (leftOccurrences == null) {
3365                             leftOccurrences = reqDef.getMaxOccurrences();
3366                         }
3367                         int left = Integer.parseInt(leftOccurrences);
3368                         if (left > 0) {
3369                             --left;
3370                             reqDef.setLeftOccurrences(String.valueOf(left));
3371                             validRegDef = reqDef;
3372                             break;
3373                         } else {
3374                             continue;
3375                         }
3376                     } else {
3377                         validRegDef = reqDef;
3378                         break;
3379                     }
3380                 }
3381             }
3382         }
3383         if (validRegDef == null) {
3384             ResponseFormat responseFormat = componentsUtils
3385                     .getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3386                             uploadComponentInstanceInfo.getType());
3387             return Either.right(responseFormat);
3388         }
3389         return Either.left(validRegDef);
3390     }
3391
3392     private Resource createResourceInstances(String yamlName, Resource resource, Resource oldResource,
3393                                              Map<String, UploadComponentInstanceInfo> uploadResInstancesMap, Map<String, Resource> nodeNamespaceMap,
3394                                              Map<String, Resource> existingNodeTypesByResourceNames) {
3395         Either<Resource, ResponseFormat> eitherResource;
3396         log.debug("createResourceInstances is {} - going to create resource instanse from CSAR", yamlName);
3397         if (isEmpty(uploadResInstancesMap) && resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3398             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
3399             throw new ByResponseFormatComponentException(responseFormat);
3400         }
3401         if (MapUtils.isNotEmpty(nodeNamespaceMap)) {
3402             nodeNamespaceMap.forEach((k, v) -> existingNodeTypesByResourceNames.put(v.getToscaResourceName(), v));
3403         }
3404         Map<ComponentInstance, Resource> resourcesInstancesMap = new HashMap<>();
3405         uploadResInstancesMap.values().forEach(
3406                 i -> createAndAddResourceInstance(i, yamlName, resource, nodeNamespaceMap, existingNodeTypesByResourceNames, resourcesInstancesMap));
3407         if (oldResource != null && oldResource.getResourceType() != ResourceTypeEnum.CVFC && oldResource.getComponentInstances() != null) {
3408             Map<String, Resource> existingNodeTypesByUids = existingNodeTypesByResourceNames.values().stream()
3409                     .collect(toMap(Resource::getUniqueId, r -> r));
3410             oldResource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar())
3411                     .forEach(uiInst -> resourcesInstancesMap.put(uiInst, getOriginResource(existingNodeTypesByUids, uiInst)));
3412         }
3413         if (isNotEmpty(resourcesInstancesMap)) {
3414             try {
3415                 toscaOperationFacade.associateComponentInstancesToComponent(resource, resourcesInstancesMap, false, oldResource != null);
3416             } catch (StorageException exp) {
3417                 if (exp.getStorageOperationStatus() != null && exp.getStorageOperationStatus() != StorageOperationStatus.OK) {
3418                     log.debug("Failed to add component instances to container component {}", resource.getName());
3419                     ResponseFormat responseFormat = componentsUtils
3420                             .getResponseFormat(componentsUtils.convertFromStorageResponse(exp.getStorageOperationStatus()));
3421                     eitherResource = Either.right(responseFormat);
3422                     throw new ByResponseFormatComponentException(eitherResource.right().value());
3423                 }
3424             }
3425         }
3426         if (CollectionUtils.isEmpty(resource.getComponentInstances()) &&
3427                 resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3428             log.debug("Error when create resource instance from csar. ComponentInstances list empty");
3429             BeEcompErrorManager.getInstance().logBeDaoSystemError("Error when create resource instance from csar. ComponentInstances list empty");
3430             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE));
3431         }
3432         return resource;
3433     }
3434
3435     private void createAndAddResourceInstance(UploadComponentInstanceInfo uploadComponentInstanceInfo, String yamlName, Resource resource,
3436                                               Map<String, Resource> nodeNamespaceMap, Map<String, Resource> existingnodeTypeMap,
3437                                               Map<ComponentInstance, Resource> resourcesInstancesMap) {
3438         Either<Resource, ResponseFormat> eitherResource;
3439         log.debug("*************Going to create  resource instances {}", yamlName);
3440         // updating type if the type is node type name - we need to take the
3441
3442         // updated name
3443         log.debug("*************Going to create  resource instances {}", uploadComponentInstanceInfo.getName());
3444         if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3445             uploadComponentInstanceInfo.setType(nodeNamespaceMap.get(uploadComponentInstanceInfo.getType()).getToscaResourceName());
3446         }
3447         Resource refResource = validateResourceInstanceBeforeCreate(yamlName, uploadComponentInstanceInfo, existingnodeTypeMap, resource);
3448         ComponentInstance componentInstance = new ComponentInstance();
3449         componentInstance.setComponentUid(refResource.getUniqueId());
3450         Collection<String> directives = uploadComponentInstanceInfo.getDirectives();
3451         if (directives != null && !directives.isEmpty()) {
3452             componentInstance.setDirectives(new ArrayList<>(directives));
3453         }
3454         UploadNodeFilterInfo uploadNodeFilterInfo = uploadComponentInstanceInfo.getUploadNodeFilterInfo();
3455         if (uploadNodeFilterInfo != null) {
3456             componentInstance
3457                     .setNodeFilter(new CINodeFilterUtils().getNodeFilterDataDefinition(uploadNodeFilterInfo, componentInstance.getUniqueId()));
3458         }
3459         ComponentTypeEnum containerComponentType = resource.getComponentType();
3460         NodeTypeEnum containerNodeType = containerComponentType.getNodeType();
3461         if (containerNodeType == NodeTypeEnum.Resource && isNotEmpty(uploadComponentInstanceInfo.getCapabilities()) && isNotEmpty(
3462                 refResource.getCapabilities())) {
3463             setCapabilityNamesTypes(refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3464             Map<String, List<CapabilityDefinition>> validComponentInstanceCapabilities = getValidComponentInstanceCapabilities(
3465                     refResource.getUniqueId(), refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3466             componentInstance.setCapabilities(validComponentInstanceCapabilities);
3467         }
3468         if (isNotEmpty(uploadComponentInstanceInfo.getArtifacts())) {
3469             Map<String, Map<String, UploadArtifactInfo>> artifacts = uploadComponentInstanceInfo.getArtifacts();
3470             Map<String, ToscaArtifactDataDefinition> toscaArtifacts = new HashMap<>();
3471             Map<String, Map<String, UploadArtifactInfo>> arts = artifacts.entrySet().stream()
3472                     .filter(e -> e.getKey().contains(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName()))
3473                     .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
3474             Map<String, UploadArtifactInfo> artifact = arts.get(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName());
3475             for (Map.Entry<String, UploadArtifactInfo> entry : artifact.entrySet()) {
3476                 ToscaArtifactDataDefinition to = new ToscaArtifactDataDefinition();
3477                 to.setFile(entry.getValue().getFile());
3478                 to.setType(entry.getValue().getType());
3479                 if(isNotEmpty(entry.getValue().getProperties())) {
3480                     Map<String, Object> newPropertiesMap = new HashMap<>();
3481                     List<UploadPropInfo> artifactPropsInfo = entry.getValue().getProperties();
3482                     for(UploadPropInfo propInfo: artifactPropsInfo) {
3483                         newPropertiesMap.put(propInfo.getName(), propInfo.getValue());
3484                     }
3485                     to.setProperties(newPropertiesMap);
3486                 }
3487                 toscaArtifacts.put(entry.getKey(), to);
3488             }
3489             componentInstance.setToscaArtifacts(toscaArtifacts);
3490         }
3491         if (!existingnodeTypeMap.containsKey(uploadComponentInstanceInfo.getType())) {
3492             log.debug("createResourceInstances - not found lates version for resource instance with name {} and type {}",
3493                     uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3494             throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3495                     uploadComponentInstanceInfo.getType());
3496         }
3497         Resource origResource = existingnodeTypeMap.get(uploadComponentInstanceInfo.getType());
3498         componentInstance.setName(uploadComponentInstanceInfo.getName());
3499         componentInstance.setIcon(origResource.getIcon());
3500         componentInstance.setCreatedFrom(CreatedFrom.CSAR);
3501         resourcesInstancesMap.put(componentInstance, origResource);
3502     }
3503
3504     private void setCapabilityNamesTypes(Map<String, List<CapabilityDefinition>> originCapabilities,
3505                                          Map<String, List<UploadCapInfo>> uploadedCapabilities) {
3506         for (Entry<String, List<UploadCapInfo>> currEntry : uploadedCapabilities.entrySet()) {
3507             if (originCapabilities.containsKey(currEntry.getKey())) {
3508                 currEntry.getValue().forEach(cap -> cap.setType(currEntry.getKey()));
3509             }
3510         }
3511         for (Map.Entry<String, List<CapabilityDefinition>> capabilities : originCapabilities.entrySet()) {
3512             capabilities.getValue().forEach(cap -> {
3513                 if (uploadedCapabilities.containsKey(cap.getName())) {
3514                     uploadedCapabilities.get(cap.getName()).forEach(c -> {
3515                         c.setName(cap.getName());
3516                         c.setType(cap.getType());
3517                     });
3518                 }
3519             });
3520         }
3521     }
3522
3523     private Resource validateResourceInstanceBeforeCreate(String yamlName, UploadComponentInstanceInfo uploadComponentInstanceInfo,
3524                                                           Map<String, Resource> nodeNamespaceMap, Resource resource) {
3525         log.debug("validateResourceInstanceBeforeCreate - going to validate resource instance with name {} and type {} before create",
3526                 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3527         Resource refResource;
3528         if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3529             refResource = nodeNamespaceMap.get(uploadComponentInstanceInfo.getType());
3530         } else {
3531             Either<Resource, StorageOperationStatus> findResourceEither = StringUtils.isEmpty(resource.getModel()) ?
3532                     toscaOperationFacade.getByToscaResourceNameMatchingVendorRelease(uploadComponentInstanceInfo.getType(),
3533                             ((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()).getVendorRelease()):
3534                     toscaOperationFacade.getLatestByToscaResourceNameAndModel(uploadComponentInstanceInfo.getType(), resource.getModel());
3535             if (findResourceEither.isRight()) {
3536                 log.debug("validateResourceInstanceBeforeCreate - not found latest version for resource instance with name {} and type {}",
3537                         uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3538                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(findResourceEither.right().value()));
3539             }
3540             refResource = findResourceEither.left().value();
3541             nodeNamespaceMap.put(refResource.getToscaResourceName(), refResource);
3542         }
3543         String componentState = refResource.getComponentMetadataDefinition().getMetadataDataDefinition().getState();
3544         if (componentState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3545             log.debug(
3546                     "validateResourceInstanceBeforeCreate - component instance of component {} can not be created because the component is in an illegal state {}.",
3547                     refResource.getName(), componentState);
3548             throw new ByActionStatusComponentException(ActionStatus.ILLEGAL_COMPONENT_STATE, refResource.getComponentType().getValue(),
3549                     refResource.getName(), componentState);
3550         }
3551         if (!ModelConverter.isAtomicComponent(refResource) && refResource.getResourceType() != ResourceTypeEnum.CVFC) {
3552             log.debug("validateResourceInstanceBeforeCreate -  ref resource type is {} ", refResource.getResourceType());
3553             throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3554                     uploadComponentInstanceInfo.getType());
3555         }
3556         return refResource;
3557     }
3558
3559     public Resource propagateStateToCertified(User user, Resource resource, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3560                                               boolean needLock, boolean forceCertificationAllowed) {
3561         boolean failed = false;
3562         try {
3563             if (resource.getLifecycleState() != LifecycleStateEnum.CERTIFIED && forceCertificationAllowed && lifecycleBusinessLogic
3564                     .isFirstCertification(resource.getVersion())) {
3565                 nodeForceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3566             }
3567             if (resource.getLifecycleState() == LifecycleStateEnum.CERTIFIED) {
3568                 Either<ArtifactDefinition, Operation> eitherPopulated = populateToscaArtifacts(resource, user, false, inTransaction, needLock, false);
3569                 return resource;
3570             }
3571             return nodeFullCertification(resource.getUniqueId(), user, lifecycleChangeInfo, inTransaction, needLock);
3572         } catch (ComponentException e) {
3573             failed = true;
3574             log.debug("The exception has occurred upon certification of resource {}. ", resource.getName(), e);
3575             throw e;
3576         } finally {
3577             if (failed) {
3578                 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3579                 if (!inTransaction) {
3580                     janusGraphDao.rollback();
3581                 }
3582             } else if (!inTransaction) {
3583                 janusGraphDao.commit();
3584             }
3585         }
3586     }
3587
3588     private Resource nodeFullCertification(String uniqueId, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3589                                            boolean needLock) {
3590         Either<Resource, ResponseFormat> resourceResponse = lifecycleBusinessLogic
3591                 .changeState(uniqueId, user, LifeCycleTransitionEnum.CERTIFY, lifecycleChangeInfo, inTransaction, needLock);
3592         if (resourceResponse.isRight()) {
3593             throw new ByResponseFormatComponentException(resourceResponse.right().value());
3594         }
3595         return resourceResponse.left().value();
3596     }
3597
3598     private Resource nodeForceCertification(Resource resource, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3599                                             boolean needLock) {
3600         return lifecycleBusinessLogic.forceResourceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3601     }
3602
3603     public ImmutablePair<Resource, ActionStatus> createOrUpdateResourceByImport(final Resource resource, final User user, final boolean isNormative,
3604                                                                                 final boolean isInTransaction, final boolean needLock,
3605                                                                                 final CsarInfo csarInfo, final String nodeName,
3606                                                                                 final boolean isNested) {
3607         ImmutablePair<Resource, ActionStatus> result = null;
3608         // check if resource already exists (search by tosca name = type)
3609         final boolean isNestedResource = isNestedResourceUpdate(csarInfo, nodeName);
3610         final String resourceName = resource.getToscaResourceName();
3611         final Either<Resource, StorageOperationStatus> latestByToscaName = toscaOperationFacade
3612                 .getLatestByToscaResourceNameAndModel(resourceName, resource.getModel());
3613         if (latestByToscaName.isLeft() && Objects.nonNull(latestByToscaName.left().value())) {
3614             final Resource foundResource = latestByToscaName.left().value();
3615             // we don't allow updating names of top level types
3616             if (!isNestedResource && !StringUtils.equals(resource.getName(), foundResource.getName())) {
3617                 BeEcompErrorManager.getInstance()
3618                         .logBeComponentMissingError("Create / Update resource by import", ComponentTypeEnum.RESOURCE.getValue(), resource.getName());
3619                 log.debug("resource already exist new name={} old name={} same type={}", resource.getName(), foundResource.getName(),
3620                         resource.getToscaResourceName());
3621                 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
3622                 componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3623                 throwComponentException(responseFormat);
3624             }
3625             result = updateExistingResourceByImport(resource, foundResource, user, isNormative, needLock, isNested);
3626         } else if (isNotFound(latestByToscaName)) {
3627             if (isNestedResource) {
3628                 result = createOrUpdateNestedResource(resource, user, isNormative, isInTransaction, needLock, csarInfo, isNested, nodeName);
3629             } else {
3630                 result = createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3631             }
3632         } else {
3633             StorageOperationStatus status = latestByToscaName.right().value();
3634             log.debug("failed to get latest version of resource {}. status={}", resource.getName(), status);
3635             ResponseFormat responseFormat = componentsUtils
3636                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(latestByToscaName.right().value()), resource);
3637             componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3638             throwComponentException(responseFormat);
3639         }
3640         return result;
3641     }
3642
3643     private boolean isNestedResourceUpdate(CsarInfo csarInfo, String nodeName) {
3644         return csarInfo != null && csarInfo.isUpdate() && nodeName != null;
3645     }
3646
3647     private ImmutablePair<Resource, ActionStatus> createOrUpdateNestedResource(final Resource resource, final User user, final boolean isNormative,
3648                                                                                final boolean isInTransaction, final boolean needLock,
3649                                                                                final CsarInfo csarInfo, final boolean isNested,
3650                                                                                final String nodeName) {
3651         final Either<Component, StorageOperationStatus> latestByToscaName = toscaOperationFacade.getLatestByToscaResourceName(
3652                 buildNestedToscaResourceName(resource.getResourceType().name(), csarInfo.getVfResourceName(), nodeName).getRight(), resource.getModel());
3653         if (latestByToscaName.isLeft()) {
3654             final Resource nestedResource = (Resource) latestByToscaName.left().value();
3655             log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
3656             final Either<Boolean, ResponseFormat> eitherValidation = validateNestedDerivedFromDuringUpdate(nestedResource, resource,
3657                     ValidationUtils.hasBeenCertified(nestedResource.getVersion()));
3658             if (eitherValidation.isRight()) {
3659                 return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3660             }
3661             return updateExistingResourceByImport(resource, nestedResource, user, isNormative, needLock, isNested);
3662         } else {
3663             return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3664         }
3665     }
3666
3667     private boolean isNotFound(Either<Resource, StorageOperationStatus> getResourceEither) {
3668         return getResourceEither.isRight() && getResourceEither.right().value() == StorageOperationStatus.NOT_FOUND;
3669     }
3670
3671     private ImmutablePair<Resource, ActionStatus> createResourceByImport(Resource resource, User user, boolean isNormative, boolean isInTransaction,
3672                                                                          CsarInfo csarInfo) {
3673         log.debug("resource with name {} does not exist. create new resource", resource.getName());
3674         validateResourceBeforeCreate(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isInTransaction, csarInfo);
3675         final Resource createResourceByDao = createResourceByDao(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isNormative, isInTransaction);
3676         Resource createdResource = updateCatalog(createResourceByDao, ChangeTypeEnum.LIFECYCLE).left().map(r -> (Resource) r).left().value();
3677         ImmutablePair<Resource, ActionStatus> resourcePair = new ImmutablePair<>(createdResource, ActionStatus.CREATED);
3678         ASDCKpiApi.countImportResourcesKPI();
3679         return resourcePair;
3680     }
3681
3682     public boolean isResourceExist(String resourceName) {
3683         Either<Resource, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByName(resourceName, null);
3684         return latestByName.isLeft();
3685     }
3686
3687     private ImmutablePair<Resource, ActionStatus> updateExistingResourceByImport(Resource newResource, Resource oldResource, User user,
3688                                                                                  boolean inTransaction, boolean needLock, boolean isNested) {
3689         String lockedResourceId = oldResource.getUniqueId();
3690         log.debug("found resource: name={}, id={}, version={}, state={}", oldResource.getName(), lockedResourceId, oldResource.getVersion(),
3691                 oldResource.getLifecycleState());
3692         ImmutablePair<Resource, ActionStatus> resourcePair = null;
3693         try {
3694             lockComponent(lockedResourceId, oldResource, needLock, "Update Resource by Import");
3695             oldResource = prepareResourceForUpdate(oldResource, newResource, user, inTransaction, false);
3696             mergeOldResourceMetadataWithNew(oldResource, newResource);
3697             validateResourceFieldsBeforeUpdate(oldResource, newResource, inTransaction, isNested);
3698             validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), newResource, AuditingActionEnum.IMPORT_RESOURCE, inTransaction);
3699             // contact info normalization
3700             newResource.setContactId(newResource.getContactId().toLowerCase());
3701             PropertyConstraintsUtils.validatePropertiesConstraints(newResource, oldResource);
3702             // non-updatable fields
3703             newResource.setCreatorUserId(user.getUserId());
3704             newResource.setCreatorFullName(user.getFullName());
3705             newResource.setLastUpdaterUserId(user.getUserId());
3706             newResource.setLastUpdaterFullName(user.getFullName());
3707             newResource.setUniqueId(oldResource.getUniqueId());
3708             newResource.setVersion(oldResource.getVersion());
3709             newResource.setInvariantUUID(oldResource.getInvariantUUID());
3710             newResource.setLifecycleState(oldResource.getLifecycleState());
3711             newResource.setUUID(oldResource.getUUID());
3712             newResource.setNormalizedName(oldResource.getNormalizedName());
3713             newResource.setSystemName(oldResource.getSystemName());
3714             newResource.setModel(oldResource.getModel());
3715             if (oldResource.getCsarUUID() != null) {
3716                 newResource.setCsarUUID(oldResource.getCsarUUID());
3717             }
3718             if (oldResource.getImportedToscaChecksum() != null) {
3719                 newResource.setImportedToscaChecksum(oldResource.getImportedToscaChecksum());
3720             }
3721             newResource.setAbstract(oldResource.isAbstract());
3722             if (CollectionUtils.isEmpty(newResource.getDerivedFrom())) {
3723                 newResource.setDerivedFrom(oldResource.getDerivedFrom());
3724             }
3725             if (CollectionUtils.isEmpty(newResource.getDataTypes())) {
3726                 newResource.setDataTypes(oldResource.getDataTypes());
3727             }
3728             if (StringUtils.isEmpty(newResource.getDerivedFromGenericType())) {
3729                 newResource.setDerivedFromGenericType(oldResource.getDerivedFromGenericType());
3730             }
3731             if (StringUtils.isEmpty(newResource.getDerivedFromGenericVersion())) {
3732                 newResource.setDerivedFromGenericVersion(oldResource.getDerivedFromGenericVersion());
3733             }
3734             // add for new)
3735
3736             // created without tosca artifacts - add the placeholders
3737             if (MapUtils.isEmpty(newResource.getToscaArtifacts())) {
3738                 setToscaArtifactsPlaceHolders(newResource, user);
3739             }
3740             if (MapUtils.isEmpty(newResource.getInterfaces())) {
3741                 newResource.setInterfaces(oldResource.getInterfaces());
3742             }
3743             if (CollectionUtils.isEmpty(newResource.getAttributes())) {
3744                 newResource.setAttributes(oldResource.getAttributes());
3745             }
3746             if (CollectionUtils.isEmpty(newResource.getProperties())) {
3747                 newResource.setProperties(oldResource.getProperties());
3748             }
3749             Either<Resource, StorageOperationStatus> overrideResource = toscaOperationFacade.overrideComponent(newResource, oldResource);
3750             if (overrideResource.isRight()) {
3751                 ResponseFormat responseFormat = componentsUtils
3752                         .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(overrideResource.right().value()), newResource);
3753                 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE);
3754                 throwComponentException(responseFormat);
3755             }
3756             updateCatalog(overrideResource.left().value(), ChangeTypeEnum.LIFECYCLE);
3757             log.debug("Resource updated successfully!!!");
3758             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3759             componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3760                     ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3761             resourcePair = new ImmutablePair<>(overrideResource.left().value(), ActionStatus.OK);
3762             return resourcePair;
3763         } finally {
3764             if (resourcePair == null) {
3765                 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3766                 janusGraphDao.rollback();
3767             } else if (!inTransaction) {
3768                 janusGraphDao.commit();
3769             }
3770             if (needLock) {
3771                 log.debug("unlock resource {}", lockedResourceId);
3772                 graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource);
3773             }
3774         }
3775     }
3776
3777     /**
3778      * Merge old resource with new. Keep old category and vendor name without change
3779      *
3780      * @param oldResource
3781      * @param newResource
3782      */
3783     private void mergeOldResourceMetadataWithNew(Resource oldResource, Resource newResource) {
3784         // keep old category and vendor name without change
3785
3786         // merge the rest of the resource metadata
3787         if (newResource.getTags() == null || newResource.getTags().isEmpty()) {
3788             newResource.setTags(oldResource.getTags());
3789         }
3790         if (newResource.getDescription() == null) {
3791             newResource.setDescription(oldResource.getDescription());
3792         }
3793         if (newResource.getVendorRelease() == null) {
3794             newResource.setVendorRelease(oldResource.getVendorRelease());
3795         }
3796         if (newResource.getResourceVendorModelNumber() == null) {
3797             newResource.setResourceVendorModelNumber(oldResource.getResourceVendorModelNumber());
3798         }
3799         if (newResource.getModel() == null) {
3800             newResource.setModel(oldResource.getModel());
3801         }
3802         if (newResource.getContactId() == null) {
3803             newResource.setContactId(oldResource.getContactId());
3804         }
3805         newResource.setCategories(oldResource.getCategories());
3806         if (newResource.getVendorName() == null) {
3807             newResource.setVendorName(oldResource.getVendorName());
3808         }
3809         List<GroupDefinition> oldForUpdate = oldResource.getGroups();
3810         if (CollectionUtils.isNotEmpty(oldForUpdate)) {
3811             List<GroupDefinition> groupForUpdate = oldForUpdate.stream().map(GroupDefinition::new).collect(Collectors.toList());
3812             groupForUpdate.stream().filter(GroupDataDefinition::isVspOriginated).forEach(group -> group.setName(group.getInvariantName()));
3813             newResource.setGroups(groupForUpdate);
3814         }
3815         if (newResource.getResourceType().isAtomicType() && !newResource.getName().equals("Root")
3816                 && newResource.getResourceType() != ResourceTypeEnum.CVFC) {
3817             ResourceTypeEnum updatedResourceType = newResource.getResourceType();
3818             Optional<Component> derivedFromResourceOptional = getParentComponent(newResource);
3819             if (derivedFromResourceOptional.isPresent() && derivedFromResourceOptional.get().getComponentType() == ComponentTypeEnum.RESOURCE) {
3820                 Resource parentResource = (Resource) derivedFromResourceOptional.get();
3821                 if (!(parentResource.isAbstract() && (ResourceTypeEnum.VFC == parentResource.getResourceType()
3822                         || ResourceTypeEnum.ABSTRACT == parentResource.getResourceType())) && parentResource.getResourceType() != updatedResourceType
3823                         && oldResource.getResourceType() != updatedResourceType) {
3824                     BeEcompErrorManager.getInstance().logInternalDataError("mergeOldResourceMetadataWithNew",
3825                             "resource type of the resource does not match to derived from resource type", ErrorSeverity.ERROR);
3826                     log.debug(
3827                             "#mergeOldResourceMetadataWithNew - resource type {} of the resource {} does not match to derived from resource type {}",
3828                             newResource.getResourceType(), newResource.getToscaResourceName(), parentResource.getResourceType());
3829                     throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_TYPE);
3830                 }
3831             }
3832         }
3833     }
3834
3835     private Optional<Component> getParentComponent(Resource newResource) {
3836         if (newResource.getDerivedFrom() == null) {
3837             return Optional.empty();
3838         }
3839         String toscaResourceNameDerivedFrom = newResource.getDerivedFrom().get(0);
3840         Either<Component, StorageOperationStatus> latestByToscaResourceName = toscaOperationFacade
3841                 .getLatestByToscaResourceName(toscaResourceNameDerivedFrom, newResource.getModel());
3842         if (latestByToscaResourceName.isRight()) {
3843             BeEcompErrorManager.getInstance()
3844                     .logInternalDataError("mergeOldResourceMetadataWithNew", "derived from resource not found", ErrorSeverity.ERROR);
3845             log.debug("#mergeOldResourceMetadataWithNew - derived from resource {} not found", toscaResourceNameDerivedFrom);
3846             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, toscaResourceNameDerivedFrom);
3847         }
3848         return Optional.of(latestByToscaResourceName.left().value());
3849     }
3850
3851     private Resource prepareResourceForUpdate(Resource oldResource, Resource newResource, User user, boolean inTransaction, boolean needLock) {
3852         if (!ComponentValidationUtils.canWorkOnResource(oldResource, user.getUserId())) {
3853             // checkout
3854             return lifecycleBusinessLogic
3855                     .changeState(oldResource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, new LifecycleChangeInfoWithAction("update by import"),
3856                             inTransaction, needLock).left().on(response -> failOnChangeState(response, user, oldResource, newResource));
3857         }
3858         return oldResource;
3859     }
3860
3861     private Resource failOnChangeState(ResponseFormat response, User user, Resource oldResource, Resource newResource) {
3862         log.info("resource {} cannot be updated. reason={}", oldResource.getUniqueId(), response.getFormattedMessage());
3863         componentsUtils.auditResource(response, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3864                 ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3865         throw new ByResponseFormatComponentException(response);
3866     }
3867
3868     public Resource validateResourceBeforeCreate(Resource resource, User user, AuditingActionEnum actionEnum, boolean inTransaction,
3869                                                  CsarInfo csarInfo) {
3870         validateResourceFieldsBeforeCreate(user, resource, actionEnum, inTransaction);
3871         validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), resource, actionEnum, inTransaction);
3872         validateLifecycleTypesCreate(user, resource, actionEnum);
3873         validateResourceType(user, resource, actionEnum);
3874         resource.setCreatorUserId(user.getUserId());
3875         resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
3876         resource.setContactId(resource.getContactId().toLowerCase());
3877         if (StringUtils.isEmpty(resource.getToscaResourceName()) && !ModelConverter.isAtomicComponent(resource)) {
3878             String resourceSystemName;
3879             if (csarInfo != null && StringUtils.isNotEmpty(csarInfo.getVfResourceName())) {
3880                 resourceSystemName = ValidationUtils.convertToSystemName(csarInfo.getVfResourceName());
3881             } else {
3882                 resourceSystemName = resource.getSystemName();
3883             }
3884             resource
3885                     .setToscaResourceName(CommonBeUtils.generateToscaResourceName(resource.getResourceType().name().toLowerCase(), resourceSystemName));
3886         }
3887         // Generate invariant UUID - must be here and not in operation since it
3888
3889         // should stay constant during clone
3890
3891         // TODO
3892         String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
3893         resource.setInvariantUUID(invariantUUID);
3894         return resource;
3895     }
3896
3897     private Either<Boolean, ResponseFormat> validateResourceType(User user, Resource resource, AuditingActionEnum actionEnum) {
3898         Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3899         if (resource.getResourceType() == null) {
3900             log.debug("Invalid resource type for resource");
3901             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
3902             eitherResult = Either.right(errorResponse);
3903             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3904         }
3905         return eitherResult;
3906     }
3907
3908     private Either<Boolean, ResponseFormat> validateLifecycleTypesCreate(User user, Resource resource, AuditingActionEnum actionEnum) {
3909         Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3910         if (resource.getInterfaces() != null && resource.getInterfaces().size() > 0) {
3911             log.debug("validate interface lifecycle Types Exist");
3912             Iterator<InterfaceDefinition> intItr = resource.getInterfaces().values().iterator();
3913             while (intItr.hasNext() && eitherResult.isLeft()) {
3914                 InterfaceDefinition interfaceDefinition = intItr.next();
3915                 String intType = interfaceDefinition.getUniqueId();
3916                 Either<InterfaceDefinition, StorageOperationStatus> eitherCapTypeFound = interfaceTypeOperation.getInterface(intType);
3917                 if (eitherCapTypeFound.isRight()) {
3918                     if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3919                         BeEcompErrorManager.getInstance()
3920                                 .logBeGraphObjectMissingError("Create Resource - validateLifecycleTypesCreate", "Interface", intType);
3921                         log.debug("Lifecycle Type: {} is required by resource: {} but does not exist in the DB", intType, resource.getName());
3922                         BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateLifecycleTypesCreate");
3923                         log.debug("request to data model failed with error: {}", eitherCapTypeFound.right().value().name());
3924                     }
3925                     ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_LIFECYCLE_TYPE, intType);
3926                     eitherResult = Either.right(errorResponse);
3927                     componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3928                 }
3929             }
3930         }
3931         return eitherResult;
3932     }
3933
3934     private Either<Boolean, ResponseFormat> validateCapabilityTypesCreate(User user, ICapabilityTypeOperation capabilityTypeOperation,
3935                                                                           Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
3936         Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3937         if (resource.getCapabilities() != null && resource.getCapabilities().size() > 0) {
3938             log.debug("validate capability Types Exist - capabilities section");
3939             for (Entry<String, List<CapabilityDefinition>> typeEntry : resource.getCapabilities().entrySet()) {
3940                 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, actionEnum, eitherResult, typeEntry,
3941                         inTransaction);
3942                 if (eitherResult.isRight()) {
3943                     return Either.right(eitherResult.right().value());
3944                 }
3945             }
3946         }
3947         if (resource.getRequirements() != null && resource.getRequirements().size() > 0) {
3948             log.debug("validate capability Types Exist - requirements section");
3949             for (String type : resource.getRequirements().keySet()) {
3950                 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, resource.getRequirements().get(type), actionEnum,
3951                         eitherResult, type, inTransaction);
3952                 if (eitherResult.isRight()) {
3953                     return Either.right(eitherResult.right().value());
3954                 }
3955             }
3956         }
3957         return eitherResult;
3958     }
3959
3960     // @param typeObject- the object to which the validation is done
3961     private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3962                                                                          Resource resource, List<?> validationObjects, AuditingActionEnum actionEnum,
3963                                                                          Either<Boolean, ResponseFormat> eitherResult, String type,
3964                                                                          boolean inTransaction) {
3965         Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation.getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), type), inTransaction);
3966         if (eitherCapTypeFound.isRight()) {
3967             if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3968                 BeEcompErrorManager.getInstance().logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", type);
3969                 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", type, resource.getName());
3970                 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3971             }
3972             log.debug("Trying to get capability type {} failed with error: {}", type, eitherCapTypeFound.right().value().name());
3973             ResponseFormat errorResponse = null;
3974             if (type != null) {
3975                 errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, type);
3976             } else {
3977                 errorResponse = componentsUtils.getResponseFormatByElement(ActionStatus.MISSING_CAPABILITY_TYPE, validationObjects);
3978             }
3979             eitherResult = Either.right(errorResponse);
3980             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3981         }
3982         return eitherResult;
3983     }
3984
3985     private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3986                                                                          Resource resource, AuditingActionEnum actionEnum,
3987                                                                          Either<Boolean, ResponseFormat> eitherResult,
3988                                                                          Entry<String, List<CapabilityDefinition>> typeEntry, boolean inTransaction) {
3989         Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation
3990                 .getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), typeEntry.getKey()), inTransaction);
3991         if (eitherCapTypeFound.isRight()) {
3992             if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3993                 BeEcompErrorManager.getInstance()
3994                         .logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", typeEntry.getKey());
3995                 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", typeEntry.getKey(), resource.getName());
3996                 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3997             }
3998             log.debug("Trying to get capability type {} failed with error: {}", typeEntry.getKey(), eitherCapTypeFound.right().value().name());
3999             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, typeEntry.getKey());
4000             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4001             return Either.right(errorResponse);
4002         }
4003         CapabilityTypeDefinition capabilityTypeDefinition = eitherCapTypeFound.left().value();
4004         if (capabilityTypeDefinition.getProperties() != null) {
4005             for (CapabilityDefinition capDef : typeEntry.getValue()) {
4006                 List<ComponentInstanceProperty> properties = capDef.getProperties();
4007                 List<ComponentInstanceProperty> changedProperties = new ArrayList<>();
4008                 if (properties == null || properties.isEmpty()) {
4009                     for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
4010                         ComponentInstanceProperty newProp = new ComponentInstanceProperty(prop.getValue());
4011                         changedProperties.add(newProp);
4012                     }
4013                 } else {
4014                     List<ComponentInstanceProperty> propsToAdd = new ArrayList<>();
4015                     for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
4016                         PropertyDefinition propFromDef = prop.getValue();
4017                         boolean propFound = false;
4018                         for (ComponentInstanceProperty cip : properties) {
4019                             if (propFromDef.getName().equals(cip.getName())) {
4020                                 //merge property value and property description only, ignore other fields
4021                                 if (cip.getDescription() != null && !cip.getDescription().equals(propFromDef.getDescription())) {
4022                                     propFromDef.setDescription(cip.getDescription());
4023                                 }
4024                                 propertyDataValueMergeBusinessLogic.mergePropertyValue(propFromDef, cip, new ArrayList<>());
4025                                 if (cip.getValue() != null) {
4026                                     propFromDef.setValue(cip.getValue());
4027                                 }
4028                                 propsToAdd.add(new ComponentInstanceProperty(propFromDef));
4029                                 propFound = true;
4030                                 properties.remove(cip);
4031                                 break;
4032                             }
4033                         }
4034                         if (!propFound) {
4035                             propsToAdd.add(new ComponentInstanceProperty(propFromDef));
4036                         }
4037                     }
4038                     if (!propsToAdd.isEmpty()) {
4039                         changedProperties.addAll(propsToAdd);
4040                     }
4041                 }
4042                 capDef.setProperties(changedProperties);
4043             }
4044         }
4045         return eitherResult;
4046     }
4047
4048     public Resource createResourceByDao(Resource resource, User user, AuditingActionEnum actionEnum, boolean isNormative, boolean inTransaction) {
4049         // create resource
4050
4051         // lock new resource name in order to avoid creation resource with same
4052
4053         // name
4054         Resource createdResource = null;
4055         if (!inTransaction) {
4056             Either<Boolean, ResponseFormat> lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE);
4057             if (lockResult.isRight()) {
4058                 ResponseFormat responseFormat = lockResult.right().value();
4059                 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4060                 throw new ByResponseFormatComponentException(responseFormat);
4061             }
4062             log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult);
4063         }
4064         try {
4065             if (resource.deriveFromGeneric()) {
4066                 handleResourceGenericType(resource);
4067             }
4068             createdResource = createResourceTransaction(resource, user, isNormative);
4069             componentsUtils.auditResource(componentsUtils.getResponseFormat(ActionStatus.CREATED), user, createdResource, actionEnum);
4070             ASDCKpiApi.countCreatedResourcesKPI();
4071         } catch (ComponentException e) {
4072             ResponseFormat responseFormat =
4073                     e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
4074             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4075             throw e;
4076         } catch (StorageException e) {
4077             ResponseFormat responseFormat = componentsUtils
4078                     .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
4079             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4080             throw e;
4081         } finally {
4082             if (!inTransaction) {
4083                 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
4084             }
4085         }
4086         return createdResource;
4087     }
4088
4089     private Resource createResourceTransaction(Resource resource, User user, boolean isNormative) {
4090         final String resourceName = resource.getName();
4091         final String modelName = resource.getModel();
4092         final ResourceTypeEnum resourceType = resource.getResourceType();
4093         final ComponentTypeEnum componentType = resource.getComponentType();
4094         final Either<Boolean, StorageOperationStatus> eitherValidation = toscaOperationFacade
4095                 .validateComponentNameAndModelExists(resourceName, modelName, resourceType, componentType);
4096         if (eitherValidation.isRight()) {
4097             loggerSupportability.log(LoggerSupportabilityActions.VALIDATE_NAME, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4098                     "ERROR while validate component name {} Status is: {}", resource.getName(), eitherValidation.right().value());
4099             log.debug("Failed to validate component name {}. Status is {}. ", resource.getName(), eitherValidation.right().value());
4100             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(eitherValidation.right().value()));
4101         }
4102         if (eitherValidation.left().value()) {
4103             log.debug("resource with name: {}, already exists", resource.getName());
4104             loggerSupportability
4105                     .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4106                             "resource with name: {} already exists", resource.getName());
4107             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4108                     resource.getName());
4109         }
4110         log.debug("send resource {} to dao for create", resource.getName());
4111         createArtifactsPlaceHolderData(resource, user);
4112         // enrich object
4113         if (!isNormative) {
4114             log.debug("enrich resource with creator, version and state");
4115             resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
4116             resource.setVersion(INITIAL_VERSION);
4117             resource.setHighestVersion(true);
4118             if (resource.getResourceType() != null && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4119                 resource.setAbstract(false);
4120             }
4121         }
4122         return toscaOperationFacade.createToscaComponent(resource).left().on(r -> throwComponentExceptionByResource(r, resource));
4123     }
4124
4125     private Resource throwComponentExceptionByResource(StorageOperationStatus status, Resource resource) {
4126         ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(status), resource);
4127         throw new ByResponseFormatComponentException(responseFormat);
4128     }
4129
4130     private void createArtifactsPlaceHolderData(Resource resource, User user) {
4131         // create mandatory artifacts
4132
4133         // TODO it must be removed after that artifact uniqueId creation will be
4134
4135         // moved to ArtifactOperation
4136         setInformationalArtifactsPlaceHolder(resource, user);
4137         setDeploymentArtifactsPlaceHolder(resource, user);
4138         setToscaArtifactsPlaceHolders(resource, user);
4139     }
4140
4141     @SuppressWarnings("unchecked")
4142     @Override
4143     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
4144         Resource resource = (Resource) component;
4145         Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
4146         if (artifactMap == null) {
4147             artifactMap = new HashMap<>();
4148         }
4149         Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4150                 .getDeploymentResourceArtifacts();
4151         if (deploymentResourceArtifacts != null) {
4152             Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
4153             deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
4154         }
4155         resource.setDeploymentArtifacts(artifactMap);
4156     }
4157
4158     private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
4159         Map<String, Object> artifactDetails = (Map<String, Object>) v;
4160         Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
4161         if (object != null) {
4162             List<String> artifactTypes = (List<String>) object;
4163             if (!artifactTypes.contains(resource.getResourceType().name())) {
4164                 return;
4165             }
4166         } else {
4167             log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
4168         }
4169         if (artifactsBusinessLogic != null) {
4170             ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4171                     .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
4172             if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
4173                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4174             }
4175         }
4176     }
4177
4178     @SuppressWarnings("unchecked")
4179     private void setInformationalArtifactsPlaceHolder(Resource resource, User user) {
4180         Map<String, ArtifactDefinition> artifactMap = resource.getArtifacts();
4181         if (artifactMap == null) {
4182             artifactMap = new HashMap<>();
4183         }
4184         String resourceUniqueId = resource.getUniqueId();
4185         List<String> exludeResourceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceCategory();
4186         List<String> exludeResourceType = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceType();
4187         Map<String, Object> informationalResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4188                 .getInformationalResourceArtifacts();
4189         List<CategoryDefinition> categories = resource.getCategories();
4190         boolean isCreateArtifact = true;
4191         if (exludeResourceCategory != null) {
4192             String category = categories.get(0).getName();
4193             isCreateArtifact = exludeResourceCategory.stream().noneMatch(e -> e.equalsIgnoreCase(category));
4194         }
4195         if (isCreateArtifact && exludeResourceType != null) {
4196             String resourceType = resource.getResourceType().name();
4197             isCreateArtifact = exludeResourceType.stream().noneMatch(e -> e.equalsIgnoreCase(resourceType));
4198         }
4199         if (informationalResourceArtifacts != null && isCreateArtifact) {
4200             Set<String> keys = informationalResourceArtifacts.keySet();
4201             for (String informationalResourceArtifactName : keys) {
4202                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalResourceArtifacts.get(informationalResourceArtifactName);
4203                 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4204                         .createArtifactPlaceHolderInfo(resourceUniqueId, informationalResourceArtifactName, artifactInfoMap, user,
4205                                 ArtifactGroupTypeEnum.INFORMATIONAL);
4206                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4207             }
4208         }
4209         resource.setArtifacts(artifactMap);
4210     }
4211
4212     /**
4213      * deleteResource
4214      *
4215      * @param resourceId
4216      * @param user
4217      * @return
4218      */
4219     public ResponseFormat deleteResource(String resourceId, User user) {
4220         ResponseFormat responseFormat;
4221         validateUserExists(user);
4222         Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4223         if (resourceStatus.isRight()) {
4224             log.debug("failed to get resource {}", resourceId);
4225             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), "");
4226         }
4227         Resource resource = resourceStatus.left().value();
4228         StorageOperationStatus result = StorageOperationStatus.OK;
4229         lockComponent(resourceId, resource, "Mark resource to delete");
4230         try {
4231             result = markComponentToDelete(resource);
4232             if (result == StorageOperationStatus.OK) {
4233                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4234             } else {
4235                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4236                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4237             }
4238             return responseFormat;
4239         } finally {
4240             if (!StorageOperationStatus.OK.equals(result)) {
4241                 janusGraphDao.rollback();
4242             } else {
4243                 janusGraphDao.commit();
4244             }
4245             graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
4246         }
4247     }
4248
4249     private boolean isComponentSystemDeployed(Resource resource) {
4250         return resource.getComponentMetadataDefinition().getMetadataDataDefinition().isNormative();
4251     }
4252
4253     /**
4254      * Deletes every version of the provided resource
4255      *
4256      * @param resourceId the resource identifier
4257      * @param user the user that performs the deletion
4258      * @return
4259      * @throws ComponentException if there is any error in the deletion of the resource operation
4260      */
4261     public void deleteResourceAllVersions(String resourceId, User user) {
4262         validateUserExists(user);
4263         Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4264         if (resourceStatus.isRight()) {
4265             log.debug("Failed to get resource {}", resourceId);
4266             componentException(resourceStatus.right().value());
4267         }
4268         Resource resource = resourceStatus.left().value();
4269         if (isComponentSystemDeployed(resource)) {
4270             throw new ByActionStatusComponentException(ActionStatus.CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES, ComponentTypeEnum.RESOURCE.getValue(),
4271                 resource.getName());
4272         }
4273         if (Boolean.FALSE.equals(resource.isArchived())) {
4274             log.debug("The resource, {}, requested for delete has not been archived.", resourceId);
4275             throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, resourceId);
4276         }
4277         try {
4278             String model = resource.getModel();
4279             final Optional<Model> modelOptional = modelOperation.findModelByName(model);
4280             List<String> deletedResourceList = toscaOperationFacade.deleteComponent(resource.getInvariantUUID(), NodeTypeEnum.Resource, true);
4281             if (log.isDebugEnabled()) {
4282                 deletedResourceList.forEach(deletedR -> log.debug("Component {} was deleted.", deletedR));
4283             }
4284             if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
4285                 modelOperation.deleteModel(modelOptional.get(), true);
4286             }
4287             toscaOperationFacade.commitAndCheck(resource.getUniqueId());
4288             updateCatalog(resource, ChangeTypeEnum.DELETE);
4289         } catch (ComponentException exception) {
4290             log.debug("Failed to delete resource, {} ", resourceId);
4291             janusGraphDao.rollback();
4292             throw exception;
4293         }
4294     }
4295
4296     public ResponseFormat deleteResourceByNameAndVersion(String resourceName, String version, User user) {
4297         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4298         validateUserExists(user);
4299         Resource resource = null;
4300         StorageOperationStatus result = StorageOperationStatus.OK;
4301         boolean failed = false;
4302         try {
4303             Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade
4304                     .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, version);
4305             if (resourceStatus.isRight()) {
4306                 log.debug("failed to get resource {} version {}", resourceName, version);
4307                 return componentsUtils
4308                         .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), resourceName);
4309             }
4310             resource = resourceStatus.left().value();
4311         } finally {
4312             janusGraphDao.commit();
4313         }
4314         if (resource != null) {
4315             lockComponent(resource.getUniqueId(), resource, DELETE_RESOURCE);
4316             try {
4317                 result = markComponentToDelete(resource);
4318                 if (result != StorageOperationStatus.OK) {
4319                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4320                     responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4321                     return responseFormat;
4322                 }
4323             } catch (ComponentException e) {
4324                 failed = true;
4325                 throw e;
4326             } finally {
4327                 if (failed || !StorageOperationStatus.OK.equals(result)) {
4328                     janusGraphDao.rollback();
4329                 } else {
4330                     janusGraphDao.commit();
4331                 }
4332                 graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource);
4333             }
4334         }
4335         return responseFormat;
4336     }
4337
4338     public Either<Resource, ResponseFormat> getResource(String resourceId, User user) {
4339         if (user != null) {
4340             validateUserExists(user);
4341         }
4342         Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceId);
4343         if (storageStatus.isRight()) {
4344             log.debug("failed to get resource by id {}", resourceId);
4345             return Either.right(
4346                     componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), resourceId));
4347         }
4348         if (storageStatus.left().value() == null) {
4349             return Either.right(componentsUtils
4350                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), resourceId));
4351         }
4352         return Either.left(storageStatus.left().value());
4353     }
4354
4355     public Either<Resource, ResponseFormat> getResourceByNameAndVersion(String resourceName, String resourceVersion, String userId) {
4356         validateUserExists(userId);
4357         Either<Resource, StorageOperationStatus> getResource = toscaOperationFacade
4358                 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion);
4359         if (getResource.isRight()) {
4360             log.debug("failed to get resource by name {} and version {}", resourceName, resourceVersion);
4361             return Either.right(
4362                     componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResource.right().value()), resourceName));
4363         }
4364         return Either.left(getResource.left().value());
4365     }
4366
4367     /**
4368      * updateResourceMetadata
4369      *
4370      * @param user               - modifier data (userId)
4371      * @param inTransaction      TODO
4372      * @param resourceIdToUpdate - the resource identifier
4373      * @param newResource
4374      * @return Either<Resource, responseFormat>
4375      */
4376     public Resource updateResourceMetadata(String resourceIdToUpdate, Resource newResource, Resource currentResource, User user,
4377                                            boolean inTransaction) {
4378         validateUserExists(user.getUserId());
4379         log.debug("Get resource with id {}", resourceIdToUpdate);
4380         boolean needToUnlock = false;
4381         try {
4382             if (currentResource == null) {
4383                 Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceIdToUpdate);
4384                 if (storageStatus.isRight()) {
4385                     throw new ByResponseFormatComponentException(
4386                             componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), ""));
4387                 }
4388                 currentResource = storageStatus.left().value();
4389             }
4390             // verify that resource is checked-out and the user is the last
4391
4392             // updater
4393             if (!ComponentValidationUtils.canWorkOnResource(currentResource, user.getUserId())) {
4394                 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
4395             }
4396             // lock resource
4397             StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4398             if (lockResult != StorageOperationStatus.OK) {
4399                 BeEcompErrorManager.getInstance()
4400                         .logBeFailedLockObjectError("Upload Artifact - lock ", NodeTypeEnum.Resource.getName(), resourceIdToUpdate);
4401                 log.debug("Failed to lock resource: {}, error - {}", resourceIdToUpdate, lockResult);
4402                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult));
4403                 throw new ByResponseFormatComponentException(responseFormat);
4404             }
4405             needToUnlock = true;
4406             // critical section starts here
4407
4408             // convert json to object
4409
4410             // Update and updated resource must have a non-empty "derivedFrom"
4411
4412             // list
4413
4414             // This code is not called from import resources, because of root
4415
4416             // VF "derivedFrom" should be null (or ignored)
4417             if (ModelConverter.isAtomicComponent(currentResource)) {
4418                 validateDerivedFromNotEmpty(null, newResource, null);
4419                 validateDerivedFromNotEmpty(null, currentResource, null);
4420             } else {
4421                 newResource.setDerivedFrom(null);
4422             }
4423             Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource, false,
4424                     true);
4425             if (dataModelResponse.isRight()) {
4426                 log.debug("failed to update resource metadata!!!");
4427                 throw new ByResponseFormatComponentException(dataModelResponse.right().value());
4428             }
4429             log.debug("Resource metadata updated successfully!!!");
4430             return dataModelResponse.left().value();
4431         } catch (ComponentException | StorageException e) {
4432             rollback(inTransaction, newResource, null, null);
4433             throw e;
4434         } finally {
4435             if (!inTransaction) {
4436                 janusGraphDao.commit();
4437             }
4438             if (needToUnlock) {
4439                 graphLockOperation.unlockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4440             }
4441         }
4442     }
4443
4444     private Either<Resource, ResponseFormat> updateResourceMetadata(String resourceIdToUpdate, Resource newResource, User user,
4445                                                                     Resource currentResource, boolean shouldLock, boolean inTransaction) {
4446         updateVfModuleGroupsNames(currentResource, newResource);
4447         validateResourceFieldsBeforeUpdate(currentResource, newResource, inTransaction, false);
4448         // Setting last updater and uniqueId
4449         newResource.setContactId(newResource.getContactId().toLowerCase());
4450         newResource.setLastUpdaterUserId(user.getUserId());
4451         newResource.setUniqueId(resourceIdToUpdate);
4452         // Cannot set highest version through UI
4453         newResource.setHighestVersion(currentResource.isHighestVersion());
4454         newResource.setCreationDate(currentResource.getCreationDate());
4455         Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom = processUpdateOfDerivedFrom(currentResource, newResource, user.getUserId(),
4456                 inTransaction);
4457         if (processUpdateOfDerivedFrom.isRight()) {
4458             log.debug("Couldn't update derived from for resource {}", resourceIdToUpdate);
4459             return Either.right(processUpdateOfDerivedFrom.right().value());
4460         }
4461         log.debug("send resource {} to dao for update", newResource.getUniqueId());
4462         if (isNotEmpty(newResource.getGroups())) {
4463             for (GroupDefinition group : newResource.getGroups()) {
4464                 if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
4465                     groupBusinessLogic
4466                             .validateAndUpdateGroupMetadata(newResource.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId(), user,
4467                                     newResource.getComponentType(), group, true, false);
4468                 }
4469             }
4470         }
4471         Either<Resource, StorageOperationStatus> dataModelResponse = toscaOperationFacade.updateToscaElement(newResource);
4472         if (dataModelResponse.isRight()) {
4473             ResponseFormat responseFormat = componentsUtils
4474                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), newResource);
4475             return Either.right(responseFormat);
4476         } else if (dataModelResponse.left().value() == null) {
4477             log.debug("No response from updateResource");
4478             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
4479         }
4480         return Either.left(dataModelResponse.left().value());
4481     }
4482
4483     private void updateVfModuleGroupsNames(Resource currentResource, Resource newResource) {
4484         if (currentResource.getGroups() != null && !currentResource.getName().equals(newResource.getName())) {
4485             List<GroupDefinition> updatedGroups = currentResource.getGroups().stream()
4486                     .map(group -> getUpdatedGroup(group, currentResource.getName(), newResource.getName())).collect(toList());
4487             newResource.setGroups(updatedGroups);
4488         }
4489     }
4490
4491     private GroupDefinition getUpdatedGroup(GroupDefinition currGroup, String replacePattern, String with) {
4492         GroupDefinition updatedGroup = new GroupDefinition(currGroup);
4493         if (updatedGroup.isSamePrefix(replacePattern) && updatedGroup.getType().equals(DEFAULT_GROUP_VF_MODULE)) {
4494             String prefix = updatedGroup.getName().substring(0, replacePattern.length());
4495             String newGroupName = updatedGroup.getName().replaceFirst(prefix, with);
4496             updatedGroup.setName(newGroupName);
4497         }
4498         return updatedGroup;
4499     }
4500
4501     /**
4502      * validateResourceFieldsBeforeCreate
4503      *
4504      * @param user - modifier data (userId)
4505      */
4506     private void validateResourceFieldsBeforeCreate(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4507         componentValidator.validate(user, resource, actionEnum);
4508         // validate category
4509         log.debug("validate category");
4510         validateCategory(user, resource, actionEnum, inTransaction);
4511         // validate vendor name & release & model number
4512         log.debug("validate vendor name");
4513         validateVendorName(user, resource, actionEnum);
4514         log.debug("validate vendor release");
4515         validateVendorReleaseName(user, resource, actionEnum);
4516         log.debug("validate resource vendor model number");
4517         validateResourceVendorModelNumber(user, resource, actionEnum);
4518         // validate cost
4519         log.debug("validate cost");
4520         validateCost(resource);
4521         // validate licenseType
4522         log.debug("validate licenseType");
4523         validateLicenseType(user, resource, actionEnum);
4524         // validate template (derived from)
4525         log.debug("validate derived from");
4526         if (!ModelConverter.isAtomicComponent(resource) && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4527             resource.setDerivedFrom(null);
4528         }
4529         validateDerivedFromExist(user, resource, actionEnum);
4530         // warn about non-updatable fields
4531         checkComponentFieldsForOverrideAttempt(resource);
4532         String currentCreatorFullName = resource.getCreatorFullName();
4533         if (currentCreatorFullName != null) {
4534             log.debug("Resource Creator fullname is automatically set and cannot be updated");
4535         }
4536         String currentLastUpdaterFullName = resource.getLastUpdaterFullName();
4537         if (currentLastUpdaterFullName != null) {
4538             log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4539         }
4540         Long currentLastUpdateDate = resource.getLastUpdateDate();
4541         if (currentLastUpdateDate != null) {
4542             log.debug("Resource last update date is automatically set and cannot be updated");
4543         }
4544         Boolean currentAbstract = resource.isAbstract();
4545         if (currentAbstract != null) {
4546             log.debug("Resource abstract is automatically set and cannot be updated");
4547         }
4548     }
4549
4550     /**
4551      * validateResourceFieldsBeforeUpdate
4552      *
4553      * @param currentResource - Resource object to validate
4554      * @param isNested
4555      */
4556     private void validateResourceFieldsBeforeUpdate(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4557         validateFields(currentResource, updateInfoResource, inTransaction, isNested);
4558         warnNonEditableFields(currentResource, updateInfoResource);
4559     }
4560
4561     private void warnNonEditableFields(Resource currentResource, Resource updateInfoResource) {
4562         String currentResourceVersion = currentResource.getVersion();
4563         String updatedResourceVersion = updateInfoResource.getVersion();
4564         if ((updatedResourceVersion != null) && (!updatedResourceVersion.equals(currentResourceVersion))) {
4565             log.debug("Resource version is automatically set and cannot be updated");
4566         }
4567         String currentCreatorUserId = currentResource.getCreatorUserId();
4568         String updatedCreatorUserId = updateInfoResource.getCreatorUserId();
4569         if ((updatedCreatorUserId != null) && (!updatedCreatorUserId.equals(currentCreatorUserId))) {
4570             log.debug("Resource Creator UserId is automatically set and cannot be updated");
4571         }
4572         String currentCreatorFullName = currentResource.getCreatorFullName();
4573         String updatedCreatorFullName = updateInfoResource.getCreatorFullName();
4574         if ((updatedCreatorFullName != null) && (!updatedCreatorFullName.equals(currentCreatorFullName))) {
4575             log.debug("Resource Creator fullname is automatically set and cannot be updated");
4576         }
4577         String currentLastUpdaterUserId = currentResource.getLastUpdaterUserId();
4578         String updatedLastUpdaterUserId = updateInfoResource.getLastUpdaterUserId();
4579         if ((updatedLastUpdaterUserId != null) && (!updatedLastUpdaterUserId.equals(currentLastUpdaterUserId))) {
4580             log.debug("Resource LastUpdater userId is automatically set and cannot be updated");
4581         }
4582         String currentLastUpdaterFullName = currentResource.getLastUpdaterFullName();
4583         String updatedLastUpdaterFullName = updateInfoResource.getLastUpdaterFullName();
4584         if ((updatedLastUpdaterFullName != null) && (!updatedLastUpdaterFullName.equals(currentLastUpdaterFullName))) {
4585             log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4586         }
4587         Long currentCreationDate = currentResource.getCreationDate();
4588         Long updatedCreationDate = updateInfoResource.getCreationDate();
4589         if ((updatedCreationDate != null) && (!updatedCreationDate.equals(currentCreationDate))) {
4590             log.debug("Resource Creation date is automatically set and cannot be updated");
4591         }
4592         Long currentLastUpdateDate = currentResource.getLastUpdateDate();
4593         Long updatedLastUpdateDate = updateInfoResource.getLastUpdateDate();
4594         if ((updatedLastUpdateDate != null) && (!updatedLastUpdateDate.equals(currentLastUpdateDate))) {
4595             log.debug("Resource last update date is automatically set and cannot be updated");
4596         }
4597         LifecycleStateEnum currentLifecycleState = currentResource.getLifecycleState();
4598         LifecycleStateEnum updatedLifecycleState = updateInfoResource.getLifecycleState();
4599         if ((updatedLifecycleState != null) && (!updatedLifecycleState.equals(currentLifecycleState))) {
4600             log.debug("Resource lifecycle state date is automatically set and cannot be updated");
4601         }
4602         Boolean currentAbstract = currentResource.isAbstract();
4603         Boolean updatedAbstract = updateInfoResource.isAbstract();
4604         if ((updatedAbstract != null) && (!updatedAbstract.equals(currentAbstract))) {
4605             log.debug("Resource abstract is automatically set and cannot be updated");
4606         }
4607         Boolean currentHighestVersion = currentResource.isHighestVersion();
4608         Boolean updatedHighestVersion = updateInfoResource.isHighestVersion();
4609         if ((updatedHighestVersion != null) && (!updatedHighestVersion.equals(currentHighestVersion))) {
4610             log.debug("Resource highest version is automatically set and cannot be updated");
4611         }
4612         String currentUuid = currentResource.getUUID();
4613         String updatedUuid = updateInfoResource.getUUID();
4614         if ((updatedUuid != null) && (!updatedUuid.equals(currentUuid))) {
4615             log.debug("Resource UUID is automatically set and cannot be updated");
4616         }
4617         log.debug("Resource Type  cannot be updated");
4618         String currentInvariantUuid = currentResource.getInvariantUUID();
4619         String updatedInvariantUuid = updateInfoResource.getInvariantUUID();
4620         if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
4621             log.debug("Resource invariant UUID is automatically set and cannot be updated");
4622             updateInfoResource.setInvariantUUID(currentInvariantUuid);
4623         }
4624     }
4625
4626     private void validateFields(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4627         boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentResource.getVersion());
4628         log.debug("validate resource name before update");
4629         validateResourceName(currentResource, updateInfoResource, hasBeenCertified, isNested);
4630         log.debug("validate description before update");
4631         componentDescriptionValidator.validateAndCorrectField(null, updateInfoResource, null);
4632         log.debug("validate icon before update");
4633         validateIcon(currentResource, updateInfoResource, hasBeenCertified);
4634         log.debug("validate tags before update");
4635         componentTagsValidator.validateAndCorrectField(null, updateInfoResource, null);
4636         log.debug("validate vendor name before update");
4637         validateVendorName(null, updateInfoResource, null);
4638         log.debug("validate resource vendor model number before update");
4639         validateResourceVendorModelNumber(currentResource, updateInfoResource);
4640         log.debug("validate vendor release before update");
4641         validateVendorReleaseName(null, updateInfoResource, null);
4642         log.debug("validate contact info before update");
4643         componentContactIdValidator.validateAndCorrectField(null, updateInfoResource, null);
4644         log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
4645         validateDerivedFromDuringUpdate(currentResource, updateInfoResource, hasBeenCertified);
4646         log.debug("validate category before update");
4647         validateCategory(currentResource, updateInfoResource, hasBeenCertified, inTransaction);
4648     }
4649
4650     private boolean isResourceNameEquals(Resource currentResource, Resource updateInfoResource) {
4651         String resourceNameUpdated = updateInfoResource.getName();
4652         String resourceNameCurrent = currentResource.getName();
4653         if (resourceNameCurrent.equals(resourceNameUpdated)) {
4654             return true;
4655         }
4656         // In case of CVFC type we should support the case of old VF with CVFC
4657
4658         // instances that were created without the "Cvfc" suffix
4659         return currentResource.getResourceType() == ResourceTypeEnum.CVFC && resourceNameUpdated
4660                 .equals(addCvfcSuffixToResourceName(resourceNameCurrent));
4661     }
4662
4663     private String addCvfcSuffixToResourceName(String resourceName) {
4664         return resourceName + "Cvfc";
4665     }
4666
4667     private void validateResourceName(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified, boolean isNested) {
4668         String resourceNameUpdated = updateInfoResource.getName();
4669         if (!isResourceNameEquals(currentResource, updateInfoResource)) {
4670             if (isNested || !hasBeenCertified) {
4671                 componentNameValidator.validateAndCorrectField(null, updateInfoResource, null);
4672                 validateResourceNameUniqueness(updateInfoResource);
4673                 currentResource.setName(resourceNameUpdated);
4674                 currentResource.setNormalizedName(ValidationUtils.normaliseComponentName(resourceNameUpdated));
4675                 currentResource.setSystemName(ValidationUtils.convertToSystemName(resourceNameUpdated));
4676             } else {
4677                 log.info("Resource name: {}, cannot be updated once the resource has been certified once.", resourceNameUpdated);
4678                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NAME_CANNOT_BE_CHANGED);
4679             }
4680         }
4681     }
4682
4683     private void validateIcon(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) {
4684         String iconUpdated = updateInfoResource.getIcon();
4685         String iconCurrent = currentResource.getIcon();
4686         if (!iconCurrent.equals(iconUpdated)) {
4687             if (!hasBeenCertified) {
4688                 componentIconValidator.validateAndCorrectField(null, updateInfoResource, null);
4689             } else {
4690                 log.info("Icon {} cannot be updated once the resource has been certified once.", iconUpdated);
4691                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_ICON_CANNOT_BE_CHANGED);
4692             }
4693         }
4694     }
4695
4696     private void validateResourceVendorModelNumber(Resource currentResource, Resource updateInfoResource) {
4697         String updatedResourceVendorModelNumber = updateInfoResource.getResourceVendorModelNumber();
4698         String currentResourceVendorModelNumber = currentResource.getResourceVendorModelNumber();
4699         if (!currentResourceVendorModelNumber.equals(updatedResourceVendorModelNumber)) {
4700             validateResourceVendorModelNumber(null, updateInfoResource, null);
4701         }
4702     }
4703
4704     private Either<Boolean, ResponseFormat> validateCategory(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified,
4705                                                              boolean inTransaction) {
4706         validateCategory(null, updateInfoResource, null, inTransaction);
4707         if (hasBeenCertified) {
4708             CategoryDefinition currentCategory = currentResource.getCategories().get(0);
4709             SubCategoryDefinition currentSubCategory = currentCategory.getSubcategories().get(0);
4710             CategoryDefinition updateCategory = updateInfoResource.getCategories().get(0);
4711             SubCategoryDefinition updtaeSubCategory = updateCategory.getSubcategories().get(0);
4712             if (!currentCategory.getName().equals(updateCategory.getName()) || !currentSubCategory.getName().equals(updtaeSubCategory.getName())) {
4713                 log.info("Category {} cannot be updated once the resource has been certified once.", currentResource.getCategories());
4714                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CATEGORY_CANNOT_BE_CHANGED);
4715                 return Either.right(errorResponse);
4716             }
4717         }
4718         return Either.left(true);
4719     }
4720
4721     private Either<Boolean, ResponseFormat> validateDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4722                                                                             boolean hasBeenCertified) {
4723         List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4724         List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4725         if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4726             log.trace("Update normative types");
4727             return Either.left(true);
4728         }
4729         String derivedFromCurrent = currentDerivedFrom.get(0);
4730         String derivedFromUpdated = updatedDerivedFrom.get(0);
4731         if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4732             if (!hasBeenCertified) {
4733                 validateDerivedFromExist(null, updateInfoResource, null);
4734             } else {
4735                 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4736                         null);
4737                 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4738                     log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4739                     return validateDerivedFromExtending;
4740                 }
4741             }
4742         } else {
4743             // For derived from, we must know whether it was actually changed,
4744
4745             // otherwise we must do no action.
4746
4747             // Due to changes it inflicts on data model (remove artifacts,
4748
4749             // properties...), it's not like a flat field which can be
4750
4751             // overwritten if not changed.
4752
4753             // So we must indicate that derived from is not changed
4754             updateInfoResource.setDerivedFrom(null);
4755         }
4756         return Either.left(true);
4757     }
4758
4759     private Either<Boolean, ResponseFormat> validateNestedDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4760                                                                                   boolean hasBeenCertified) {
4761         List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4762         List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4763         if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4764             log.trace("Update normative types");
4765             return Either.left(true);
4766         }
4767         String derivedFromCurrent = currentDerivedFrom.get(0);
4768         String derivedFromUpdated = updatedDerivedFrom.get(0);
4769         if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4770             if (!hasBeenCertified) {
4771                 validateDerivedFromExist(null, updateInfoResource, null);
4772             } else {
4773                 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4774                         null);
4775                 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4776                     log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4777                     return validateDerivedFromExtending;
4778                 }
4779             }
4780         }
4781         return Either.left(true);
4782     }
4783
4784     private void validateDerivedFromExist(User user, Resource resource, AuditingActionEnum actionEnum) {
4785         if (resource.getDerivedFrom() == null || resource.getDerivedFrom().isEmpty()) {
4786             return;
4787         }
4788         String templateName = resource.getDerivedFrom().get(0);
4789         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateToscaResourceNameExists(templateName);
4790         if (dataModelResponse.isRight()) {
4791             StorageOperationStatus storageStatus = dataModelResponse.right().value();
4792             BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateDerivedFromExist");
4793             log.debug("request to data model failed with error: {}", storageStatus);
4794             ResponseFormat responseFormat = componentsUtils
4795                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), resource);
4796             log.trace("audit before sending response");
4797             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4798             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageStatus));
4799         } else if (!dataModelResponse.left().value()) {
4800             log.info("resource template with name: {}, does not exists", templateName);
4801             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4802             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4803             throw new ByActionStatusComponentException(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4804         }
4805     }
4806
4807     // Tal G for extending inheritance US815447
4808     private Either<Boolean, ResponseFormat> validateDerivedFromExtending(User user, Resource currentResource, Resource updateInfoResource,
4809                                                                          AuditingActionEnum actionEnum) {
4810         String currentTemplateName = currentResource.getDerivedFrom().get(0);
4811         String updatedTemplateName = updateInfoResource.getDerivedFrom().get(0);
4812         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
4813                 .validateToscaResourceNameExtends(currentTemplateName, updatedTemplateName, currentResource.getModel());
4814         if (dataModelResponse.isRight()) {
4815             StorageOperationStatus storageStatus = dataModelResponse.right().value();
4816             BeEcompErrorManager.getInstance().logBeDaoSystemError("Create/Update Resource - validateDerivingFromExtendingType");
4817             ResponseFormat responseFormat = componentsUtils
4818                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), currentResource);
4819             log.trace("audit before sending response");
4820             componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4821             return Either.right(responseFormat);
4822         }
4823         if (!dataModelResponse.left().value()) {
4824             log.info("resource template with name {} does not inherit as original {}", updatedTemplateName, currentTemplateName);
4825             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_DOES_NOT_EXTEND);
4826             componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4827             return Either.right(responseFormat);
4828         }
4829         return Either.left(true);
4830     }
4831
4832     public void validateDerivedFromNotEmpty(User user, Resource resource, AuditingActionEnum actionEnum) {
4833         log.debug("validate resource derivedFrom field");
4834         if ((resource.getDerivedFrom() == null) || (resource.getDerivedFrom().isEmpty()) || (resource.getDerivedFrom().get(0)) == null || (resource
4835                 .getDerivedFrom().get(0).trim().isEmpty())) {
4836             log.info("derived from (template) field is missing for the resource");
4837             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4838             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4839             throw new ByActionStatusComponentException(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4840         }
4841     }
4842
4843     private void validateResourceNameUniqueness(Resource resource) {
4844         Either<Boolean, StorageOperationStatus> resourceOperationResponse = toscaOperationFacade
4845                 .validateComponentNameExists(resource.getName(), resource.getResourceType(), resource.getComponentType());
4846         if (resourceOperationResponse.isLeft() && resourceOperationResponse.left().value()) {
4847             log.debug("resource with name: {}, already exists", resource.getName());
4848             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4849                     resource.getName());
4850         } else if (resourceOperationResponse.isRight()) {
4851             log.debug("error while validateResourceNameExists for resource: {}", resource.getName());
4852             throw new StorageException(resourceOperationResponse.right().value());
4853         }
4854     }
4855
4856     private void validateCategory(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4857         List<CategoryDefinition> categories = resource.getCategories();
4858         if (CollectionUtils.isEmpty(categories)) {
4859             log.debug(CATEGORY_IS_EMPTY);
4860             ResponseFormat responseFormat = componentsUtils
4861                     .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4862             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4863             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4864         }
4865         if (categories.size() > 1) {
4866             log.debug("Must be only one category for resource");
4867             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.RESOURCE.getValue());
4868         }
4869         CategoryDefinition category = categories.get(0);
4870         List<SubCategoryDefinition> subcategories = category.getSubcategories();
4871         if (CollectionUtils.isEmpty(subcategories)) {
4872             log.debug("Missinig subcategory for resource");
4873             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY);
4874         }
4875         if (subcategories.size() > 1) {
4876             log.debug("Must be only one sub category for resource");
4877             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_TOO_MUCH_SUBCATEGORIES);
4878         }
4879         SubCategoryDefinition subcategory = subcategories.get(0);
4880         if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
4881             log.debug(CATEGORY_IS_EMPTY);
4882             ResponseFormat responseFormat = componentsUtils
4883                     .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4884             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4885             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4886         }
4887         if (!ValidationUtils.validateStringNotEmpty(subcategory.getName())) {
4888             log.debug(CATEGORY_IS_EMPTY);
4889             ResponseFormat responseFormat = componentsUtils
4890                     .getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4891             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4892             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4893         }
4894         validateCategoryListed(category, subcategory, user, resource, actionEnum, inTransaction);
4895     }
4896
4897     private void validateCategoryListed(CategoryDefinition category, SubCategoryDefinition subcategory, User user, Resource resource,
4898                                         AuditingActionEnum actionEnum, boolean inTransaction) {
4899         ResponseFormat responseFormat;
4900         if (category != null && subcategory != null) {
4901             log.debug("validating resource category {} against valid categories list", category);
4902             Either<List<CategoryDefinition>, ActionStatus> categories = elementDao.getAllCategories(NodeTypeEnum.ResourceNewCategory, inTransaction);
4903             if (categories.isRight()) {
4904                 log.debug("failed to retrieve resource categories from JanusGraph");
4905                 responseFormat = componentsUtils.getResponseFormat(categories.right().value());
4906                 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4907                 throw new ByActionStatusComponentException(categories.right().value());
4908             }
4909             List<CategoryDefinition> categoryList = categories.left().value();
4910             Optional<CategoryDefinition> foundCategory = categoryList.stream().filter(cat -> cat.getName().equals(category.getName())).findFirst();
4911             if (foundCategory.isEmpty()) {
4912                 log.debug("Category {} is not part of resource category group. Resource category valid values are {}", category, categoryList);
4913                 failOnInvalidCategory(user, resource, actionEnum);
4914                 return; // explisite output even if failOnInvalidCategory throw an exception
4915             }
4916             Optional<SubCategoryDefinition> foundSubcategory = foundCategory.get().getSubcategories().stream()
4917                     .filter(subcat -> subcat.getName().equals(subcategory.getName())).findFirst();
4918             if (foundSubcategory.isEmpty()) {
4919                 log.debug("SubCategory {} is not part of resource category group. Resource subcategory valid values are {}", subcategory,
4920                         foundCategory.get().getSubcategories());
4921                 failOnInvalidCategory(user, resource, actionEnum);
4922             }
4923         }
4924     }
4925
4926     private void failOnInvalidCategory(User user, Resource resource, AuditingActionEnum actionEnum) {
4927         ResponseFormat responseFormat;
4928         responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4929         componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4930         throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4931     }
4932
4933     public void validateVendorReleaseName(User user, Resource resource, AuditingActionEnum actionEnum) {
4934         String vendorRelease = resource.getVendorRelease();
4935         log.debug("validate vendor relese name");
4936         if (!ValidationUtils.validateStringNotEmpty(vendorRelease)) {
4937             log.info("vendor relese name is missing.");
4938             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_RELEASE);
4939             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4940             throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_RELEASE);
4941         }
4942         validateVendorReleaseName(vendorRelease, user, resource, actionEnum);
4943     }
4944
4945     public void validateVendorReleaseName(String vendorRelease, User user, Resource resource, AuditingActionEnum actionEnum) {
4946         if (vendorRelease != null) {
4947             if (!ValidationUtils.validateVendorReleaseLength(vendorRelease)) {
4948                 log.info("vendor release exceds limit.");
4949                 ResponseFormat errorResponse = componentsUtils
4950                         .getResponseFormat(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4951                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4952                 throw new ByActionStatusComponentException(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4953             }
4954             if (!ValidationUtils.validateVendorRelease(vendorRelease)) {
4955                 log.info("vendor release  is not valid.");
4956                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_RELEASE);
4957                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4958                 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_RELEASE, vendorRelease);
4959             }
4960         }
4961     }
4962
4963     private void validateVendorName(User user, Resource resource, AuditingActionEnum actionEnum) {
4964         String vendorName = resource.getVendorName();
4965         if (!ValidationUtils.validateStringNotEmpty(vendorName)) {
4966             log.info("vendor name is missing.");
4967             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_NAME);
4968             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4969             throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_NAME);
4970         }
4971         validateVendorName(vendorName, user, resource, actionEnum);
4972     }
4973
4974     private void validateVendorName(String vendorName, User user, Resource resource, AuditingActionEnum actionEnum) {
4975         if (vendorName != null) {
4976             if (!ValidationUtils.validateVendorNameLength(vendorName)) {
4977                 log.info("vendor name exceds limit.");
4978                 ResponseFormat errorResponse = componentsUtils
4979                         .getResponseFormat(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4980                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4981                 throw new ByActionStatusComponentException(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4982             }
4983             if (!ValidationUtils.validateVendorName(vendorName)) {
4984                 log.info("vendor name  is not valid.");
4985                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_NAME);
4986                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4987                 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_NAME, vendorName);
4988             }
4989         }
4990     }
4991
4992     private void validateResourceVendorModelNumber(User user, Resource resource, AuditingActionEnum actionEnum) {
4993         String resourceVendorModelNumber = resource.getResourceVendorModelNumber();
4994         if (StringUtils.isNotEmpty(resourceVendorModelNumber)) {
4995             if (!ValidationUtils.validateResourceVendorModelNumberLength(resourceVendorModelNumber)) {
4996                 log.info("resource vendor model number exceeds limit.");
4997                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4998                         "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4999                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
5000                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
5001                         "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
5002             }
5003             // resource vendor model number is currently validated as vendor
5004
5005             // name
5006             if (!ValidationUtils.validateVendorName(resourceVendorModelNumber)) {
5007                 log.info("resource vendor model number  is not valid.");
5008                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
5009                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
5010                 throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
5011             }
5012         }
5013     }
5014
5015     private void validateCost(Resource resource) {
5016         String cost = resource.getCost();
5017         if (cost != null) {
5018             if (!ValidationUtils.validateCost(cost)) {
5019                 log.debug("resource cost is invalid.");
5020                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
5021             }
5022         }
5023     }
5024
5025     private void validateLicenseType(User user, Resource resource, AuditingActionEnum actionEnum) {
5026         log.debug("validate licenseType");
5027         String licenseType = resource.getLicenseType();
5028         if (licenseType != null) {
5029             List<String> licenseTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getLicenseTypes();
5030             if (!licenseTypes.contains(licenseType)) {
5031                 log.debug("License type {} isn't configured", licenseType);
5032                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
5033                 if (actionEnum != null) {
5034                     // In update case, no audit is required
5035                     componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
5036                 }
5037                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
5038             }
5039         }
5040     }
5041
5042     private Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom(Resource currentResource, Resource updatedResource, String userId,
5043                                                                        boolean inTransaction) {
5044         if (updatedResource.getDerivedFrom() != null) {
5045             log.debug("Starting derived from update for resource {}", updatedResource.getUniqueId());
5046             log.debug("1. Removing interface artifacts from graph");
5047             // Remove all interface artifacts of resource
5048             String resourceId = updatedResource.getUniqueId();
5049             Map<String, InterfaceDefinition> interfaces = currentResource.getInterfaces();
5050             if (interfaces != null) {
5051                 Collection<InterfaceDefinition> values = interfaces.values();
5052                 for (InterfaceDefinition interfaceDefinition : values) {
5053                     String interfaceType = interfaceTypeOperation.getShortInterfaceName(interfaceDefinition);
5054                     log.trace("Starting interface artifacts removal for interface type {}", interfaceType);
5055                     Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
5056                     if (operations != null) {
5057                         for (Entry<String, Operation> operationEntry : operations.entrySet()) {
5058                             Operation operation = operationEntry.getValue();
5059                             ArtifactDefinition implementation = operation.getImplementationArtifact();
5060                             if (implementation != null) {
5061                                 String uniqueId = implementation.getUniqueId();
5062                                 log.debug("Removing interface artifact definition {}, operation {}, interfaceType {}", uniqueId,
5063                                         operationEntry.getKey(), interfaceType);
5064                                 // only thing that transacts and locks here
5065                                 Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface = artifactsBusinessLogic
5066                                         .deleteArtifactByInterface(resourceId, userId, uniqueId, true);
5067                                 if (deleteArtifactByInterface.isRight()) {
5068                                     log.debug("Couldn't remove artifact definition with id {}", uniqueId);
5069                                     if (!inTransaction) {
5070                                         janusGraphDao.rollback();
5071                                     }
5072                                     return Either.right(deleteArtifactByInterface.right().value());
5073                                 }
5074                             } else {
5075                                 log.trace("No implementation found for operation {} - nothing to delete", operationEntry.getKey());
5076                             }
5077                         }
5078                     } else {
5079                         log.trace("No operations found for interface type {}", interfaceType);
5080                     }
5081                 }
5082             }
5083             log.debug("2. Removing properties");
5084             Either<Map<String, PropertyDefinition>, StorageOperationStatus> findPropertiesOfNode = propertyOperation
5085                     .deleteAllPropertiesAssociatedToNode(NodeTypeEnum.Resource, resourceId);
5086             if (findPropertiesOfNode.isRight() && findPropertiesOfNode.right().value() != StorageOperationStatus.OK) {
5087                 log.debug("Failed to remove all properties of resource");
5088                 if (!inTransaction) {
5089                     janusGraphDao.rollback();
5090                 }
5091                 return Either
5092                         .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findPropertiesOfNode.right().value())));
5093             }
5094         } else {
5095             log.debug("Derived from wasn't changed during update");
5096         }
5097         if (inTransaction) {
5098             return Either.left(true);
5099         }
5100         janusGraphDao.commit();
5101         return Either.left(true);
5102     }
5103
5104     public ICapabilityTypeOperation getCapabilityTypeOperation() {
5105         return capabilityTypeOperation;
5106     }
5107
5108     @Autowired
5109     public void setCapabilityTypeOperation(ICapabilityTypeOperation capabilityTypeOperation) {
5110         this.capabilityTypeOperation = capabilityTypeOperation;
5111     }
5112
5113     public Boolean validatePropertiesDefaultValues(Resource resource) {
5114         log.debug("validate resource properties default values");
5115         List<PropertyDefinition> properties = resource.getProperties();
5116         if (properties != null) {
5117             iterateOverProperties(properties, resource.getModel());
5118         }
5119         return true;
5120     }
5121
5122     public void iterateOverProperties(List<PropertyDefinition> properties, String model) {
5123         String type = null;
5124         String innerType = null;
5125         for (PropertyDefinition property : properties) {
5126             if (!propertyOperation.isPropertyTypeValid(property, model)) {
5127                 log.info("Invalid type for property {}", property);
5128                 throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
5129             }
5130             Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
5131             type = property.getType();
5132             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5133                 ResponseFormat responseFormat = validateMapOrListPropertyType(property, innerType, allDataTypes);
5134                 if (responseFormat != null) {
5135                     break;
5136                 }
5137             }
5138             validateDefaultPropertyValue(property, allDataTypes, type, innerType);
5139         }
5140     }
5141
5142     private void validateDefaultPropertyValue(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes, String type,
5143                                               String innerType) {
5144         if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes)) {
5145             log.info("Invalid default value for property {}", property);
5146             ResponseFormat responseFormat;
5147             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5148                 throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
5149                         property.getDefaultValue());
5150             }
5151             throw new ByActionStatusComponentException(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
5152         }
5153     }
5154
5155     private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property, String innerType,
5156                                                          Map<String, DataTypeDefinition> allDataTypes) {
5157         ResponseFormat responseFormat = null;
5158         ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, allDataTypes);
5159         innerType = propertyInnerTypeValid.getLeft();
5160         if (!propertyInnerTypeValid.getRight()) {
5161             log.info("Invalid inner type for property {}", property);
5162             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
5163         }
5164         return responseFormat;
5165     }
5166
5167     @Override
5168     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
5169         return deleteMarkedComponents(ComponentTypeEnum.RESOURCE);
5170     }
5171
5172     @Override
5173     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
5174         return componentInstanceBusinessLogic;
5175     }
5176
5177     private String getComponentTypeForResponse(Component component) {
5178         String componentTypeForResponse = "SERVICE";
5179         if (component instanceof Resource) {
5180             componentTypeForResponse = ((Resource) component).getResourceType().name();
5181         }
5182         return componentTypeForResponse;
5183     }
5184
5185     public Either<Resource, ResponseFormat> getLatestResourceFromCsarUuid(String csarUuid, User user) {
5186         // validate user
5187         if (user != null) {
5188             validateUserExists(user);
5189         }
5190         // get resource from csar uuid
5191         Either<Resource, StorageOperationStatus> either = toscaOperationFacade
5192                 .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUuid, "");
5193         if (either.isRight()) {
5194             ResponseFormat resp = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUuid);
5195             return Either.right(resp);
5196         }
5197         return Either.left(either.left().value());
5198     }
5199
5200     @Override
5201     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
5202         return null;
5203     }
5204
5205     private Map<String, List<CapabilityDefinition>> getValidComponentInstanceCapabilities(String resourceId,
5206                                                                                           Map<String, List<CapabilityDefinition>> defaultCapabilities,
5207                                                                                           Map<String, List<UploadCapInfo>> uploadedCapabilities) {
5208         Map<String, List<CapabilityDefinition>> validCapabilitiesMap = new HashMap<>();
5209         uploadedCapabilities.forEach((k, v) -> addValidComponentInstanceCapabilities(k, v, resourceId, defaultCapabilities, validCapabilitiesMap));
5210         return validCapabilitiesMap;
5211     }
5212
5213     private void addValidComponentInstanceCapabilities(String key, List<UploadCapInfo> capabilities, String resourceId,
5214                                                        Map<String, List<CapabilityDefinition>> defaultCapabilities,
5215                                                        Map<String, List<CapabilityDefinition>> validCapabilitiesMap) {
5216         String capabilityType = capabilities.get(0).getType();
5217         if (defaultCapabilities.containsKey(capabilityType)) {
5218             CapabilityDefinition defaultCapability = getCapability(resourceId, defaultCapabilities, capabilityType);
5219             validateCapabilityProperties(capabilities, resourceId, defaultCapability);
5220             List<CapabilityDefinition> validCapabilityList = new ArrayList<>();
5221             validCapabilityList.add(defaultCapability);
5222             validCapabilitiesMap.put(key, validCapabilityList);
5223         } else {
5224             throw new ByActionStatusComponentException(ActionStatus.MISSING_CAPABILITY_TYPE, capabilityType);
5225         }
5226     }
5227
5228     private void validateCapabilityProperties(List<UploadCapInfo> capabilities, String resourceId, CapabilityDefinition defaultCapability) {
5229         if (CollectionUtils.isEmpty(defaultCapability.getProperties()) && isNotEmpty(capabilities.get(0).getProperties())) {
5230             log.debug("Failed to validate capability {} of component {}. Property list is empty. ", defaultCapability.getName(), resourceId);
5231             log.debug("Failed to update capability property values. Property list of fetched capability {} is empty. ", defaultCapability.getName());
5232             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, resourceId);
5233         } else if (isNotEmpty(capabilities.get(0).getProperties())) {
5234             validateUniquenessUpdateUploadedComponentInstanceCapability(defaultCapability, capabilities.get(0));
5235         }
5236     }
5237
5238     private CapabilityDefinition getCapability(String resourceId, Map<String, List<CapabilityDefinition>> defaultCapabilities,
5239                                                String capabilityType) {
5240         CapabilityDefinition defaultCapability;
5241         if (isNotEmpty(defaultCapabilities.get(capabilityType).get(0).getProperties())) {
5242             defaultCapability = defaultCapabilities.get(capabilityType).get(0);
5243         } else {
5244             Either<Component, StorageOperationStatus> getFullComponentRes = toscaOperationFacade.getToscaFullElement(resourceId);
5245             if (getFullComponentRes.isRight()) {
5246                 log.debug("Failed to get full component {}. Status is {}. ", resourceId, getFullComponentRes.right().value());
5247                 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, resourceId);
5248             }
5249             defaultCapability = getFullComponentRes.left().value().getCapabilities().get(capabilityType).get(0);
5250         }
5251         return defaultCapability;
5252     }
5253
5254     private void validateUniquenessUpdateUploadedComponentInstanceCapability(CapabilityDefinition defaultCapability,
5255                                                                              UploadCapInfo uploadedCapability) {
5256         List<ComponentInstanceProperty> validProperties = new ArrayList<>();
5257         Map<String, PropertyDefinition> defaultProperties = defaultCapability.getProperties().stream()
5258                 .collect(toMap(PropertyDefinition::getName, Function.identity()));
5259         List<UploadPropInfo> uploadedProperties = uploadedCapability.getProperties();
5260         for (UploadPropInfo property : uploadedProperties) {
5261             String propertyName = property.getName().toLowerCase();
5262             String propertyType = property.getType();
5263             ComponentInstanceProperty validProperty;
5264             if (defaultProperties.containsKey(propertyName) && propertTypeEqualsTo(defaultProperties, propertyName, propertyType)) {
5265                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, propertyName);
5266             }
5267             validProperty = new ComponentInstanceProperty();
5268             validProperty.setName(propertyName);
5269             if (property.getValue() != null) {
5270                 validProperty.setValue(property.getValue().toString());
5271             }
5272             validProperty.setDescription(property.getDescription());
5273             validProperty.setPassword(property.isPassword());
5274             validProperties.add(validProperty);
5275         }
5276         defaultCapability.setProperties(validProperties);
5277     }
5278
5279     private boolean propertTypeEqualsTo(Map<String, PropertyDefinition> defaultProperties, String propertyName, String propertyType) {
5280         return propertyType != null && !defaultProperties.get(propertyName).getType().equals(propertyType);
5281     }
5282
5283     private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> organizeVfCsarArtifactsByArtifactOperation(
5284             List<NonMetaArtifactInfo> artifactPathAndNameList, List<ArtifactDefinition> existingArtifactsToHandle, Resource resource, User user) {
5285         EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
5286         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
5287         Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> nodeTypeArtifactsToHandleRes = Either
5288                 .left(nodeTypeArtifactsToHandle);
5289         try {
5290             // add all found Csar artifacts to list to upload
5291             List<NonMetaArtifactInfo> artifactsToUpload = new ArrayList<>(artifactPathAndNameList);
5292             List<NonMetaArtifactInfo> artifactsToUpdate = new ArrayList<>();
5293             List<NonMetaArtifactInfo> artifactsToDelete = new ArrayList<>();
5294             for (NonMetaArtifactInfo currNewArtifact : artifactPathAndNameList) {
5295                 ArtifactDefinition foundArtifact;
5296                 if (!existingArtifactsToHandle.isEmpty()) {
5297                     foundArtifact = existingArtifactsToHandle.stream().filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName()))
5298                             .findFirst().orElse(null);
5299                     if (foundArtifact != null) {
5300                         if (foundArtifact.getArtifactType().equals(currNewArtifact.getArtifactType())) {
5301                             if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
5302                                 currNewArtifact.setArtifactUniqueId(foundArtifact.getUniqueId());
5303                                 // if current artifact already exists, but has
5304
5305                                 // different content, add him to the list to
5306
5307                                 // update
5308                                 artifactsToUpdate.add(currNewArtifact);
5309                             }
5310                             // remove found artifact from the list of existing
5311
5312                             // artifacts to handle, because it was already
5313
5314                             // handled
5315                             existingArtifactsToHandle.remove(foundArtifact);
5316                             // and remove found artifact from the list to
5317
5318                             // upload, because it should either be updated or be
5319
5320                             // ignored
5321                             artifactsToUpload.remove(currNewArtifact);
5322                         } else {
5323                             log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
5324                             ResponseFormat responseFormat = ResponseFormatManager.getInstance()
5325                                     .getResponseFormat(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, currNewArtifact.getArtifactName(),
5326                                             currNewArtifact.getArtifactType(), foundArtifact.getArtifactType());
5327                             AuditingActionEnum auditingAction = artifactsBusinessLogic
5328                                     .detectAuditingType(new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE),
5329                                             foundArtifact.getArtifactChecksum());
5330                             artifactsBusinessLogic
5331                                     .handleAuditing(auditingAction, resource, resource.getUniqueId(), user, null, null, foundArtifact.getUniqueId(),
5332                                             responseFormat, resource.getComponentType(), null);
5333                             responseWrapper.setInnerElement(responseFormat);
5334                             break;
5335                         }
5336                     }
5337                 }
5338             }
5339             if (responseWrapper.isEmpty()) {
5340                 for (ArtifactDefinition currArtifact : existingArtifactsToHandle) {
5341                     if (currArtifact.getIsFromCsar()) {
5342                         artifactsToDelete.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5343                                 currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5344                     } else {
5345                         artifactsToUpdate.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5346                                 currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5347                     }
5348                 }
5349             }
5350             if (responseWrapper.isEmpty()) {
5351                 if (!artifactsToUpload.isEmpty()) {
5352                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
5353                 }
5354                 if (!artifactsToUpdate.isEmpty()) {
5355                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
5356                 }
5357                 if (!artifactsToDelete.isEmpty()) {
5358                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
5359                 }
5360             }
5361             if (!responseWrapper.isEmpty()) {
5362                 nodeTypeArtifactsToHandleRes = Either.right(responseWrapper.getInnerElement());
5363             }
5364         } catch (Exception e) {
5365             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
5366             responseWrapper.setInnerElement(responseFormat);
5367             log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
5368         }
5369         return nodeTypeArtifactsToHandleRes;
5370     }
5371
5372     ImmutablePair<String, String> buildNestedToscaResourceName(final String nodeResourceType, final String vfResourceName,
5373                                                                final String nodeTypeFullName) {
5374         String actualType;
5375         String actualVfName;
5376         if (ResourceTypeEnum.CVFC.name().equals(nodeResourceType)) {
5377             actualVfName = vfResourceName + ResourceTypeEnum.CVFC.name();
5378             actualType = ResourceTypeEnum.VFC.name();
5379         } else {
5380             actualVfName = vfResourceName;
5381             actualType = nodeResourceType;
5382         }
5383         String nameWithouNamespacePrefix;
5384         try {
5385             final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
5386             log.debug("####### buildNestedToscaResourceName nodeResourceType {}, vfResourceName {}, "
5387                             + "nodeTypeFullName {}, actualType {}, vfResourceName {} ", nodeResourceType, vfResourceName, nodeTypeFullName, actualType,
5388                     vfResourceName);
5389             final StringBuilder toscaResourceName = new StringBuilder(nodeTypeNamePrefix);
5390             if (!nodeTypeFullName.contains(nodeTypeNamePrefix)) {
5391                 nameWithouNamespacePrefix = nodeTypeFullName;
5392             } else {
5393                 nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.length());
5394             }
5395             final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
5396             String actualName;
5397             if (nodeResourceType.equalsIgnoreCase(findTypes[0])) {
5398                 actualName = nameWithouNamespacePrefix.substring(nodeResourceType.length());
5399             } else {
5400                 actualName = "." + nameWithouNamespacePrefix;
5401             }
5402             if (actualName.startsWith(Constants.ABSTRACT)) {
5403                 toscaResourceName.append(nodeResourceType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName));
5404             } else {
5405                 toscaResourceName.append(actualType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName)).append('.')
5406                         .append(Constants.ABSTRACT);
5407             }
5408             final StringBuilder previousToscaResourceName = new StringBuilder(toscaResourceName);
5409             final String[] actualNames = actualName.split("\\.");
5410             if (actualNames.length < 3) {
5411                 return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5412                         previousToscaResourceName.append(actualName).toString());
5413             }
5414             return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5415                     previousToscaResourceName.append(actualName.substring(actualNames[1].length() + 1).toLowerCase()).toString());
5416         } catch (final Exception e) {
5417             log.debug("Exception occured when buildNestedToscaResourceName, error is:{}", e.getMessage(), e);
5418             throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE, vfResourceName);
5419         }
5420     }
5421
5422     /**
5423      * Extracts a Node Type Name prefix from the given Node Type Name.
5424      *
5425      * @param fullName Node Type Name
5426      * @return Node Type Name Prefix
5427      */
5428     private String getNodeTypeNamePrefix(final String fullName) {
5429         String tempPrefix = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX;
5430         final List<String> definedNodeTypeNamespaceList = getDefinedNodeTypeNamespaceList();
5431         log.debug("************* getPrefiX fullName {} FROM {}", fullName, definedNodeTypeNamespaceList);
5432         final Optional<String> validNameSpace = validateNodeTypeNamePrefix(fullName, definedNodeTypeNamespaceList);
5433         if (validNameSpace.isPresent()) {
5434             tempPrefix = validNameSpace.get();
5435         }
5436         log.debug("************* getNodeTypeNamePrefix return fullName {} ", tempPrefix);
5437         return tempPrefix;
5438     }
5439
5440     @Override
5441     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId,
5442                                                                                                    List<String> dataParamsToReturn) {
5443         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
5444         Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, paramsToReturn);
5445         if (resourceResultEither.isRight()) {
5446             if (resourceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
5447                 log.debug("Failed to found resource with id {} ", resourceId);
5448                 Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
5449             }
5450             log.debug("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn);
5451             return Either.right(
5452                     componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceResultEither.right().value()), ""));
5453         }
5454         Resource resource = resourceResultEither.left().value();
5455         if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
5456             ListUtils.emptyIfNull(resource.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
5457         }
5458         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromResourceByParams(resource, dataParamsToReturn);
5459         return Either.left(dataTransfer);
5460     }
5461
5462     @Override
5463     public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
5464         Resource resource = (Resource) clonedComponent;
5465         if (ModelConverter.isAtomicComponent(resource.getResourceType())) {
5466             Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived = toscaOperationFacade.shouldUpgradeToLatestDerived(resource);
5467             if (shouldUpgradeToLatestDerived.isRight()) {
5468                 return Either.right(componentsUtils.convertFromStorageResponse(shouldUpgradeToLatestDerived.right().value()));
5469             }
5470             return Either.left(shouldUpgradeToLatestDerived.left().value());
5471         } else {
5472             return super.shouldUpgradeToLatestDerived(clonedComponent);
5473         }
5474     }
5475 }