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