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