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