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