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