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