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