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