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