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