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