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