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