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