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