Implement 'Update Service by importing Tosca Template'-story
[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, null);
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, null);
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             janusGraphDao.rollback();
3979             ResponseFormat responseFormat =
3980                 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
3981             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3982             throw e;
3983         } catch (StorageException e) {
3984             janusGraphDao.rollback();
3985             ResponseFormat responseFormat = componentsUtils
3986                 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
3987             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3988             throw e;
3989         } finally {
3990             if (!inTransaction) {
3991                 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
3992             }
3993         }
3994         return createdResource;
3995     }
3996
3997     private Resource createResourceTransaction(Resource resource, User user, boolean isNormative) {
3998         final String resourceName = resource.getName();
3999         final String modelName = resource.getModel();
4000         final ResourceTypeEnum resourceType = resource.getResourceType();
4001         final ComponentTypeEnum componentType = resource.getComponentType();
4002         final Either<Boolean, StorageOperationStatus> eitherValidation = toscaOperationFacade
4003             .validateComponentNameAndModelExists(resourceName, modelName, resourceType, componentType);
4004         if (eitherValidation.isRight()) {
4005             loggerSupportability.log(LoggerSupportabilityActions.VALIDATE_NAME, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4006                 "ERROR while validate component name {} Status is: {}", resource.getName(), eitherValidation.right().value());
4007             log.debug("Failed to validate component name {}. Status is {}. ", resource.getName(), eitherValidation.right().value());
4008             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(eitherValidation.right().value()));
4009         }
4010         if (eitherValidation.left().value()) {
4011             log.debug("resource with name: {}, already exists", resource.getName());
4012             loggerSupportability
4013                 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4014                     "resource with name: {} already exists", resource.getName());
4015             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4016                 resource.getName());
4017         }
4018         log.debug("send resource {} to dao for create", resource.getName());
4019         createArtifactsPlaceHolderData(resource, user);
4020         // enrich object
4021         if (!isNormative) {
4022             log.debug("enrich resource with creator, version and state");
4023             resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
4024             resource.setVersion(INITIAL_VERSION);
4025             resource.setHighestVersion(true);
4026             if (resource.getResourceType() != null && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4027                 resource.setAbstract(false);
4028             }
4029         }
4030         return toscaOperationFacade.createToscaComponent(resource).left().on(r -> throwComponentExceptionByResource(r, resource));
4031     }
4032
4033     private Resource throwComponentExceptionByResource(StorageOperationStatus status, Resource resource) {
4034         ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(status), resource);
4035         throw new ByResponseFormatComponentException(responseFormat);
4036     }
4037
4038     private void createArtifactsPlaceHolderData(Resource resource, User user) {
4039         // create mandatory artifacts
4040
4041         // TODO it must be removed after that artifact uniqueId creation will be
4042
4043         // moved to ArtifactOperation
4044         setInformationalArtifactsPlaceHolder(resource, user);
4045         setDeploymentArtifactsPlaceHolder(resource, user);
4046         setToscaArtifactsPlaceHolders(resource, user);
4047     }
4048
4049     @SuppressWarnings("unchecked")
4050     @Override
4051     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
4052         Resource resource = (Resource) component;
4053         Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
4054         if (artifactMap == null) {
4055             artifactMap = new HashMap<>();
4056         }
4057         Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4058             .getDeploymentResourceArtifacts();
4059         if (deploymentResourceArtifacts != null) {
4060             Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
4061             deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
4062         }
4063         resource.setDeploymentArtifacts(artifactMap);
4064     }
4065
4066     private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
4067         Map<String, Object> artifactDetails = (Map<String, Object>) v;
4068         Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
4069         if (object != null) {
4070             List<String> artifactTypes = (List<String>) object;
4071             if (!artifactTypes.contains(resource.getResourceType().name())) {
4072                 return;
4073             }
4074         } else {
4075             log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
4076         }
4077         if (artifactsBusinessLogic != null) {
4078             ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4079                 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
4080             if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
4081                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4082             }
4083         }
4084     }
4085
4086     @SuppressWarnings("unchecked")
4087     private void setInformationalArtifactsPlaceHolder(Resource resource, User user) {
4088         Map<String, ArtifactDefinition> artifactMap = resource.getArtifacts();
4089         if (artifactMap == null) {
4090             artifactMap = new HashMap<>();
4091         }
4092         String resourceUniqueId = resource.getUniqueId();
4093         List<String> exludeResourceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceCategory();
4094         List<String> exludeResourceType = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceType();
4095         Map<String, Object> informationalResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4096             .getInformationalResourceArtifacts();
4097         List<CategoryDefinition> categories = resource.getCategories();
4098         boolean isCreateArtifact = true;
4099         if (exludeResourceCategory != null) {
4100             String category = categories.get(0).getName();
4101             isCreateArtifact = exludeResourceCategory.stream().noneMatch(e -> e.equalsIgnoreCase(category));
4102         }
4103         if (isCreateArtifact && exludeResourceType != null) {
4104             String resourceType = resource.getResourceType().name();
4105             isCreateArtifact = exludeResourceType.stream().noneMatch(e -> e.equalsIgnoreCase(resourceType));
4106         }
4107         if (informationalResourceArtifacts != null && isCreateArtifact) {
4108             Set<String> keys = informationalResourceArtifacts.keySet();
4109             for (String informationalResourceArtifactName : keys) {
4110                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalResourceArtifacts.get(informationalResourceArtifactName);
4111                 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4112                     .createArtifactPlaceHolderInfo(resourceUniqueId, informationalResourceArtifactName, artifactInfoMap, user,
4113                         ArtifactGroupTypeEnum.INFORMATIONAL);
4114                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4115             }
4116         }
4117         resource.setArtifacts(artifactMap);
4118     }
4119
4120     /**
4121      * deleteResource
4122      *
4123      * @param resourceId
4124      * @param user
4125      * @return
4126      */
4127     public ResponseFormat deleteResource(String resourceId, User user) {
4128         ResponseFormat responseFormat;
4129         validateUserExists(user);
4130         Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4131         if (resourceStatus.isRight()) {
4132             log.debug("failed to get resource {}", resourceId);
4133             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), "");
4134         }
4135         Resource resource = resourceStatus.left().value();
4136         StorageOperationStatus result = StorageOperationStatus.OK;
4137         lockComponent(resourceId, resource, "Mark resource to delete");
4138         try {
4139             result = markComponentToDelete(resource);
4140             if (result == StorageOperationStatus.OK) {
4141                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4142             } else {
4143                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4144                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4145             }
4146             return responseFormat;
4147         } finally {
4148             if (!StorageOperationStatus.OK.equals(result)) {
4149                 janusGraphDao.rollback();
4150             } else {
4151                 janusGraphDao.commit();
4152             }
4153             graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
4154         }
4155     }
4156
4157     private boolean isComponentSystemDeployed(Resource resource) {
4158         return resource.getComponentMetadataDefinition().getMetadataDataDefinition().isNormative();
4159     }
4160
4161     /**
4162      * Deletes every version of the provided resource
4163      *
4164      * @param resourceId the resource identifier
4165      * @param user       the user that performs the deletion
4166      * @return
4167      * @throws ComponentException if there is any error in the deletion of the resource operation
4168      */
4169     public void deleteResourceAllVersions(String resourceId, User user) {
4170         validateUserExists(user);
4171         Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4172         if (resourceStatus.isRight()) {
4173             log.debug("Failed to get resource {}", resourceId);
4174             componentException(resourceStatus.right().value());
4175         }
4176         Resource resource = resourceStatus.left().value();
4177         if (isComponentSystemDeployed(resource)) {
4178             throw new ByActionStatusComponentException(ActionStatus.CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES, ComponentTypeEnum.RESOURCE.getValue(),
4179                 resource.getName());
4180         }
4181         if (Boolean.FALSE.equals(resource.isArchived())) {
4182             log.debug("The resource, {}, requested for delete has not been archived.", resourceId);
4183             throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, resourceId);
4184         }
4185         try {
4186             String model = resource.getModel();
4187             final Optional<Model> modelOptional = modelOperation.findModelByName(model);
4188             List<String> deletedResourceList = toscaOperationFacade.deleteComponent(resource.getInvariantUUID(), NodeTypeEnum.Resource, true);
4189             if (log.isDebugEnabled()) {
4190                 deletedResourceList.forEach(deletedR -> log.debug("Component {} was deleted.", deletedR));
4191             }
4192             if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
4193                 modelOperation.deleteModel(modelOptional.get(), true);
4194             }
4195             toscaOperationFacade.commitAndCheck(resource.getUniqueId());
4196             updateCatalog(resource, ChangeTypeEnum.DELETE);
4197         } catch (ComponentException exception) {
4198             log.debug("Failed to delete resource, {} ", resourceId);
4199             janusGraphDao.rollback();
4200             throw exception;
4201         }
4202     }
4203
4204     public ResponseFormat deleteResourceByNameAndVersion(String resourceName, String version, User user) {
4205         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4206         validateUserExists(user);
4207         Resource resource = null;
4208         StorageOperationStatus result = StorageOperationStatus.OK;
4209         boolean failed = false;
4210         try {
4211             Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade
4212                 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, version);
4213             if (resourceStatus.isRight()) {
4214                 log.debug("failed to get resource {} version {}", resourceName, version);
4215                 return componentsUtils
4216                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), resourceName);
4217             }
4218             resource = resourceStatus.left().value();
4219         } finally {
4220             janusGraphDao.commit();
4221         }
4222         if (resource != null) {
4223             lockComponent(resource.getUniqueId(), resource, DELETE_RESOURCE);
4224             try {
4225                 result = markComponentToDelete(resource);
4226                 if (result != StorageOperationStatus.OK) {
4227                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4228                     responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4229                     return responseFormat;
4230                 }
4231             } catch (ComponentException e) {
4232                 failed = true;
4233                 throw e;
4234             } finally {
4235                 if (failed || !StorageOperationStatus.OK.equals(result)) {
4236                     janusGraphDao.rollback();
4237                 } else {
4238                     janusGraphDao.commit();
4239                 }
4240                 graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource);
4241             }
4242         }
4243         return responseFormat;
4244     }
4245
4246     public Either<Resource, ResponseFormat> getResource(String resourceId, User user) {
4247         if (user != null) {
4248             validateUserExists(user);
4249         }
4250         Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceId);
4251         if (storageStatus.isRight()) {
4252             log.debug("failed to get resource by id {}", resourceId);
4253             return Either.right(
4254                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), resourceId));
4255         }
4256         if (storageStatus.left().value() == null) {
4257             return Either.right(componentsUtils
4258                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), resourceId));
4259         }
4260         return Either.left(storageStatus.left().value());
4261     }
4262
4263     public Either<Resource, ResponseFormat> getResourceByNameAndVersion(String resourceName, String resourceVersion, String userId) {
4264         validateUserExists(userId);
4265         Either<Resource, StorageOperationStatus> getResource = toscaOperationFacade
4266             .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion);
4267         if (getResource.isRight()) {
4268             log.debug("failed to get resource by name {} and version {}", resourceName, resourceVersion);
4269             return Either.right(
4270                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResource.right().value()), resourceName));
4271         }
4272         return Either.left(getResource.left().value());
4273     }
4274
4275     /**
4276      * updateResourceMetadata
4277      *
4278      * @param user               - modifier data (userId)
4279      * @param inTransaction      TODO
4280      * @param resourceIdToUpdate - the resource identifier
4281      * @param newResource
4282      * @return Either<Resource, responseFormat>
4283      */
4284     public Resource updateResourceMetadata(String resourceIdToUpdate, Resource newResource, Resource currentResource, User user,
4285                                            boolean inTransaction) {
4286         validateUserExists(user.getUserId());
4287         log.debug("Get resource with id {}", resourceIdToUpdate);
4288         boolean needToUnlock = false;
4289         try {
4290             if (currentResource == null) {
4291                 Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceIdToUpdate);
4292                 if (storageStatus.isRight()) {
4293                     throw new ByResponseFormatComponentException(
4294                         componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), ""));
4295                 }
4296                 currentResource = storageStatus.left().value();
4297             }
4298             // verify that resource is checked-out and the user is the last
4299
4300             // updater
4301             if (!ComponentValidationUtils.canWorkOnResource(currentResource, user.getUserId())) {
4302                 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
4303             }
4304             // lock resource
4305             StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4306             if (lockResult != StorageOperationStatus.OK) {
4307                 BeEcompErrorManager.getInstance()
4308                     .logBeFailedLockObjectError("Upload Artifact - lock ", NodeTypeEnum.Resource.getName(), resourceIdToUpdate);
4309                 log.debug("Failed to lock resource: {}, error - {}", resourceIdToUpdate, lockResult);
4310                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult));
4311                 throw new ByResponseFormatComponentException(responseFormat);
4312             }
4313             needToUnlock = true;
4314             // critical section starts here
4315
4316             // convert json to object
4317
4318             // Update and updated resource must have a non-empty "derivedFrom"
4319
4320             // list
4321
4322             // This code is not called from import resources, because of root
4323
4324             // VF "derivedFrom" should be null (or ignored)
4325             if (ModelConverter.isAtomicComponent(currentResource)) {
4326                 validateDerivedFromNotEmpty(null, newResource, null);
4327                 validateDerivedFromNotEmpty(null, currentResource, null);
4328             } else {
4329                 newResource.setDerivedFrom(null);
4330             }
4331             Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource,
4332                 true);
4333             if (dataModelResponse.isRight()) {
4334                 log.debug("failed to update resource metadata!!!");
4335                 throw new ByResponseFormatComponentException(dataModelResponse.right().value());
4336             }
4337             log.debug("Resource metadata updated successfully!!!");
4338             return dataModelResponse.left().value();
4339         } catch (ComponentException | StorageException e) {
4340             rollback(inTransaction, newResource, null, null);
4341             throw e;
4342         } finally {
4343             if (!inTransaction) {
4344                 janusGraphDao.commit();
4345             }
4346             if (needToUnlock) {
4347                 graphLockOperation.unlockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4348             }
4349         }
4350     }
4351
4352     private Either<Resource, ResponseFormat> updateResourceMetadata(String resourceIdToUpdate, Resource newResource, User user,
4353                                                                     Resource currentResource, boolean inTransaction) {
4354         updateVfModuleGroupsNames(currentResource, newResource);
4355         validateResourceFieldsBeforeUpdate(currentResource, newResource, inTransaction, false);
4356         // Setting last updater and uniqueId
4357         newResource.setContactId(newResource.getContactId().toLowerCase());
4358         newResource.setLastUpdaterUserId(user.getUserId());
4359         newResource.setUniqueId(resourceIdToUpdate);
4360         // Cannot set highest version through UI
4361         newResource.setHighestVersion(currentResource.isHighestVersion());
4362         newResource.setCreationDate(currentResource.getCreationDate());
4363         Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom = processUpdateOfDerivedFrom(currentResource, newResource, user.getUserId(),
4364             inTransaction);
4365         if (processUpdateOfDerivedFrom.isRight()) {
4366             log.debug("Couldn't update derived from for resource {}", resourceIdToUpdate);
4367             return Either.right(processUpdateOfDerivedFrom.right().value());
4368         }
4369         log.debug("send resource {} to dao for update", newResource.getUniqueId());
4370         if (isNotEmpty(newResource.getGroups())) {
4371             for (GroupDefinition group : newResource.getGroups()) {
4372                 if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
4373                     groupBusinessLogic
4374                         .validateAndUpdateGroupMetadata(newResource.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId(), user,
4375                             newResource.getComponentType(), group, true, false);
4376                 }
4377             }
4378         }
4379         Either<Resource, StorageOperationStatus> dataModelResponse = toscaOperationFacade.updateToscaElement(newResource);
4380         if (dataModelResponse.isRight()) {
4381             ResponseFormat responseFormat = componentsUtils
4382                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), newResource);
4383             return Either.right(responseFormat);
4384         } else if (dataModelResponse.left().value() == null) {
4385             log.debug("No response from updateResource");
4386             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
4387         }
4388         return Either.left(dataModelResponse.left().value());
4389     }
4390
4391     private void updateVfModuleGroupsNames(Resource currentResource, Resource newResource) {
4392         if (currentResource.getGroups() != null && !currentResource.getName().equals(newResource.getName())) {
4393             List<GroupDefinition> updatedGroups = currentResource.getGroups().stream()
4394                 .map(group -> getUpdatedGroup(group, currentResource.getName(), newResource.getName())).collect(toList());
4395             newResource.setGroups(updatedGroups);
4396         }
4397     }
4398
4399     private GroupDefinition getUpdatedGroup(GroupDefinition currGroup, String replacePattern, String with) {
4400         GroupDefinition updatedGroup = new GroupDefinition(currGroup);
4401         if (updatedGroup.isSamePrefix(replacePattern) && updatedGroup.getType().equals(DEFAULT_GROUP_VF_MODULE)) {
4402             String prefix = updatedGroup.getName().substring(0, replacePattern.length());
4403             String newGroupName = updatedGroup.getName().replaceFirst(prefix, with);
4404             updatedGroup.setName(newGroupName);
4405         }
4406         return updatedGroup;
4407     }
4408
4409     /**
4410      * validateResourceFieldsBeforeCreate
4411      *
4412      * @param user - modifier data (userId)
4413      */
4414     private void validateResourceFieldsBeforeCreate(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4415         componentValidator.validate(user, resource, actionEnum);
4416         // validate category
4417         log.debug("validate category");
4418         validateCategory(user, resource, actionEnum, inTransaction);
4419         // validate vendor name & release & model number
4420         log.debug("validate vendor name");
4421         validateVendorName(user, resource, actionEnum);
4422         log.debug("validate vendor release");
4423         validateVendorReleaseName(user, resource, actionEnum);
4424         log.debug("validate resource vendor model number");
4425         validateResourceVendorModelNumber(user, resource, actionEnum);
4426         // validate cost
4427         log.debug("validate cost");
4428         validateCost(resource);
4429         // validate licenseType
4430         log.debug("validate licenseType");
4431         validateLicenseType(user, resource, actionEnum);
4432         // validate template (derived from)
4433         log.debug("validate derived from");
4434         if (!ModelConverter.isAtomicComponent(resource) && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4435             resource.setDerivedFrom(null);
4436         }
4437         validateDerivedFromExist(user, resource, actionEnum);
4438         // warn about non-updatable fields
4439         checkComponentFieldsForOverrideAttempt(resource);
4440         String currentCreatorFullName = resource.getCreatorFullName();
4441         if (currentCreatorFullName != null) {
4442             log.debug("Resource Creator fullname is automatically set and cannot be updated");
4443         }
4444         String currentLastUpdaterFullName = resource.getLastUpdaterFullName();
4445         if (currentLastUpdaterFullName != null) {
4446             log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4447         }
4448         Long currentLastUpdateDate = resource.getLastUpdateDate();
4449         if (currentLastUpdateDate != null) {
4450             log.debug("Resource last update date is automatically set and cannot be updated");
4451         }
4452         Boolean currentAbstract = resource.isAbstract();
4453         if (currentAbstract != null) {
4454             log.debug("Resource abstract is automatically set and cannot be updated");
4455         }
4456     }
4457
4458     /**
4459      * validateResourceFieldsBeforeUpdate
4460      *
4461      * @param currentResource - Resource object to validate
4462      * @param isNested
4463      */
4464     private void validateResourceFieldsBeforeUpdate(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4465         validateFields(currentResource, updateInfoResource, inTransaction, isNested);
4466         warnNonEditableFields(currentResource, updateInfoResource);
4467     }
4468
4469     private void warnNonEditableFields(Resource currentResource, Resource updateInfoResource) {
4470         String currentResourceVersion = currentResource.getVersion();
4471         String updatedResourceVersion = updateInfoResource.getVersion();
4472         if ((updatedResourceVersion != null) && (!updatedResourceVersion.equals(currentResourceVersion))) {
4473             log.debug("Resource version is automatically set and cannot be updated");
4474         }
4475         String currentCreatorUserId = currentResource.getCreatorUserId();
4476         String updatedCreatorUserId = updateInfoResource.getCreatorUserId();
4477         if ((updatedCreatorUserId != null) && (!updatedCreatorUserId.equals(currentCreatorUserId))) {
4478             log.debug("Resource Creator UserId is automatically set and cannot be updated");
4479         }
4480         String currentCreatorFullName = currentResource.getCreatorFullName();
4481         String updatedCreatorFullName = updateInfoResource.getCreatorFullName();
4482         if ((updatedCreatorFullName != null) && (!updatedCreatorFullName.equals(currentCreatorFullName))) {
4483             log.debug("Resource Creator fullname is automatically set and cannot be updated");
4484         }
4485         String currentLastUpdaterUserId = currentResource.getLastUpdaterUserId();
4486         String updatedLastUpdaterUserId = updateInfoResource.getLastUpdaterUserId();
4487         if ((updatedLastUpdaterUserId != null) && (!updatedLastUpdaterUserId.equals(currentLastUpdaterUserId))) {
4488             log.debug("Resource LastUpdater userId is automatically set and cannot be updated");
4489         }
4490         String currentLastUpdaterFullName = currentResource.getLastUpdaterFullName();
4491         String updatedLastUpdaterFullName = updateInfoResource.getLastUpdaterFullName();
4492         if ((updatedLastUpdaterFullName != null) && (!updatedLastUpdaterFullName.equals(currentLastUpdaterFullName))) {
4493             log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4494         }
4495         Long currentCreationDate = currentResource.getCreationDate();
4496         Long updatedCreationDate = updateInfoResource.getCreationDate();
4497         if ((updatedCreationDate != null) && (!updatedCreationDate.equals(currentCreationDate))) {
4498             log.debug("Resource Creation date is automatically set and cannot be updated");
4499         }
4500         Long currentLastUpdateDate = currentResource.getLastUpdateDate();
4501         Long updatedLastUpdateDate = updateInfoResource.getLastUpdateDate();
4502         if ((updatedLastUpdateDate != null) && (!updatedLastUpdateDate.equals(currentLastUpdateDate))) {
4503             log.debug("Resource last update date is automatically set and cannot be updated");
4504         }
4505         LifecycleStateEnum currentLifecycleState = currentResource.getLifecycleState();
4506         LifecycleStateEnum updatedLifecycleState = updateInfoResource.getLifecycleState();
4507         if ((updatedLifecycleState != null) && (!updatedLifecycleState.equals(currentLifecycleState))) {
4508             log.debug("Resource lifecycle state date is automatically set and cannot be updated");
4509         }
4510         Boolean currentAbstract = currentResource.isAbstract();
4511         Boolean updatedAbstract = updateInfoResource.isAbstract();
4512         if ((updatedAbstract != null) && (!updatedAbstract.equals(currentAbstract))) {
4513             log.debug("Resource abstract is automatically set and cannot be updated");
4514         }
4515         Boolean currentHighestVersion = currentResource.isHighestVersion();
4516         Boolean updatedHighestVersion = updateInfoResource.isHighestVersion();
4517         if ((updatedHighestVersion != null) && (!updatedHighestVersion.equals(currentHighestVersion))) {
4518             log.debug("Resource highest version is automatically set and cannot be updated");
4519         }
4520         String currentUuid = currentResource.getUUID();
4521         String updatedUuid = updateInfoResource.getUUID();
4522         if ((updatedUuid != null) && (!updatedUuid.equals(currentUuid))) {
4523             log.debug("Resource UUID is automatically set and cannot be updated");
4524         }
4525         log.debug("Resource Type  cannot be updated");
4526         String currentInvariantUuid = currentResource.getInvariantUUID();
4527         String updatedInvariantUuid = updateInfoResource.getInvariantUUID();
4528         if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
4529             log.debug("Resource invariant UUID is automatically set and cannot be updated");
4530             updateInfoResource.setInvariantUUID(currentInvariantUuid);
4531         }
4532     }
4533
4534     private void validateFields(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4535         boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentResource.getVersion());
4536         log.debug("validate resource name before update");
4537         validateResourceName(currentResource, updateInfoResource, hasBeenCertified, isNested);
4538         log.debug("validate description before update");
4539         componentDescriptionValidator.validateAndCorrectField(null, updateInfoResource, null);
4540         log.debug("validate icon before update");
4541         validateIcon(currentResource, updateInfoResource, hasBeenCertified);
4542         log.debug("validate tags before update");
4543         componentTagsValidator.validateAndCorrectField(null, updateInfoResource, null);
4544         log.debug("validate vendor name before update");
4545         validateVendorName(null, updateInfoResource, null);
4546         log.debug("validate resource vendor model number before update");
4547         validateResourceVendorModelNumber(currentResource, updateInfoResource);
4548         log.debug("validate vendor release before update");
4549         validateVendorReleaseName(null, updateInfoResource, null);
4550         log.debug("validate contact info before update");
4551         componentContactIdValidator.validateAndCorrectField(null, updateInfoResource, null);
4552         log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
4553         validateDerivedFromDuringUpdate(currentResource, updateInfoResource, hasBeenCertified);
4554         log.debug("validate category before update");
4555         validateCategory(currentResource, updateInfoResource, hasBeenCertified, inTransaction);
4556     }
4557
4558     private boolean isResourceNameEquals(Resource currentResource, Resource updateInfoResource) {
4559         String resourceNameUpdated = updateInfoResource.getName();
4560         String resourceNameCurrent = currentResource.getName();
4561         if (resourceNameCurrent.equals(resourceNameUpdated)) {
4562             return true;
4563         }
4564         // In case of CVFC type we should support the case of old VF with CVFC
4565
4566         // instances that were created without the "Cvfc" suffix
4567         return currentResource.getResourceType() == ResourceTypeEnum.CVFC && resourceNameUpdated
4568             .equals(addCvfcSuffixToResourceName(resourceNameCurrent));
4569     }
4570
4571     private String addCvfcSuffixToResourceName(String resourceName) {
4572         return resourceName + "Cvfc";
4573     }
4574
4575     private void validateResourceName(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified, boolean isNested) {
4576         String resourceNameUpdated = updateInfoResource.getName();
4577         if (!isResourceNameEquals(currentResource, updateInfoResource)) {
4578             if (isNested || !hasBeenCertified) {
4579                 componentNameValidator.validateAndCorrectField(null, updateInfoResource, null);
4580                 validateResourceNameUniqueness(updateInfoResource);
4581                 currentResource.setName(resourceNameUpdated);
4582                 currentResource.setNormalizedName(ValidationUtils.normaliseComponentName(resourceNameUpdated));
4583                 currentResource.setSystemName(ValidationUtils.convertToSystemName(resourceNameUpdated));
4584             } else {
4585                 log.info("Resource name: {}, cannot be updated once the resource has been certified once.", resourceNameUpdated);
4586                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NAME_CANNOT_BE_CHANGED);
4587             }
4588         }
4589     }
4590
4591     private void validateIcon(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) {
4592         String iconUpdated = updateInfoResource.getIcon();
4593         String iconCurrent = currentResource.getIcon();
4594         if (!iconCurrent.equals(iconUpdated)) {
4595             if (!hasBeenCertified) {
4596                 componentIconValidator.validateAndCorrectField(null, updateInfoResource, null);
4597             } else {
4598                 log.info("Icon {} cannot be updated once the resource has been certified once.", iconUpdated);
4599                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_ICON_CANNOT_BE_CHANGED);
4600             }
4601         }
4602     }
4603
4604     private void validateResourceVendorModelNumber(Resource currentResource, Resource updateInfoResource) {
4605         String updatedResourceVendorModelNumber = updateInfoResource.getResourceVendorModelNumber();
4606         String currentResourceVendorModelNumber = currentResource.getResourceVendorModelNumber();
4607         if (!currentResourceVendorModelNumber.equals(updatedResourceVendorModelNumber)) {
4608             validateResourceVendorModelNumber(null, updateInfoResource, null);
4609         }
4610     }
4611
4612     private Either<Boolean, ResponseFormat> validateCategory(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified,
4613                                                              boolean inTransaction) {
4614         validateCategory(null, updateInfoResource, null, inTransaction);
4615         if (hasBeenCertified) {
4616             CategoryDefinition currentCategory = currentResource.getCategories().get(0);
4617             SubCategoryDefinition currentSubCategory = currentCategory.getSubcategories().get(0);
4618             CategoryDefinition updateCategory = updateInfoResource.getCategories().get(0);
4619             SubCategoryDefinition updtaeSubCategory = updateCategory.getSubcategories().get(0);
4620             if (!currentCategory.getName().equals(updateCategory.getName()) || !currentSubCategory.getName().equals(updtaeSubCategory.getName())) {
4621                 log.info("Category {} cannot be updated once the resource has been certified once.", currentResource.getCategories());
4622                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CATEGORY_CANNOT_BE_CHANGED);
4623                 return Either.right(errorResponse);
4624             }
4625         }
4626         return Either.left(true);
4627     }
4628
4629     private Either<Boolean, ResponseFormat> validateDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4630                                                                             boolean hasBeenCertified) {
4631         List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4632         List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4633         if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4634             log.trace("Update normative types");
4635             return Either.left(true);
4636         }
4637         String derivedFromCurrent = currentDerivedFrom.get(0);
4638         String derivedFromUpdated = updatedDerivedFrom.get(0);
4639         if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4640             if (!hasBeenCertified) {
4641                 validateDerivedFromExist(null, updateInfoResource, null);
4642             } else {
4643                 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4644                     null);
4645                 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4646                     log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4647                     return validateDerivedFromExtending;
4648                 }
4649             }
4650         } else {
4651             // For derived from, we must know whether it was actually changed,
4652
4653             // otherwise we must do no action.
4654
4655             // Due to changes it inflicts on data model (remove artifacts,
4656
4657             // properties...), it's not like a flat field which can be
4658
4659             // overwritten if not changed.
4660
4661             // So we must indicate that derived from is not changed
4662             updateInfoResource.setDerivedFrom(null);
4663         }
4664         return Either.left(true);
4665     }
4666
4667     private Either<Boolean, ResponseFormat> validateNestedDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4668                                                                                   boolean hasBeenCertified) {
4669         List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4670         List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4671         if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4672             log.trace("Update normative types");
4673             return Either.left(true);
4674         }
4675         String derivedFromCurrent = currentDerivedFrom.get(0);
4676         String derivedFromUpdated = updatedDerivedFrom.get(0);
4677         if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4678             if (!hasBeenCertified) {
4679                 validateDerivedFromExist(null, updateInfoResource, null);
4680             } else {
4681                 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4682                     null);
4683                 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4684                     log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4685                     return validateDerivedFromExtending;
4686                 }
4687             }
4688         }
4689         return Either.left(true);
4690     }
4691
4692     private void validateDerivedFromExist(User user, Resource resource, AuditingActionEnum actionEnum) {
4693         if (resource.getDerivedFrom() == null || resource.getDerivedFrom().isEmpty()) {
4694             return;
4695         }
4696         String templateName = resource.getDerivedFrom().get(0);
4697         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateToscaResourceNameExists(templateName);
4698         if (dataModelResponse.isRight()) {
4699             StorageOperationStatus storageStatus = dataModelResponse.right().value();
4700             BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateDerivedFromExist");
4701             log.debug("request to data model failed with error: {}", storageStatus);
4702             ResponseFormat responseFormat = componentsUtils
4703                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), resource);
4704             log.trace("audit before sending response");
4705             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4706             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageStatus));
4707         } else if (!dataModelResponse.left().value()) {
4708             log.info("resource template with name: {}, does not exists", templateName);
4709             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4710             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4711             throw new ByActionStatusComponentException(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4712         }
4713     }
4714
4715     // Tal G for extending inheritance US815447
4716     private Either<Boolean, ResponseFormat> validateDerivedFromExtending(User user, Resource currentResource, Resource updateInfoResource,
4717                                                                          AuditingActionEnum actionEnum) {
4718         String currentTemplateName = currentResource.getDerivedFrom().get(0);
4719         String updatedTemplateName = updateInfoResource.getDerivedFrom().get(0);
4720         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
4721             .validateToscaResourceNameExtends(currentTemplateName, updatedTemplateName, currentResource.getModel());
4722         if (dataModelResponse.isRight()) {
4723             StorageOperationStatus storageStatus = dataModelResponse.right().value();
4724             BeEcompErrorManager.getInstance().logBeDaoSystemError("Create/Update Resource - validateDerivingFromExtendingType");
4725             ResponseFormat responseFormat = componentsUtils
4726                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), currentResource);
4727             log.trace("audit before sending response");
4728             componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4729             return Either.right(responseFormat);
4730         }
4731         if (!dataModelResponse.left().value()) {
4732             log.info("resource template with name {} does not inherit as original {}", updatedTemplateName, currentTemplateName);
4733             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_DOES_NOT_EXTEND);
4734             componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4735             return Either.right(responseFormat);
4736         }
4737         return Either.left(true);
4738     }
4739
4740     public void validateDerivedFromNotEmpty(User user, Resource resource, AuditingActionEnum actionEnum) {
4741         log.debug("validate resource derivedFrom field");
4742         if ((resource.getDerivedFrom() == null) || (resource.getDerivedFrom().isEmpty()) || (resource.getDerivedFrom().get(0)) == null || (resource
4743             .getDerivedFrom().get(0).trim().isEmpty())) {
4744             log.info("derived from (template) field is missing for the resource");
4745             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4746             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4747             throw new ByActionStatusComponentException(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4748         }
4749     }
4750
4751     private void validateResourceNameUniqueness(Resource resource) {
4752         Either<Boolean, StorageOperationStatus> resourceOperationResponse = toscaOperationFacade
4753             .validateComponentNameExists(resource.getName(), resource.getResourceType(), resource.getComponentType());
4754         if (resourceOperationResponse.isLeft() && resourceOperationResponse.left().value()) {
4755             log.debug("resource with name: {}, already exists", resource.getName());
4756             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4757                 resource.getName());
4758         } else if (resourceOperationResponse.isRight()) {
4759             log.debug("error while validateResourceNameExists for resource: {}", resource.getName());
4760             throw new StorageException(resourceOperationResponse.right().value());
4761         }
4762     }
4763
4764     private void validateCategory(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4765         List<CategoryDefinition> categories = resource.getCategories();
4766         if (CollectionUtils.isEmpty(categories)) {
4767             log.debug(CATEGORY_IS_EMPTY);
4768             ResponseFormat responseFormat = componentsUtils
4769                 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4770             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4771             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4772         }
4773         if (categories.size() > 1) {
4774             log.debug("Must be only one category for resource");
4775             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.RESOURCE.getValue());
4776         }
4777         CategoryDefinition category = categories.get(0);
4778         List<SubCategoryDefinition> subcategories = category.getSubcategories();
4779         if (CollectionUtils.isEmpty(subcategories)) {
4780             log.debug("Missinig subcategory for resource");
4781             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY);
4782         }
4783         if (subcategories.size() > 1) {
4784             log.debug("Must be only one sub category for resource");
4785             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_TOO_MUCH_SUBCATEGORIES);
4786         }
4787         SubCategoryDefinition subcategory = subcategories.get(0);
4788         if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
4789             log.debug(CATEGORY_IS_EMPTY);
4790             ResponseFormat responseFormat = componentsUtils
4791                 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4792             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4793             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4794         }
4795         if (!ValidationUtils.validateStringNotEmpty(subcategory.getName())) {
4796             log.debug(CATEGORY_IS_EMPTY);
4797             ResponseFormat responseFormat = componentsUtils
4798                 .getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4799             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4800             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4801         }
4802         validateCategoryListed(category, subcategory, user, resource, actionEnum, inTransaction);
4803     }
4804
4805     private void validateCategoryListed(CategoryDefinition category, SubCategoryDefinition subcategory, User user, Resource resource,
4806                                         AuditingActionEnum actionEnum, boolean inTransaction) {
4807         ResponseFormat responseFormat;
4808         if (category != null && subcategory != null) {
4809             log.debug("validating resource category {} against valid categories list", category);
4810             Either<List<CategoryDefinition>, ActionStatus> categories = elementDao.getAllCategories(NodeTypeEnum.ResourceNewCategory, inTransaction);
4811             if (categories.isRight()) {
4812                 log.debug("failed to retrieve resource categories from JanusGraph");
4813                 responseFormat = componentsUtils.getResponseFormat(categories.right().value());
4814                 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4815                 throw new ByActionStatusComponentException(categories.right().value());
4816             }
4817             List<CategoryDefinition> categoryList = categories.left().value();
4818             Optional<CategoryDefinition> foundCategory = categoryList.stream().filter(cat -> cat.getName().equals(category.getName())).findFirst();
4819             if (foundCategory.isEmpty()) {
4820                 log.debug("Category {} is not part of resource category group. Resource category valid values are {}", category, categoryList);
4821                 failOnInvalidCategory(user, resource, actionEnum);
4822                 return; // explisite output even if failOnInvalidCategory throw an exception
4823             }
4824             Optional<SubCategoryDefinition> foundSubcategory = foundCategory.get().getSubcategories().stream()
4825                 .filter(subcat -> subcat.getName().equals(subcategory.getName())).findFirst();
4826             if (foundSubcategory.isEmpty()) {
4827                 log.debug("SubCategory {} is not part of resource category group. Resource subcategory valid values are {}", subcategory,
4828                     foundCategory.get().getSubcategories());
4829                 failOnInvalidCategory(user, resource, actionEnum);
4830             }
4831         }
4832     }
4833
4834     private void failOnInvalidCategory(User user, Resource resource, AuditingActionEnum actionEnum) {
4835         ResponseFormat responseFormat;
4836         responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4837         componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4838         throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4839     }
4840
4841     public void validateVendorReleaseName(User user, Resource resource, AuditingActionEnum actionEnum) {
4842         String vendorRelease = resource.getVendorRelease();
4843         log.debug("validate vendor relese name");
4844         if (!ValidationUtils.validateStringNotEmpty(vendorRelease)) {
4845             log.info("vendor relese name is missing.");
4846             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_RELEASE);
4847             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4848             throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_RELEASE);
4849         }
4850         validateVendorReleaseName(vendorRelease, user, resource, actionEnum);
4851     }
4852
4853     public void validateVendorReleaseName(String vendorRelease, User user, Resource resource, AuditingActionEnum actionEnum) {
4854         if (vendorRelease != null) {
4855             if (!ValidationUtils.validateVendorReleaseLength(vendorRelease)) {
4856                 log.info("vendor release exceds limit.");
4857                 ResponseFormat errorResponse = componentsUtils
4858                     .getResponseFormat(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4859                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4860                 throw new ByActionStatusComponentException(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4861             }
4862             if (!ValidationUtils.validateVendorRelease(vendorRelease)) {
4863                 log.info("vendor release  is not valid.");
4864                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_RELEASE);
4865                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4866                 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_RELEASE, vendorRelease);
4867             }
4868         }
4869     }
4870
4871     private void validateVendorName(User user, Resource resource, AuditingActionEnum actionEnum) {
4872         String vendorName = resource.getVendorName();
4873         if (!ValidationUtils.validateStringNotEmpty(vendorName)) {
4874             log.info("vendor name is missing.");
4875             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_NAME);
4876             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4877             throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_NAME);
4878         }
4879         validateVendorName(vendorName, user, resource, actionEnum);
4880     }
4881
4882     private void validateVendorName(String vendorName, User user, Resource resource, AuditingActionEnum actionEnum) {
4883         if (vendorName != null) {
4884             if (!ValidationUtils.validateVendorNameLength(vendorName)) {
4885                 log.info("vendor name exceds limit.");
4886                 ResponseFormat errorResponse = componentsUtils
4887                     .getResponseFormat(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4888                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4889                 throw new ByActionStatusComponentException(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4890             }
4891             if (!ValidationUtils.validateVendorName(vendorName)) {
4892                 log.info("vendor name  is not valid.");
4893                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_NAME);
4894                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4895                 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_NAME, vendorName);
4896             }
4897         }
4898     }
4899
4900     private void validateResourceVendorModelNumber(User user, Resource resource, AuditingActionEnum actionEnum) {
4901         String resourceVendorModelNumber = resource.getResourceVendorModelNumber();
4902         if (StringUtils.isNotEmpty(resourceVendorModelNumber)) {
4903             if (!ValidationUtils.validateResourceVendorModelNumberLength(resourceVendorModelNumber)) {
4904                 log.info("resource vendor model number exceeds limit.");
4905                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4906                     "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4907                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4908                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4909                     "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4910             }
4911             // resource vendor model number is currently validated as vendor
4912
4913             // name
4914             if (!ValidationUtils.validateVendorName(resourceVendorModelNumber)) {
4915                 log.info("resource vendor model number  is not valid.");
4916                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4917                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4918                 throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4919             }
4920         }
4921     }
4922
4923     private void validateCost(Resource resource) {
4924         String cost = resource.getCost();
4925         if (cost != null) {
4926             if (!ValidationUtils.validateCost(cost)) {
4927                 log.debug("resource cost is invalid.");
4928                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4929             }
4930         }
4931     }
4932
4933     private void validateLicenseType(User user, Resource resource, AuditingActionEnum actionEnum) {
4934         log.debug("validate licenseType");
4935         String licenseType = resource.getLicenseType();
4936         if (licenseType != null) {
4937             List<String> licenseTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getLicenseTypes();
4938             if (!licenseTypes.contains(licenseType)) {
4939                 log.debug("License type {} isn't configured", licenseType);
4940                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
4941                 if (actionEnum != null) {
4942                     // In update case, no audit is required
4943                     componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4944                 }
4945                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4946             }
4947         }
4948     }
4949
4950     private Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom(Resource currentResource, Resource updatedResource, String userId,
4951                                                                        boolean inTransaction) {
4952         if (updatedResource.getDerivedFrom() != null) {
4953             log.debug("Starting derived from update for resource {}", updatedResource.getUniqueId());
4954             log.debug("1. Removing interface artifacts from graph");
4955             // Remove all interface artifacts of resource
4956             String resourceId = updatedResource.getUniqueId();
4957             Map<String, InterfaceDefinition> interfaces = currentResource.getInterfaces();
4958             if (interfaces != null) {
4959                 Collection<InterfaceDefinition> values = interfaces.values();
4960                 for (InterfaceDefinition interfaceDefinition : values) {
4961                     String interfaceType = interfaceTypeOperation.getShortInterfaceName(interfaceDefinition);
4962                     log.trace("Starting interface artifacts removal for interface type {}", interfaceType);
4963                     Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
4964                     if (operations != null) {
4965                         for (Entry<String, Operation> operationEntry : operations.entrySet()) {
4966                             Operation operation = operationEntry.getValue();
4967                             ArtifactDefinition implementation = operation.getImplementationArtifact();
4968                             if (implementation != null) {
4969                                 String uniqueId = implementation.getUniqueId();
4970                                 log.debug("Removing interface artifact definition {}, operation {}, interfaceType {}", uniqueId,
4971                                     operationEntry.getKey(), interfaceType);
4972                                 // only thing that transacts and locks here
4973                                 Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface = artifactsBusinessLogic
4974                                     .deleteArtifactByInterface(resourceId, userId, uniqueId, true);
4975                                 if (deleteArtifactByInterface.isRight()) {
4976                                     log.debug("Couldn't remove artifact definition with id {}", uniqueId);
4977                                     if (!inTransaction) {
4978                                         janusGraphDao.rollback();
4979                                     }
4980                                     return Either.right(deleteArtifactByInterface.right().value());
4981                                 }
4982                             } else {
4983                                 log.trace("No implementation found for operation {} - nothing to delete", operationEntry.getKey());
4984                             }
4985                         }
4986                     } else {
4987                         log.trace("No operations found for interface type {}", interfaceType);
4988                     }
4989                 }
4990             }
4991             log.debug("2. Removing properties");
4992             Either<Map<String, PropertyDefinition>, StorageOperationStatus> findPropertiesOfNode = propertyOperation
4993                 .deleteAllPropertiesAssociatedToNode(NodeTypeEnum.Resource, resourceId);
4994             if (findPropertiesOfNode.isRight() && findPropertiesOfNode.right().value() != StorageOperationStatus.OK) {
4995                 log.debug("Failed to remove all properties of resource");
4996                 if (!inTransaction) {
4997                     janusGraphDao.rollback();
4998                 }
4999                 return Either
5000                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findPropertiesOfNode.right().value())));
5001             }
5002         } else {
5003             log.debug("Derived from wasn't changed during update");
5004         }
5005         if (inTransaction) {
5006             return Either.left(true);
5007         }
5008         janusGraphDao.commit();
5009         return Either.left(true);
5010     }
5011
5012     public ICapabilityTypeOperation getCapabilityTypeOperation() {
5013         return capabilityTypeOperation;
5014     }
5015
5016     @Autowired
5017     public void setCapabilityTypeOperation(ICapabilityTypeOperation capabilityTypeOperation) {
5018         this.capabilityTypeOperation = capabilityTypeOperation;
5019     }
5020
5021     public Boolean validatePropertiesDefaultValues(Resource resource) {
5022         log.debug("validate resource properties default values");
5023         List<PropertyDefinition> properties = resource.getProperties();
5024         if (properties != null) {
5025             iterateOverProperties(properties, resource.getModel());
5026         }
5027         return true;
5028     }
5029
5030     public void iterateOverProperties(List<PropertyDefinition> properties, String model) {
5031         for (PropertyDefinition property : properties) {
5032             if (!propertyOperation.isPropertyTypeValid(property, model)) {
5033                 log.info("Invalid type for property {}", property);
5034                 throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
5035             }
5036             Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
5037             String type = property.getType();
5038             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5039                 ResponseFormat responseFormat = validateMapOrListPropertyType(property, allDataTypes);
5040                 if (responseFormat != null) {
5041                     break;
5042                 }
5043             }
5044             validateDefaultPropertyValue(property, allDataTypes, type);
5045         }
5046     }
5047
5048     private void validateDefaultPropertyValue(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes, String type) {
5049         if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes)) {
5050             log.info("Invalid default value for property {}", property);
5051             ResponseFormat responseFormat;
5052             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5053                 throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type,
5054                     property.getDefaultValue());
5055             }
5056             throw new ByActionStatusComponentException(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
5057         }
5058     }
5059
5060     private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property,
5061                                                          Map<String, DataTypeDefinition> allDataTypes) {
5062         ResponseFormat responseFormat = null;
5063         ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, allDataTypes);
5064         String innerType = propertyInnerTypeValid.getLeft();
5065         if (Boolean.FALSE.equals(propertyInnerTypeValid.getRight())) {
5066             log.info("Invalid inner type for property {}", property);
5067             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
5068         }
5069         return responseFormat;
5070     }
5071
5072     @Override
5073     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
5074         return deleteMarkedComponents(ComponentTypeEnum.RESOURCE);
5075     }
5076
5077     @Override
5078     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
5079         return componentInstanceBusinessLogic;
5080     }
5081
5082     private String getComponentTypeForResponse(Component component) {
5083         String componentTypeForResponse = "SERVICE";
5084         if (component instanceof Resource) {
5085             componentTypeForResponse = ((Resource) component).getResourceType().name();
5086         }
5087         return componentTypeForResponse;
5088     }
5089
5090     public Either<Resource, ResponseFormat> getLatestResourceFromCsarUuid(String csarUuid, User user) {
5091         // validate user
5092         if (user != null) {
5093             validateUserExists(user);
5094         }
5095         // get resource from csar uuid
5096         Either<Resource, StorageOperationStatus> either = toscaOperationFacade
5097             .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUuid, "");
5098         if (either.isRight()) {
5099             ResponseFormat resp = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUuid);
5100             return Either.right(resp);
5101         }
5102         return Either.left(either.left().value());
5103     }
5104
5105     @Override
5106     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
5107         return null;
5108     }
5109
5110     private Map<String, List<CapabilityDefinition>> getValidComponentInstanceCapabilities(String resourceId,
5111                                                                                           Map<String, List<CapabilityDefinition>> defaultCapabilities,
5112                                                                                           Map<String, List<UploadCapInfo>> uploadedCapabilities) {
5113         Map<String, List<CapabilityDefinition>> validCapabilitiesMap = new HashMap<>();
5114         uploadedCapabilities.forEach((k, v) -> addValidComponentInstanceCapabilities(k, v, resourceId, defaultCapabilities, validCapabilitiesMap));
5115         return validCapabilitiesMap;
5116     }
5117
5118     private void addValidComponentInstanceCapabilities(String key, List<UploadCapInfo> capabilities, String resourceId,
5119                                                        Map<String, List<CapabilityDefinition>> defaultCapabilities,
5120                                                        Map<String, List<CapabilityDefinition>> validCapabilitiesMap) {
5121         String capabilityType = capabilities.get(0).getType();
5122         if (defaultCapabilities.containsKey(capabilityType)) {
5123             CapabilityDefinition defaultCapability = getCapability(resourceId, defaultCapabilities, capabilityType);
5124             validateCapabilityProperties(capabilities, resourceId, defaultCapability);
5125             List<CapabilityDefinition> validCapabilityList = new ArrayList<>();
5126             validCapabilityList.add(defaultCapability);
5127             validCapabilitiesMap.put(key, validCapabilityList);
5128         } else {
5129             throw new ByActionStatusComponentException(ActionStatus.MISSING_CAPABILITY_TYPE, capabilityType);
5130         }
5131     }
5132
5133     private void validateCapabilityProperties(List<UploadCapInfo> capabilities, String resourceId, CapabilityDefinition defaultCapability) {
5134         if (CollectionUtils.isEmpty(defaultCapability.getProperties()) && isNotEmpty(capabilities.get(0).getProperties())) {
5135             log.debug("Failed to validate capability {} of component {}. Property list is empty. ", defaultCapability.getName(), resourceId);
5136             log.debug("Failed to update capability property values. Property list of fetched capability {} is empty. ", defaultCapability.getName());
5137             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, resourceId);
5138         } else if (isNotEmpty(capabilities.get(0).getProperties())) {
5139             validateUniquenessUpdateUploadedComponentInstanceCapability(defaultCapability, capabilities.get(0));
5140         }
5141     }
5142
5143     private CapabilityDefinition getCapability(String resourceId, Map<String, List<CapabilityDefinition>> defaultCapabilities,
5144                                                String capabilityType) {
5145         CapabilityDefinition defaultCapability;
5146         if (isNotEmpty(defaultCapabilities.get(capabilityType).get(0).getProperties())) {
5147             defaultCapability = defaultCapabilities.get(capabilityType).get(0);
5148         } else {
5149             Either<Component, StorageOperationStatus> getFullComponentRes = toscaOperationFacade.getToscaFullElement(resourceId);
5150             if (getFullComponentRes.isRight()) {
5151                 log.debug("Failed to get full component {}. Status is {}. ", resourceId, getFullComponentRes.right().value());
5152                 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, resourceId);
5153             }
5154             defaultCapability = getFullComponentRes.left().value().getCapabilities().get(capabilityType).get(0);
5155         }
5156         return defaultCapability;
5157     }
5158
5159     private void validateUniquenessUpdateUploadedComponentInstanceCapability(CapabilityDefinition defaultCapability,
5160                                                                              UploadCapInfo uploadedCapability) {
5161         List<ComponentInstanceProperty> validProperties = new ArrayList<>();
5162         Map<String, PropertyDefinition> defaultProperties = defaultCapability.getProperties().stream()
5163             .collect(toMap(PropertyDefinition::getName, Function.identity()));
5164         List<UploadPropInfo> uploadedProperties = uploadedCapability.getProperties();
5165         for (UploadPropInfo property : uploadedProperties) {
5166             String propertyName = property.getName().toLowerCase();
5167             String propertyType = property.getType();
5168             ComponentInstanceProperty validProperty;
5169             if (defaultProperties.containsKey(propertyName) && propertTypeEqualsTo(defaultProperties, propertyName, propertyType)) {
5170                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, propertyName);
5171             }
5172             validProperty = new ComponentInstanceProperty();
5173             validProperty.setName(propertyName);
5174             if (property.getValue() != null) {
5175                 validProperty.setValue(property.getValue().toString());
5176             }
5177             validProperty.setDescription(property.getDescription());
5178             validProperty.setPassword(property.isPassword());
5179             validProperties.add(validProperty);
5180         }
5181         defaultCapability.setProperties(validProperties);
5182     }
5183
5184     private boolean propertTypeEqualsTo(Map<String, PropertyDefinition> defaultProperties, String propertyName, String propertyType) {
5185         return propertyType != null && !defaultProperties.get(propertyName).getType().equals(propertyType);
5186     }
5187
5188     private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> organizeVfCsarArtifactsByArtifactOperation(
5189         List<NonMetaArtifactInfo> artifactPathAndNameList, List<ArtifactDefinition> existingArtifactsToHandle, Resource resource, User user) {
5190         EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
5191         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
5192         Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> nodeTypeArtifactsToHandleRes = Either
5193             .left(nodeTypeArtifactsToHandle);
5194         try {
5195             // add all found Csar artifacts to list to upload
5196             List<NonMetaArtifactInfo> artifactsToUpload = new ArrayList<>(artifactPathAndNameList);
5197             List<NonMetaArtifactInfo> artifactsToUpdate = new ArrayList<>();
5198             List<NonMetaArtifactInfo> artifactsToDelete = new ArrayList<>();
5199             for (NonMetaArtifactInfo currNewArtifact : artifactPathAndNameList) {
5200                 ArtifactDefinition foundArtifact;
5201                 if (!existingArtifactsToHandle.isEmpty()) {
5202                     foundArtifact = existingArtifactsToHandle.stream().filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName()))
5203                         .findFirst().orElse(null);
5204                     if (foundArtifact != null) {
5205                         if (foundArtifact.getArtifactType().equals(currNewArtifact.getArtifactType())) {
5206                             if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
5207                                 currNewArtifact.setArtifactUniqueId(foundArtifact.getUniqueId());
5208                                 // if current artifact already exists, but has
5209
5210                                 // different content, add him to the list to
5211
5212                                 // update
5213                                 artifactsToUpdate.add(currNewArtifact);
5214                             }
5215                             // remove found artifact from the list of existing
5216
5217                             // artifacts to handle, because it was already
5218
5219                             // handled
5220                             existingArtifactsToHandle.remove(foundArtifact);
5221                             // and remove found artifact from the list to
5222
5223                             // upload, because it should either be updated or be
5224
5225                             // ignored
5226                             artifactsToUpload.remove(currNewArtifact);
5227                         } else {
5228                             log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
5229                             ResponseFormat responseFormat = ResponseFormatManager.getInstance()
5230                                 .getResponseFormat(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, currNewArtifact.getArtifactName(),
5231                                     currNewArtifact.getArtifactType(), foundArtifact.getArtifactType());
5232                             AuditingActionEnum auditingAction = artifactsBusinessLogic
5233                                 .detectAuditingType(new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE),
5234                                     foundArtifact.getArtifactChecksum());
5235                             artifactsBusinessLogic
5236                                 .handleAuditing(auditingAction, resource, resource.getUniqueId(), user, null, null, foundArtifact.getUniqueId(),
5237                                     responseFormat, resource.getComponentType(), null);
5238                             responseWrapper.setInnerElement(responseFormat);
5239                             break;
5240                         }
5241                     }
5242                 }
5243             }
5244             if (responseWrapper.isEmpty()) {
5245                 for (ArtifactDefinition currArtifact : existingArtifactsToHandle) {
5246                     if (currArtifact.getIsFromCsar()) {
5247                         artifactsToDelete.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5248                             currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5249                     } else {
5250                         artifactsToUpdate.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5251                             currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5252                     }
5253                 }
5254             }
5255             if (responseWrapper.isEmpty()) {
5256                 if (!artifactsToUpload.isEmpty()) {
5257                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
5258                 }
5259                 if (!artifactsToUpdate.isEmpty()) {
5260                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
5261                 }
5262                 if (!artifactsToDelete.isEmpty()) {
5263                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
5264                 }
5265             }
5266             if (!responseWrapper.isEmpty()) {
5267                 nodeTypeArtifactsToHandleRes = Either.right(responseWrapper.getInnerElement());
5268             }
5269         } catch (Exception e) {
5270             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
5271             responseWrapper.setInnerElement(responseFormat);
5272             log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
5273         }
5274         return nodeTypeArtifactsToHandleRes;
5275     }
5276
5277     ImmutablePair<String, String> buildNestedToscaResourceName(final String nodeResourceType, final String vfResourceName,
5278                                                                final String nodeTypeFullName) {
5279         String actualType;
5280         String actualVfName;
5281         if (ResourceTypeEnum.CVFC.name().equals(nodeResourceType)) {
5282             actualVfName = vfResourceName + ResourceTypeEnum.CVFC.name();
5283             actualType = ResourceTypeEnum.VFC.name();
5284         } else {
5285             actualVfName = vfResourceName;
5286             actualType = nodeResourceType;
5287         }
5288         String nameWithouNamespacePrefix;
5289         try {
5290             final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
5291             log.debug("####### buildNestedToscaResourceName nodeResourceType {}, vfResourceName {}, "
5292                     + "nodeTypeFullName {}, actualType {}, vfResourceName {} ", nodeResourceType, vfResourceName, nodeTypeFullName, actualType,
5293                 vfResourceName);
5294             final StringBuilder toscaResourceName = new StringBuilder(nodeTypeNamePrefix);
5295             if (!nodeTypeFullName.contains(nodeTypeNamePrefix)) {
5296                 nameWithouNamespacePrefix = nodeTypeFullName;
5297             } else {
5298                 nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.length());
5299             }
5300             final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
5301             String actualName;
5302             if (nodeResourceType.equalsIgnoreCase(findTypes[0])) {
5303                 actualName = nameWithouNamespacePrefix.substring(nodeResourceType.length());
5304             } else {
5305                 actualName = "." + nameWithouNamespacePrefix;
5306             }
5307             if (actualName.startsWith(Constants.ABSTRACT)) {
5308                 toscaResourceName.append(nodeResourceType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName));
5309             } else {
5310                 toscaResourceName.append(actualType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName)).append('.')
5311                     .append(Constants.ABSTRACT);
5312             }
5313             final StringBuilder previousToscaResourceName = new StringBuilder(toscaResourceName);
5314             final String[] actualNames = actualName.split("\\.");
5315             if (actualNames.length < 3) {
5316                 return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5317                     previousToscaResourceName.append(actualName).toString());
5318             }
5319             return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5320                 previousToscaResourceName.append(actualName.substring(actualNames[1].length() + 1).toLowerCase()).toString());
5321         } catch (final Exception e) {
5322             log.debug("Exception occured when buildNestedToscaResourceName, error is:{}", e.getMessage(), e);
5323             throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE, vfResourceName);
5324         }
5325     }
5326
5327     /**
5328      * Extracts a Node Type Name prefix from the given Node Type Name.
5329      *
5330      * @param fullName Node Type Name
5331      * @return Node Type Name Prefix
5332      */
5333     private String getNodeTypeNamePrefix(final String fullName) {
5334         String tempPrefix = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX;
5335         final List<String> definedNodeTypeNamespaceList = getDefinedNodeTypeNamespaceList();
5336         log.debug("************* getPrefiX fullName {} FROM {}", fullName, definedNodeTypeNamespaceList);
5337         final Optional<String> validNameSpace = validateNodeTypeNamePrefix(fullName, definedNodeTypeNamespaceList);
5338         if (validNameSpace.isPresent()) {
5339             tempPrefix = validNameSpace.get();
5340         }
5341         log.debug("************* getNodeTypeNamePrefix return fullName {} ", tempPrefix);
5342         return tempPrefix;
5343     }
5344
5345     @Override
5346     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId,
5347                                                                                                    List<String> dataParamsToReturn) {
5348         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
5349         Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, paramsToReturn);
5350         if (resourceResultEither.isRight()) {
5351             if (resourceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
5352                 log.debug("Failed to found resource with id {} ", resourceId);
5353                 Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
5354             }
5355             log.debug("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn);
5356             return Either.right(
5357                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceResultEither.right().value()), ""));
5358         }
5359         Resource resource = resourceResultEither.left().value();
5360         if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
5361             ListUtils.emptyIfNull(resource.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
5362         }
5363         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromResourceByParams(resource, dataParamsToReturn);
5364         return Either.left(dataTransfer);
5365     }
5366
5367     @Override
5368     public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
5369         Resource resource = (Resource) clonedComponent;
5370         if (ModelConverter.isAtomicComponent(resource.getResourceType())) {
5371             Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived = toscaOperationFacade.shouldUpgradeToLatestDerived(resource);
5372             if (shouldUpgradeToLatestDerived.isRight()) {
5373                 return Either.right(componentsUtils.convertFromStorageResponse(shouldUpgradeToLatestDerived.right().value()));
5374             }
5375             return Either.left(shouldUpgradeToLatestDerived.left().value());
5376         } else {
5377             return super.shouldUpgradeToLatestDerived(clonedComponent);
5378         }
5379     }
5380 }