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