Support unknown data types in service import
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ResourceBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.components.impl;
21
22 import static java.util.stream.Collectors.toList;
23 import static java.util.stream.Collectors.toMap;
24 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
25 import static org.apache.commons.collections.MapUtils.isEmpty;
26 import static org.apache.commons.collections.MapUtils.isNotEmpty;
27 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement;
28 import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue;
29 import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN;
30 import static org.openecomp.sdc.common.api.Constants.DEFAULT_GROUP_VF_MODULE;
31
32 import com.google.common.annotations.VisibleForTesting;
33 import fj.data.Either;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.EnumMap;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.ListIterator;
43 import java.util.Map;
44 import java.util.Map.Entry;
45 import java.util.Objects;
46 import java.util.Optional;
47 import java.util.Set;
48 import java.util.function.Function;
49 import java.util.regex.Pattern;
50 import java.util.stream.Collectors;
51 import org.apache.commons.codec.binary.Base64;
52 import org.apache.commons.collections.CollectionUtils;
53 import org.apache.commons.collections.MapUtils;
54 import org.apache.commons.collections4.ListUtils;
55 import org.apache.commons.lang3.StringUtils;
56 import org.apache.commons.lang3.tuple.ImmutablePair;
57 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
58 import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic;
59 import org.openecomp.sdc.be.components.csar.CsarBusinessLogic;
60 import org.openecomp.sdc.be.components.csar.CsarInfo;
61 import org.openecomp.sdc.be.components.csar.OnboardedCsarInfo;
62 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
63 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
64 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
65 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
66 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
67 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
68 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
69 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
70 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
71 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
72 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
73 import org.openecomp.sdc.be.components.merge.TopologyComparator;
74 import org.openecomp.sdc.be.components.merge.property.PropertyDataValueMergeBusinessLogic;
75 import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic;
76 import org.openecomp.sdc.be.components.merge.utils.MergeInstanceUtils;
77 import org.openecomp.sdc.be.components.property.PropertyConstraintsUtils;
78 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
79 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
80 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
81 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
82 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
83 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
84 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
85 import org.openecomp.sdc.be.config.BeEcompErrorManager;
86 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
87 import org.openecomp.sdc.be.config.ConfigurationManager;
88 import org.openecomp.sdc.be.dao.api.ActionStatus;
89 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
90 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
91 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
92 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
93 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
94 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
95 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
96 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
97 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
98 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
99 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
100 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
101 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
102 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
103 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
104 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
105 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
106 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
107 import org.openecomp.sdc.be.impl.ComponentsUtils;
108 import org.openecomp.sdc.be.info.NodeTypeInfoToUpdateArtifacts;
109 import org.openecomp.sdc.be.model.ArtifactDefinition;
110 import org.openecomp.sdc.be.model.AttributeDefinition;
111 import org.openecomp.sdc.be.model.CapabilityDefinition;
112 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
113 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
114 import org.openecomp.sdc.be.model.Component;
115 import org.openecomp.sdc.be.model.ComponentInstance;
116 import org.openecomp.sdc.be.model.ComponentInstanceInput;
117 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
118 import org.openecomp.sdc.be.model.ComponentParametersView;
119 import org.openecomp.sdc.be.model.DataTypeDefinition;
120 import org.openecomp.sdc.be.model.GroupDefinition;
121 import org.openecomp.sdc.be.model.GroupProperty;
122 import org.openecomp.sdc.be.model.InputDefinition;
123 import org.openecomp.sdc.be.model.InterfaceDefinition;
124 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
125 import org.openecomp.sdc.be.model.LifecycleStateEnum;
126 import org.openecomp.sdc.be.model.Model;
127 import org.openecomp.sdc.be.model.NodeTypeInfo;
128 import org.openecomp.sdc.be.model.Operation;
129 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
130 import org.openecomp.sdc.be.model.PolicyDefinition;
131 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
132 import org.openecomp.sdc.be.model.PropertyDefinition;
133 import org.openecomp.sdc.be.model.RelationshipImpl;
134 import org.openecomp.sdc.be.model.RelationshipInfo;
135 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
136 import org.openecomp.sdc.be.model.RequirementDefinition;
137 import org.openecomp.sdc.be.model.Resource;
138 import org.openecomp.sdc.be.model.UploadArtifactInfo;
139 import org.openecomp.sdc.be.model.UploadCapInfo;
140 import org.openecomp.sdc.be.model.UploadComponentInstanceInfo;
141 import org.openecomp.sdc.be.model.UploadInfo;
142 import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
143 import org.openecomp.sdc.be.model.UploadPropInfo;
144 import org.openecomp.sdc.be.model.UploadReqInfo;
145 import org.openecomp.sdc.be.model.UploadResourceInfo;
146 import org.openecomp.sdc.be.model.User;
147 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
148 import org.openecomp.sdc.be.model.category.CategoryDefinition;
149 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
150 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
151 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
152 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
153 import org.openecomp.sdc.be.model.operations.StorageException;
154 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
155 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
156 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
157 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
158 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
159 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
160 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
161 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
162 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
163 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
164 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
165 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
166 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
167 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
168 import org.openecomp.sdc.be.tosca.CsarUtils;
169 import org.openecomp.sdc.be.tosca.CsarUtils.NonMetaArtifactInfo;
170 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
171 import org.openecomp.sdc.be.user.UserBusinessLogic;
172 import org.openecomp.sdc.be.utils.CommonBeUtils;
173 import org.openecomp.sdc.be.utils.TypeUtils;
174 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
175 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
176 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
177 import org.openecomp.sdc.common.api.Constants;
178 import org.openecomp.sdc.common.datastructure.Wrapper;
179 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
180 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
181 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
182 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
183 import org.openecomp.sdc.common.log.enums.StatusCode;
184 import org.openecomp.sdc.common.log.wrappers.Logger;
185 import org.openecomp.sdc.common.util.GeneralUtility;
186 import org.openecomp.sdc.common.util.ValidationUtils;
187 import org.openecomp.sdc.exception.ResponseFormat;
188 import org.springframework.beans.factory.annotation.Autowired;
189 import org.springframework.context.annotation.Lazy;
190 import org.yaml.snakeyaml.DumperOptions;
191 import org.yaml.snakeyaml.Yaml;
192
193 @org.springframework.stereotype.Component("resourceBusinessLogic")
194 public class ResourceBusinessLogic extends ComponentBusinessLogic {
195
196     private static final String DELETE_RESOURCE = "Delete Resource";
197     private static final String IN_RESOURCE = "  in resource {} ";
198     private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
199     private static final String INITIAL_VERSION = "0.1";
200     private static final Logger log = Logger.getLogger(ResourceBusinessLogic.class);
201     private static final String CERTIFICATION_ON_IMPORT = "certification on import";
202     private static final String CREATE_RESOURCE = "Create Resource";
203     private static final String VALIDATE_DERIVED_BEFORE_UPDATE = "validate derived before update";
204     private static final String CATEGORY_IS_EMPTY = "Resource category is empty";
205     private static final String CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES = "Create Resource - validateCapabilityTypesCreate";
206     private static final String COMPONENT_INSTANCE_WITH_NAME = "component instance with name ";
207     private static final String COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE = "component instance with name {}  in resource {} ";
208     private static final String VALID_CHARACTERS_ARTIFACT_NAME = "'A-Z', 'a-z', '0-9', '.', '_', '-', '@' and space";
209     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourceBusinessLogic.class.getName());
210     private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
211     private final ResourceImportManager resourceImportManager;
212     private final InputsBusinessLogic inputsBusinessLogic;
213     private final OutputsBusinessLogic outputsBusinessLogic;
214     private final CompositionBusinessLogic compositionBusinessLogic;
215     private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic;
216     private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic;
217     private final MergeInstanceUtils mergeInstanceUtils;
218     private final UiComponentDataConverter uiComponentDataConverter;
219     private final CsarBusinessLogic csarBusinessLogic;
220     private final PropertyBusinessLogic propertyBusinessLogic;
221     private final PolicyBusinessLogic policyBusinessLogic;
222     private final ModelBusinessLogic modelBusinessLogic;
223     private final DataTypeBusinessLogic dataTypeBusinessLogic;
224     private final PolicyTypeBusinessLogic policyTypeBusinessLogic;
225     private final ModelOperation modelOperation;
226     private IInterfaceLifecycleOperation interfaceTypeOperation;
227     private LifecycleBusinessLogic lifecycleBusinessLogic;
228     @Autowired
229     private ICapabilityTypeOperation capabilityTypeOperation;
230     @Autowired
231     private TopologyComparator topologyComparator;
232     @Autowired
233     private ComponentValidator componentValidator;
234     @Autowired
235     private PropertyDataValueMergeBusinessLogic propertyDataValueMergeBusinessLogic;
236     @Autowired
237     private SoftwareInformationBusinessLogic softwareInformationBusinessLogic;
238
239
240     @Autowired
241     public ResourceBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
242                                  final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
243                                  final GroupBusinessLogic groupBusinessLogic, final InterfaceOperation interfaceOperation,
244                                  final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
245                                  final ArtifactsBusinessLogic artifactsBusinessLogic,
246                                  final ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
247                                  final @Lazy ResourceImportManager resourceImportManager, final InputsBusinessLogic inputsBusinessLogic,
248                                  final OutputsBusinessLogic outputsBusinessLogic, final CompositionBusinessLogic compositionBusinessLogic,
249                                  final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic,
250                                  final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic,
251                                  final MergeInstanceUtils mergeInstanceUtils, final UiComponentDataConverter uiComponentDataConverter,
252                                  final CsarBusinessLogic csarBusinessLogic, final ArtifactsOperations artifactToscaOperation,
253                                  final PropertyBusinessLogic propertyBusinessLogic, final ComponentContactIdValidator componentContactIdValidator,
254                                  final ComponentNameValidator componentNameValidator, final ComponentTagsValidator componentTagsValidator,
255                                  final ComponentValidator componentValidator, final ComponentIconValidator componentIconValidator,
256                                  final ComponentProjectCodeValidator componentProjectCodeValidator,
257                                  final ComponentDescriptionValidator componentDescriptionValidator, final PolicyBusinessLogic policyBusinessLogic,
258                                  final ModelBusinessLogic modelBusinessLogic,
259                                  final DataTypeBusinessLogic dataTypeBusinessLogic, final PolicyTypeBusinessLogic policyTypeBusinessLogic,
260                                  final ModelOperation modelOperation) {
261         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
262             interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
263             componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
264         this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
265         this.resourceImportManager = resourceImportManager;
266         this.inputsBusinessLogic = inputsBusinessLogic;
267         this.outputsBusinessLogic = outputsBusinessLogic;
268         this.compositionBusinessLogic = compositionBusinessLogic;
269         this.resourceDataMergeBusinessLogic = resourceDataMergeBusinessLogic;
270         this.csarArtifactsAndGroupsBusinessLogic = csarArtifactsAndGroupsBusinessLogic;
271         this.mergeInstanceUtils = mergeInstanceUtils;
272         this.uiComponentDataConverter = uiComponentDataConverter;
273         this.csarBusinessLogic = csarBusinessLogic;
274         this.propertyBusinessLogic = propertyBusinessLogic;
275         this.policyBusinessLogic = policyBusinessLogic;
276         this.modelBusinessLogic = modelBusinessLogic;
277         this.dataTypeBusinessLogic = dataTypeBusinessLogic;
278         this.policyTypeBusinessLogic = policyTypeBusinessLogic;
279         this.modelOperation = modelOperation;
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         OnboardedCsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID);
1046
1047         Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
1048         final String model = resource.getModel();
1049         if (StringUtils.isNotEmpty(model)) {
1050             final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(model, csarInfo.getDataTypes());
1051             final Map<String, Object> policyTypesToCreate = getPolicytypesToCreate(model, csarInfo.getPolicyTypes());
1052             if (MapUtils.isNotEmpty(dataTypesToCreate) || MapUtils.isNotEmpty(policyTypesToCreate)) {
1053                 createModel(resource, csarInfo.getVfResourceName());
1054             }
1055             if (MapUtils.isNotEmpty(dataTypesToCreate)) {
1056                 dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), model, true);
1057             }
1058             if (MapUtils.isNotEmpty(policyTypesToCreate)) {
1059                 policyTypeBusinessLogic.createPolicyTypeFromYaml(new Yaml().dump(policyTypesToCreate), model, true);
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.createPolicies(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, resource);
1931
1932             if (addPropertyEither.isRight()) {
1933                 final String error = String.format("failed to add properties from yaml: %s", 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             for (Entry<String, GroupDefinition> entry : groups.entrySet()) {
1948                 String groupName = entry.getKey();
1949                 GroupDefinition groupDefinition = entry.getValue();
1950                 GroupDefinition updatedGroupDefinition = new GroupDefinition(groupDefinition);
1951
1952                 updatedGroupDefinition.setMembers(null);
1953                 Map<String, String> members = groupDefinition.getMembers();
1954                 if (members != null) {
1955                     updateGroupMembers(groups, updatedGroupDefinition, component, componentInstances, groupName, members);
1956                 }
1957                 result.add(updatedGroupDefinition);
1958             }
1959         }
1960         return result;
1961     }
1962
1963     private void updateGroupMembers(Map<String, GroupDefinition> groups, GroupDefinition updatedGroupDefinition, Resource component,
1964                                     List<ComponentInstance> componentInstances, String groupName, Map<String, String> members) {
1965         Set<String> compInstancesNames = members.keySet();
1966         if (CollectionUtils.isEmpty(componentInstances)) {
1967             String membersAstString = String.join(",", compInstancesNames);
1968             log.debug("The members: {}, in group: {}, cannot be found in component {}. There are no component instances.", membersAstString,
1969                 groupName, component.getNormalizedName());
1970             throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1971                 component.getNormalizedName(), getComponentTypeForResponse(component));
1972         }
1973         // Find all component instances with the member names
1974         Map<String, String> memberNames = componentInstances.stream().collect(toMap(ComponentInstance::getName, ComponentInstance::getUniqueId));
1975         memberNames.putAll(groups.keySet().stream().collect(toMap(g -> g, g -> "")));
1976         Map<String, String> relevantInstances = memberNames.entrySet().stream().filter(n -> compInstancesNames.contains(n.getKey()))
1977             .collect(toMap(Entry::getKey, Entry::getValue));
1978         if (relevantInstances.size() != compInstancesNames.size()) {
1979             List<String> foundMembers = new ArrayList<>(relevantInstances.keySet());
1980             foundMembers.forEach(compInstancesNames::remove);
1981             String membersAstString = String.join(",", compInstancesNames);
1982             log.debug("The members: {}, in group: {}, cannot be found in component: {}", membersAstString, groupName, component.getNormalizedName());
1983             throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1984                 component.getNormalizedName(), getComponentTypeForResponse(component));
1985         }
1986         updatedGroupDefinition.setMembers(relevantInstances);
1987     }
1988
1989     private Resource createRIAndRelationsFromYaml(String yamlName, Resource resource,
1990                                                   Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap,
1991                                                   String topologyTemplateYaml, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1992                                                   Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1993                                                   Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1994                                                   String nodeName, final String substitutableAsNodeType) {
1995         log.debug("************* Going to create all nodes {}", yamlName);
1996         handleNodeTypes(yamlName, resource, topologyTemplateYaml, false, nodeTypesArtifactsToCreate, nodeTypesNewCreatedArtifacts, nodeTypesInfo,
1997             csarInfo, nodeName, substitutableAsNodeType);
1998         log.debug("************* Finished to create all nodes {}", yamlName);
1999         log.debug("************* Going to create all resource instances {}", yamlName);
2000         Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
2001         resource = createResourceInstances(yamlName, resource, null, uploadComponentInstanceInfoMap, csarInfo.getCreatedNodes(),
2002             existingNodeTypesByResourceNames);
2003         log.debug("************* Finished to create all resource instances {}", yamlName);
2004         log.debug("************* Going to create all relations {}", yamlName);
2005         resource = createResourceInstancesRelations(csarInfo.getModifier(), yamlName, resource, null, uploadComponentInstanceInfoMap,
2006             existingNodeTypesByResourceNames);
2007         log.debug("************* Finished to create all relations {}", yamlName);
2008         log.debug("************* Going to create positions {}", yamlName);
2009         compositionBusinessLogic.setPositionsForComponentInstances(resource, csarInfo.getModifier().getUserId());
2010         log.debug("************* Finished to set positions {}", yamlName);
2011         return resource;
2012     }
2013
2014     private void handleAndAddExtractedVfcsArtifacts(List<ArtifactDefinition> vfcArtifacts, List<ArtifactDefinition> artifactsToAdd) {
2015         List<String> vfcArtifactNames = vfcArtifacts.stream().map(ArtifactDataDefinition::getArtifactName).collect(toList());
2016         artifactsToAdd.forEach(a -> {
2017             if (!vfcArtifactNames.contains(a.getArtifactName())) {
2018                 vfcArtifacts.add(a);
2019             } else {
2020                 log.debug("Can't upload two artifact with the same name {}. ", a.getArtifactName());
2021             }
2022         });
2023     }
2024
2025     @SuppressWarnings("unchecked")
2026     private void handleNodeTypes(String yamlName, Resource resource, String topologyTemplateYaml, boolean needLock,
2027                                  Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
2028                                  List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
2029                                  String nodeName, String substitutableAsNodeType) {
2030         try {
2031             for (Entry<String, NodeTypeInfo> nodeTypeEntry : nodeTypesInfo.entrySet()) {
2032                 if (nodeTypeEntry.getValue().isNested() && !nodeTypeAlreadyExists(nodeTypeEntry.getKey(), resource.getModel())) {
2033                     handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
2034                         nodeTypeEntry.getKey());
2035                     log.trace("************* finished to create node {}", nodeTypeEntry.getKey());
2036                 }
2037             }
2038             Map<String, Object> mappedToscaTemplate = null;
2039             if (StringUtils.isNotEmpty(nodeName) && isNotEmpty(nodeTypesInfo) && nodeTypesInfo.containsKey(nodeName)) {
2040                 mappedToscaTemplate = nodeTypesInfo.get(nodeName).getMappedToscaTemplate();
2041             }
2042             if (isEmpty(mappedToscaTemplate)) {
2043                 mappedToscaTemplate = (Map<String, Object>) new Yaml().load(topologyTemplateYaml);
2044             }
2045             createResourcesFromYamlNodeTypesList(yamlName, resource, mappedToscaTemplate, needLock, nodeTypesArtifactsToHandle,
2046                 nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, substitutableAsNodeType);
2047         } catch (ComponentException e) {
2048             ResponseFormat responseFormat =
2049                 e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2050             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2051             throw e;
2052         } catch (StorageException e) {
2053             ResponseFormat responseFormat = componentsUtils
2054                 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
2055             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2056             throw e;
2057         }
2058     }
2059
2060     private boolean nodeTypeAlreadyExists(final String toscaResourceName, String modelName) {
2061         return toscaOperationFacade.getLatestByToscaResourceName(toscaResourceName, modelName).isLeft();
2062     }
2063
2064     private Either<Resource, ResponseFormat> handleVfCsarArtifacts(Resource resource, CsarInfo csarInfo, List<ArtifactDefinition> createdArtifacts,
2065                                                                    ArtifactOperationInfo artifactOperation, boolean shouldLock,
2066                                                                    boolean inTransaction) {
2067         if (csarInfo.getCsar() != null) {
2068             String vendorLicenseModelId = null;
2069             String vfLicenseModelId = null;
2070             if (artifactOperation.isUpdate()) {
2071                 Map<String, ArtifactDefinition> deploymentArtifactsMap = resource.getDeploymentArtifacts();
2072                 if (deploymentArtifactsMap != null && !deploymentArtifactsMap.isEmpty()) {
2073                     for (Entry<String, ArtifactDefinition> artifactEntry : deploymentArtifactsMap.entrySet()) {
2074                         if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VENDOR_LICENSE_MODEL)) {
2075                             vendorLicenseModelId = artifactEntry.getValue().getUniqueId();
2076                         }
2077                         if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VF_LICENSE_MODEL)) {
2078                             vfLicenseModelId = artifactEntry.getValue().getUniqueId();
2079                         }
2080                     }
2081                 }
2082             }
2083             // Specific Behavior for license artifacts
2084             createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VENDOR_LICENSE_MODEL,
2085                 Constants.VENDOR_LICENSE_MODEL, ArtifactTypeEnum.VENDOR_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT,
2086                 Constants.VENDOR_LICENSE_LABEL, Constants.VENDOR_LICENSE_DISPLAY_NAME, Constants.VENDOR_LICENSE_DESCRIPTION, vendorLicenseModelId,
2087                 artifactOperation, null, true, shouldLock, inTransaction);
2088             createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VF_LICENSE_MODEL, Constants.VF_LICENSE_MODEL,
2089                 ArtifactTypeEnum.VF_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT, Constants.VF_LICENSE_LABEL,
2090                 Constants.VF_LICENSE_DISPLAY_NAME, Constants.VF_LICENSE_DESCRIPTION, vfLicenseModelId, artifactOperation, null, true, shouldLock,
2091                 inTransaction);
2092             Either<Resource, ResponseFormat> eitherCreateResult = createOrUpdateNonMetaArtifacts(csarInfo, resource, createdArtifacts, shouldLock,
2093                 inTransaction, artifactOperation);
2094             if (eitherCreateResult.isRight()) {
2095                 return Either.right(eitherCreateResult.right().value());
2096             }
2097             Either<ImmutablePair<String, String>, ResponseFormat> artifacsMetaCsarStatus = CsarValidationUtils
2098                 .getArtifactsMeta(csarInfo.getCsar(), csarInfo.getCsarUUID(), componentsUtils);
2099             if (artifacsMetaCsarStatus.isLeft()) {
2100                 String artifactsFileName = artifacsMetaCsarStatus.left().value().getKey();
2101                 String artifactsContents = artifacsMetaCsarStatus.left().value().getValue();
2102                 Either<Resource, ResponseFormat> createArtifactsFromCsar;
2103                 if (artifactOperation.isCreateOrLink()) {
2104                     createArtifactsFromCsar = csarArtifactsAndGroupsBusinessLogic
2105                         .createResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts);
2106                 } else {
2107                     Either<Component, ResponseFormat> result = csarArtifactsAndGroupsBusinessLogic
2108                         .updateResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts, shouldLock,
2109                             inTransaction);
2110                     if ((result.left().value() instanceof Resource) && result.isLeft()) {
2111                         Resource service1 = (Resource) result.left().value();
2112                         createArtifactsFromCsar = Either.left(service1);
2113                     } else {
2114                         createArtifactsFromCsar = Either.right(result.right().value());
2115                     }
2116                 }
2117                 if (createArtifactsFromCsar.isRight()) {
2118                     log.debug("Couldn't create artifacts from artifacts.meta");
2119                     return Either.right(createArtifactsFromCsar.right().value());
2120                 }
2121                 return Either.left(createArtifactsFromCsar.left().value());
2122             }
2123         }
2124         return Either.left(resource);
2125     }
2126
2127     private Either<Boolean, ResponseFormat> createOrUpdateSingleNonMetaArtifact(Resource resource, CsarInfo csarInfo, String artifactPath,
2128                                                                                 String artifactFileName, String artifactType,
2129                                                                                 ArtifactGroupTypeEnum artifactGroupType, String artifactLabel,
2130                                                                                 String artifactDisplayName, String artifactDescription,
2131                                                                                 String artifactId, ArtifactOperationInfo operation,
2132                                                                                 List<ArtifactDefinition> createdArtifacts, boolean isFromCsar,
2133                                                                                 boolean shouldLock, boolean inTransaction) {
2134         byte[] artifactFileBytes = null;
2135         if (csarInfo.getCsar().containsKey(artifactPath)) {
2136             artifactFileBytes = csarInfo.getCsar().get(artifactPath);
2137         }
2138         Either<Boolean, ResponseFormat> result = Either.left(true);
2139         if (operation.isUpdate() || operation.isDelete()) {
2140             if (isArtifactDeletionRequired(artifactId, artifactFileBytes, isFromCsar)) {
2141                 Either<ArtifactDefinition, ResponseFormat> handleDelete = artifactsBusinessLogic
2142                     .handleDelete(resource.getUniqueId(), artifactId, csarInfo.getModifier(), resource, shouldLock, inTransaction);
2143                 if (handleDelete.isRight()) {
2144                     result = Either.right(handleDelete.right().value());
2145                 } else {
2146                     ArtifactDefinition value = handleDelete.left().value();
2147                     String updatedArtifactId = value.getUniqueId();
2148                     if (artifactGroupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
2149                         resource.getDeploymentArtifacts().remove(updatedArtifactId);
2150                     } else {
2151                         resource.getArtifacts().remove(updatedArtifactId);
2152                     }
2153                 }
2154                 return result;
2155             }
2156             if (StringUtils.isEmpty(artifactId) && artifactFileBytes != null) {
2157                 operation = new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE);
2158             }
2159         }
2160         if (artifactFileBytes != null) {
2161             Map<String, Object> vendorLicenseModelJson = ArtifactUtils
2162                 .buildJsonForUpdateArtifact(artifactId, artifactFileName, artifactType, artifactGroupType, artifactLabel, artifactDisplayName,
2163                     artifactDescription, artifactFileBytes, null, isFromCsar);
2164             Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts = csarArtifactsAndGroupsBusinessLogic
2165                 .createOrUpdateCsarArtifactFromJson(resource, csarInfo.getModifier(), vendorLicenseModelJson, operation);
2166             addNonMetaCreatedArtifactsToSupportRollback(operation, createdArtifacts, eitherNonMetaArtifacts);
2167             if (eitherNonMetaArtifacts.isRight()) {
2168                 BeEcompErrorManager.getInstance().logInternalFlowError("UploadLicenseArtifact",
2169                     "Failed to upload license artifact: " + artifactFileName + "With csar uuid: " + csarInfo.getCsarUUID(), ErrorSeverity.WARNING);
2170                 return Either.right(eitherNonMetaArtifacts.right().value());
2171             }
2172             ArtifactDefinition artifactDefinition = eitherNonMetaArtifacts.left().value().left().value();
2173             createOrUpdateResourceWithUpdatedArtifact(artifactDefinition, resource, artifactGroupType);
2174         }
2175         return result;
2176     }
2177
2178     private void createOrUpdateResourceWithUpdatedArtifact(ArtifactDefinition artifact, Resource resource, ArtifactGroupTypeEnum groupTypeEnum) {
2179         if (groupTypeEnum == ArtifactGroupTypeEnum.DEPLOYMENT) {
2180             resource.getDeploymentArtifacts().put(artifact.getArtifactLabel(), artifact);
2181         } else {
2182             resource.getArtifacts().put(artifact.getArtifactLabel(), artifact);
2183         }
2184     }
2185
2186     private boolean isArtifactDeletionRequired(String artifactId, byte[] artifactFileBytes, boolean isFromCsar) {
2187         return !StringUtils.isEmpty(artifactId) && artifactFileBytes == null && isFromCsar;
2188     }
2189
2190     private void addNonMetaCreatedArtifactsToSupportRollback(ArtifactOperationInfo operation, List<ArtifactDefinition> createdArtifacts,
2191                                                              Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts) {
2192         if (operation.isCreateOrLink() && createdArtifacts != null && eitherNonMetaArtifacts.isLeft()) {
2193             Either<ArtifactDefinition, Operation> eitherResult = eitherNonMetaArtifacts.left().value();
2194             if (eitherResult.isLeft()) {
2195                 createdArtifacts.add(eitherResult.left().value());
2196             }
2197         }
2198     }
2199
2200     private Either<Resource, ResponseFormat> createOrUpdateNonMetaArtifacts(CsarInfo csarInfo, Resource resource,
2201                                                                             List<ArtifactDefinition> createdArtifacts, boolean shouldLock,
2202                                                                             boolean inTransaction, ArtifactOperationInfo artifactOperation) {
2203         Either<Resource, ResponseFormat> resStatus = null;
2204         Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
2205         try {
2206             Either<List<NonMetaArtifactInfo>, String> artifactPathAndNameList = getValidArtifactNames(csarInfo, collectedWarningMessages);
2207             if (artifactPathAndNameList.isRight()) {
2208                 return Either.right(
2209                     getComponentsUtils().getResponseFormatByArtifactId(ActionStatus.ARTIFACT_NAME_INVALID, artifactPathAndNameList.right().value(),
2210                         VALID_CHARACTERS_ARTIFACT_NAME));
2211             }
2212             EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle = null;
2213             if (artifactOperation.isCreateOrLink()) {
2214                 vfCsarArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
2215                 vfCsarArtifactsToHandle.put(artifactOperation.getArtifactOperationEnum(), artifactPathAndNameList.left().value());
2216             } else {
2217                 Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandleRes = findVfCsarArtifactsToHandle(
2218                     resource, artifactPathAndNameList.left().value(), csarInfo.getModifier());
2219                 if (findVfCsarArtifactsToHandleRes.isRight()) {
2220                     resStatus = Either.right(findVfCsarArtifactsToHandleRes.right().value());
2221                 }
2222                 if (resStatus == null) {
2223                     vfCsarArtifactsToHandle = findVfCsarArtifactsToHandleRes.left().value();
2224                 }
2225             }
2226             if (resStatus == null && vfCsarArtifactsToHandle != null) {
2227                 resStatus = processCsarArtifacts(csarInfo, resource, createdArtifacts, shouldLock, inTransaction, resStatus, vfCsarArtifactsToHandle);
2228             }
2229             if (resStatus == null) {
2230                 resStatus = Either.left(resource);
2231             }
2232         } catch (Exception e) {
2233             resStatus = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2234             log.debug("Exception occurred in createNonMetaArtifacts, message:{}", e.getMessage(), e);
2235         } finally {
2236             CsarUtils.handleWarningMessages(collectedWarningMessages);
2237         }
2238         return resStatus;
2239     }
2240
2241     private Either<Resource, ResponseFormat> processCsarArtifacts(CsarInfo csarInfo, Resource resource, List<ArtifactDefinition> createdArtifacts,
2242                                                                   boolean shouldLock, boolean inTransaction,
2243                                                                   Either<Resource, ResponseFormat> resStatus,
2244                                                                   EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle) {
2245         for (Entry<ArtifactOperationEnum, List<NonMetaArtifactInfo>> currArtifactOperationPair : vfCsarArtifactsToHandle.entrySet()) {
2246             Optional<ResponseFormat> optionalCreateInDBError =
2247                 // Stream of artifacts to be created
2248                 currArtifactOperationPair.getValue().stream()
2249                     // create each artifact
2250                     .map(e -> createOrUpdateSingleNonMetaArtifact(resource, csarInfo, e.getPath(), e.getArtifactName(), e.getArtifactType(),
2251                         e.getArtifactGroupType(), e.getArtifactLabel(), e.getDisplayName(), CsarUtils.ARTIFACT_CREATED_FROM_CSAR,
2252                         e.getArtifactUniqueId(), new ArtifactOperationInfo(false, false, currArtifactOperationPair.getKey()), createdArtifacts,
2253                         e.isFromCsar(), shouldLock, inTransaction))
2254                     // filter in only error
2255                     .filter(Either::isRight).
2256                     // Convert the error from either to
2257
2258                     // ResponseFormat
2259                         map(e -> e.right().value()).
2260                     // Check if an error occurred
2261                         findAny();
2262             // Error found on artifact Creation
2263             if (optionalCreateInDBError.isPresent()) {
2264                 resStatus = Either.right(optionalCreateInDBError.get());
2265                 break;
2266             }
2267         }
2268         return resStatus;
2269     }
2270
2271     private Either<List<NonMetaArtifactInfo>, String> getValidArtifactNames(CsarInfo csarInfo,
2272                                                                             Map<String, Set<List<String>>> collectedWarningMessages) {
2273         List<NonMetaArtifactInfo> artifactPathAndNameList =
2274             // Stream of file paths contained in csar
2275             csarInfo.getCsar().entrySet().stream()
2276                 // Filter in only VF artifact path location
2277                 .filter(e -> Pattern.compile(VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
2278                 // Validate and add warnings
2279                 .map(e -> CsarUtils.validateNonMetaArtifact(e.getKey(), e.getValue(), collectedWarningMessages))
2280                 // Filter in Non Warnings
2281                 .filter(Either::isLeft)
2282                 // Convert from Either to NonMetaArtifactInfo
2283                 .map(e -> e.left().value())
2284                 // collect to List
2285                 .collect(toList());
2286         Pattern englishNumbersAndUnderScoresOnly = Pattern.compile(CsarUtils.VALID_ENGLISH_ARTIFACT_NAME);
2287         for (NonMetaArtifactInfo nonMetaArtifactInfo : artifactPathAndNameList) {
2288             if (!englishNumbersAndUnderScoresOnly.matcher(nonMetaArtifactInfo.getDisplayName()).matches()) {
2289                 return Either.right(nonMetaArtifactInfo.getArtifactName());
2290             }
2291         }
2292         return Either.left(artifactPathAndNameList);
2293     }
2294
2295     private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandle(Resource resource,
2296                                                                                                                           List<NonMetaArtifactInfo> artifactPathAndNameList,
2297                                                                                                                           User user) {
2298         List<ArtifactDefinition> existingArtifacts = new ArrayList<>();
2299         // collect all Deployment and Informational artifacts of VF
2300         if (resource.getDeploymentArtifacts() != null && !resource.getDeploymentArtifacts().isEmpty()) {
2301             existingArtifacts.addAll(resource.getDeploymentArtifacts().values());
2302         }
2303         if (resource.getArtifacts() != null && !resource.getArtifacts().isEmpty()) {
2304             existingArtifacts.addAll(resource.getArtifacts().values());
2305         }
2306         existingArtifacts = existingArtifacts.stream()
2307             // filter MANDATORY artifacts, LICENSE artifacts and artifacts
2308
2309             // was created from HEAT.meta
2310             .filter(this::isNonMetaArtifact).collect(toList());
2311         List<String> artifactsToIgnore = new ArrayList<>();
2312         // collect IDs of Artifacts of VF which belongs to any group
2313         if (resource.getGroups() != null) {
2314             resource.getGroups().forEach(g -> {
2315                 if (g.getArtifacts() != null && !g.getArtifacts().isEmpty()) {
2316                     artifactsToIgnore.addAll(g.getArtifacts());
2317                 }
2318             });
2319         }
2320         existingArtifacts = existingArtifacts.stream()
2321             // filter artifacts which belongs to any group
2322             .filter(a -> !artifactsToIgnore.contains(a.getUniqueId())).collect(toList());
2323         return organizeVfCsarArtifactsByArtifactOperation(artifactPathAndNameList, existingArtifacts, resource, user);
2324     }
2325
2326     private boolean isNonMetaArtifact(ArtifactDefinition artifact) {
2327         return !artifact.getMandatory() && artifact.getArtifactName() != null && isValidArtifactType(artifact);
2328     }
2329
2330     private boolean isValidArtifactType(ArtifactDefinition artifact) {
2331         return artifact.getArtifactType() != null && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VENDOR_LICENSE
2332             && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VF_LICENSE;
2333     }
2334
2335     private Resource createResourceInstancesRelations(User user, String yamlName, Resource resource, Resource oldResource,
2336                                                       Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2337                                                       Map<String, Resource> existingNodeTypesByResourceNames) {
2338         log.debug("#createResourceInstancesRelations - Going to create relations ");
2339         loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2340             "Start to create relations");
2341         List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2342         if (isEmpty(uploadResInstancesMap) || CollectionUtils.isEmpty(componentInstancesList) &&
2343             resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances {
2344             log.debug("#createResourceInstancesRelations - No instances found in the resource {} is empty, yaml template file name {}, ",
2345                 resource.getUniqueId(), yamlName);
2346             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2347                 "No instances found in the resource: {}, is empty, yaml template file name: {}", resource.getName(), yamlName);
2348             BeEcompErrorManager.getInstance()
2349                 .logInternalDataError("createResourceInstancesRelations", "No instances found in a resource or nn yaml template. ",
2350                     ErrorSeverity.ERROR);
2351             throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2352         }
2353         Map<String, List<ComponentInstanceProperty>> instProperties = new HashMap<>();
2354         Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities = new HashMap<>();
2355         Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements = new HashMap<>();
2356         Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts = new HashMap<>();
2357         Map<String, Map<String, ArtifactDefinition>> instArtifacts = new HashMap<>();
2358         Map<String, List<AttributeDefinition>> instAttributes = new HashMap<>();
2359         List<RequirementCapabilityRelDef> relations = new ArrayList<>();
2360         Map<String, List<ComponentInstanceInput>> instInputs = new HashMap<>();
2361         Resource finalResource = resource;
2362         uploadResInstancesMap.values().forEach(
2363             i -> processComponentInstance(yamlName, finalResource, componentInstancesList,
2364                 componentsUtils.getAllDataTypes(applicationDataTypeCache, resource.getModel()), instProperties, instCapabilities,
2365                 instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, existingNodeTypesByResourceNames, instInputs, i));
2366         resource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar()).forEach(
2367             i -> processUiComponentInstance(oldResource, i, instCapabilities, instRequirements, instDeploymentArtifacts, instArtifacts,
2368                 instProperties, instInputs, instAttributes));
2369         associateComponentInstancePropertiesToComponent(yamlName, resource, instProperties);
2370         associateComponentInstanceInputsToComponent(yamlName, resource, instInputs);
2371         associateDeploymentArtifactsToInstances(user, yamlName, resource, instDeploymentArtifacts);
2372         associateArtifactsToInstances(yamlName, resource, instArtifacts);
2373         associateOrAddCalculatedCapReq(yamlName, resource, instCapabilities, instRequirements);
2374         associateInstAttributeToComponentToInstances(yamlName, resource, instAttributes);
2375         addRelationsToRI(yamlName, resource, uploadResInstancesMap, componentInstancesList, relations);
2376         associateResourceInstances(yamlName, resource, relations);
2377         handleSubstitutionMappings(resource, uploadResInstancesMap);
2378         log.debug("************* in create relations, getResource start");
2379         loggerSupportability
2380             .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, "create relations");
2381         Either<Resource, StorageOperationStatus> eitherGetResource = toscaOperationFacade.getToscaFullElement(resource.getUniqueId());
2382         log.debug("************* in create relations, getResource end");
2383         if (eitherGetResource.isRight()) {
2384             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2385                 "ERROR while create relations");
2386             throw new ByResponseFormatComponentException(
2387                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGetResource.right().value()), resource));
2388         }
2389         return eitherGetResource.left().value();
2390     }
2391
2392     private void processUiComponentInstance(Resource oldResource, ComponentInstance instance,
2393                                             Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2394                                             Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2395                                             Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2396                                             Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2397                                             Map<String, List<ComponentInstanceProperty>> instProperties,
2398                                             Map<String, List<ComponentInstanceInput>> instInputs,
2399                                             Map<String, List<AttributeDefinition>> instAttributes) {
2400         Optional<ComponentInstance> foundInstance = findInstance(oldResource, instance);
2401         if (foundInstance.isPresent()) {
2402             if (MapUtils.isNotEmpty(foundInstance.get().getCapabilities())) {
2403                 instCapabilities.put(instance, foundInstance.get().getCapabilities());
2404             }
2405             if (MapUtils.isNotEmpty(foundInstance.get().getRequirements())) {
2406                 instRequirements.put(instance, foundInstance.get().getRequirements());
2407             }
2408             if (MapUtils.isNotEmpty(foundInstance.get().getDeploymentArtifacts())) {
2409                 instDeploymentArtifacts.put(instance.getUniqueId(), foundInstance.get().getDeploymentArtifacts());
2410             }
2411             if (MapUtils.isNotEmpty(foundInstance.get().getArtifacts())) {
2412                 instArtifacts.put(instance.getUniqueId(), foundInstance.get().getArtifacts());
2413             }
2414             if (MapUtils.isNotEmpty(oldResource.getComponentInstancesProperties()) && CollectionUtils
2415                 .isNotEmpty(oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()))) {
2416                 instProperties.put(instance.getUniqueId(), oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()));
2417             }
2418             if (MapUtils.isNotEmpty(oldResource.getComponentInstancesInputs()) && CollectionUtils
2419                 .isNotEmpty(oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()))) {
2420                 instInputs.put(instance.getUniqueId(), oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()));
2421             }
2422             if (MapUtils.isNotEmpty(oldResource.getComponentInstancesAttributes()) && CollectionUtils
2423                 .isNotEmpty(oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()))) {
2424                 instAttributes.put(instance.getUniqueId(),
2425                     oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()).stream().map(AttributeDefinition::new)
2426                         .collect(toList()));
2427             }
2428         }
2429     }
2430
2431     private Optional<ComponentInstance> findInstance(Resource oldResource, ComponentInstance instance) {
2432         if (oldResource != null && CollectionUtils.isNotEmpty(oldResource.getComponentInstances())) {
2433             return oldResource.getComponentInstances().stream().filter(i -> i.getName().equals(instance.getName())).findFirst();
2434         }
2435         return Optional.empty();
2436     }
2437
2438     private void associateResourceInstances(String yamlName, Resource resource, List<RequirementCapabilityRelDef> relations) {
2439         Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> relationsEither = toscaOperationFacade
2440             .associateResourceInstances(resource, resource.getUniqueId(), relations);
2441         if (relationsEither.isRight() && relationsEither.right().value() != StorageOperationStatus.NOT_FOUND) {
2442             StorageOperationStatus status = relationsEither.right().value();
2443             log.debug("failed to associate instances of resource {} status is {}", resource.getUniqueId(), status);
2444             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), yamlName);
2445         } else {
2446             setResourceInstanceRelationsOnComponent(resource, relationsEither.left().value());
2447         }
2448     }
2449
2450     private void associateInstAttributeToComponentToInstances(String yamlName, Resource resource,
2451                                                               Map<String, List<AttributeDefinition>> instAttributes) {
2452         StorageOperationStatus addArtToInst;
2453         addArtToInst = toscaOperationFacade.associateInstAttributeToComponentToInstances(instAttributes, resource);
2454         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2455             log.debug("failed to associate attributes of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2456             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2457         }
2458     }
2459
2460     private void associateOrAddCalculatedCapReq(String yamlName, Resource resource,
2461                                                 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2462                                                 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements) {
2463         StorageOperationStatus addArtToInst;
2464         addArtToInst = toscaOperationFacade.associateOrAddCalculatedCapReq(instCapabilities, instRequirements, resource);
2465         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2466             log.debug("failed to associate cap and req of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2467             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2468         }
2469     }
2470
2471     private void associateArtifactsToInstances(String yamlName, Resource resource, Map<String, Map<String, ArtifactDefinition>> instArtifacts) {
2472         StorageOperationStatus addArtToInst;
2473         addArtToInst = toscaOperationFacade.associateArtifactsToInstances(instArtifacts, resource);
2474         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2475             log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2476             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2477         }
2478     }
2479
2480     private void associateDeploymentArtifactsToInstances(User user, String yamlName, Resource resource,
2481                                                          Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts) {
2482         StorageOperationStatus addArtToInst = toscaOperationFacade.associateDeploymentArtifactsToInstances(instDeploymentArtifacts, resource, user);
2483         if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2484             log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2485             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2486         }
2487     }
2488
2489     private void associateComponentInstanceInputsToComponent(String yamlName, Resource resource,
2490                                                              Map<String, List<ComponentInstanceInput>> instInputs) {
2491         if (MapUtils.isNotEmpty(instInputs)) {
2492             Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addInputToInst = toscaOperationFacade
2493                 .associateComponentInstanceInputsToComponent(instInputs, resource.getUniqueId());
2494             if (addInputToInst.isRight()) {
2495                 StorageOperationStatus addInputToInstError = addInputToInst.right().value();
2496                 log.debug("failed to associate inputs value of resource {} status is {}", resource.getUniqueId(), addInputToInstError);
2497                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addInputToInstError), yamlName);
2498             }
2499             setComponentInstanceInputsOnComponent(resource, instInputs);
2500         }
2501     }
2502
2503     private void setComponentInstanceInputsOnComponent(Resource resource, Map<String, List<ComponentInstanceInput>> instInputs) {
2504         Map<String, List<ComponentInstanceInput>> componentInstancesInputs = resource.getComponentInstancesInputs();
2505         if (componentInstancesInputs == null) {
2506             componentInstancesInputs = new HashMap<>();
2507         }
2508         componentInstancesInputs.putAll(instInputs);
2509         resource.setComponentInstancesInputs(componentInstancesInputs);
2510     }
2511
2512     private void associateComponentInstancePropertiesToComponent(String yamlName, Resource resource,
2513                                                                  Map<String, List<ComponentInstanceProperty>> instProperties) {
2514         Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addPropToInst = toscaOperationFacade
2515             .associateComponentInstancePropertiesToComponent(instProperties, resource.getUniqueId());
2516         if (addPropToInst.isRight()) {
2517             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2518                 "ERROR while  associate compnent insatnce properties of resource: {} status is: {}", resource.getName(),
2519                 addPropToInst.right().value());
2520             StorageOperationStatus storageOperationStatus = addPropToInst.right().value();
2521             log.debug("failed to associate properties of resource {} status is {}", resource.getUniqueId(), storageOperationStatus);
2522             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageOperationStatus), yamlName);
2523         }
2524         setComponentInstancePropertiesOnComponent(resource, instProperties);
2525     }
2526
2527     private void setComponentInstancePropertiesOnComponent(Resource resource, Map<String, List<ComponentInstanceProperty>> instProperties) {
2528         Map<String, List<ComponentInstanceProperty>> componentInstanceProps = resource.getComponentInstancesProperties();
2529         if (componentInstanceProps == null) {
2530             componentInstanceProps = new HashMap<>();
2531         }
2532         componentInstanceProps.putAll(instProperties);
2533         resource.setComponentInstancesProperties(componentInstanceProps);
2534     }
2535
2536     private void handleSubstitutionMappings(Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2537         Either<Resource, StorageOperationStatus> getResourceRes = null;
2538         if (resource.getResourceType() == ResourceTypeEnum.CVFC) {
2539             getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap);
2540         } else if (StringUtils.isNotEmpty(resource.getModel()) && resource.getResourceType() == ResourceTypeEnum.VF) {
2541             getResourceRes = updateCalculatedCapReqWithSubstitutionMappingsForVf(resource, uploadResInstancesMap);
2542         }
2543         if (getResourceRes != null && getResourceRes.isRight()) {
2544             ResponseFormat responseFormat = componentsUtils
2545                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource);
2546             throw new ByResponseFormatComponentException(responseFormat);
2547         }
2548
2549     }
2550
2551     private void addRelationsToRI(String yamlName, Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2552                                   List<ComponentInstance> componentInstancesList, List<RequirementCapabilityRelDef> relations) {
2553         for (Entry<String, UploadComponentInstanceInfo> entry : uploadResInstancesMap.entrySet()) {
2554             UploadComponentInstanceInfo uploadComponentInstanceInfo = entry.getValue();
2555             ComponentInstance currentCompInstance = null;
2556             for (ComponentInstance compInstance : componentInstancesList) {
2557                 if (compInstance.getName().equals(uploadComponentInstanceInfo.getName())) {
2558                     currentCompInstance = compInstance;
2559                     break;
2560                 }
2561             }
2562             if (currentCompInstance == null) {
2563                 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2564                 BeEcompErrorManager.getInstance()
2565                     .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2566                         ErrorSeverity.ERROR);
2567                 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2568             }
2569             ResponseFormat addRelationToRiRes = addRelationToRI(yamlName, resource, entry.getValue(), relations);
2570             if (addRelationToRiRes.getStatus() != 200) {
2571                 throw new ByResponseFormatComponentException(addRelationToRiRes);
2572             }
2573         }
2574     }
2575
2576     private void setResourceInstanceRelationsOnComponent(Resource resource, List<RequirementCapabilityRelDef> relations) {
2577         if (resource.getComponentInstancesRelations() != null) {
2578             resource.getComponentInstancesRelations().addAll(relations);
2579         } else {
2580             resource.setComponentInstancesRelations(relations);
2581         }
2582     }
2583
2584     private void processComponentInstance(String yamlName, Resource resource, List<ComponentInstance> componentInstancesList,
2585                                           Map<String, DataTypeDefinition> allDataTypes,
2586                                           Map<String, List<ComponentInstanceProperty>> instProperties,
2587                                           Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2588                                           Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2589                                           Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2590                                           Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2591                                           Map<String, List<AttributeDefinition>> instAttributes, Map<String, Resource> originCompMap,
2592                                           Map<String, List<ComponentInstanceInput>> instInputs,
2593                                           UploadComponentInstanceInfo uploadComponentInstanceInfo) {
2594         Optional<ComponentInstance> currentCompInstanceOpt = componentInstancesList.stream()
2595             .filter(i -> i.getName().equals(uploadComponentInstanceInfo.getName())).findFirst();
2596         if (currentCompInstanceOpt.isEmpty()) {
2597             log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2598             BeEcompErrorManager.getInstance()
2599                 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2600                     ErrorSeverity.ERROR);
2601             throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2602         }
2603         ComponentInstance currentCompInstance = currentCompInstanceOpt.get();
2604         String resourceInstanceId = currentCompInstance.getUniqueId();
2605         Resource originResource = getOriginResource(originCompMap, currentCompInstance);
2606         if (isNotEmpty(originResource.getRequirements())) {
2607             instRequirements.put(currentCompInstance, originResource.getRequirements());
2608         }
2609         if (isNotEmpty(originResource.getCapabilities())) {
2610             processComponentInstanceCapabilities(allDataTypes, instCapabilties, uploadComponentInstanceInfo, currentCompInstance, originResource);
2611         }
2612         if (originResource.getDeploymentArtifacts() != null && !originResource.getDeploymentArtifacts().isEmpty()) {
2613             instDeploymentArtifacts.put(resourceInstanceId, originResource.getDeploymentArtifacts());
2614         }
2615         if (originResource.getArtifacts() != null && !originResource.getArtifacts().isEmpty()) {
2616             instArtifacts.put(resourceInstanceId, originResource.getArtifacts());
2617         }
2618         if (originResource.getAttributes() != null && !originResource.getAttributes().isEmpty()) {
2619             instAttributes.put(resourceInstanceId, originResource.getAttributes());
2620         }
2621         if (originResource.getResourceType() != ResourceTypeEnum.CVFC) {
2622             ResponseFormat addPropertiesValueToRiRes = addPropertyValuesToRi(uploadComponentInstanceInfo, resource, originResource,
2623                 currentCompInstance, instProperties, allDataTypes);
2624             if (addPropertiesValueToRiRes.getStatus() != 200) {
2625                 throw new ByResponseFormatComponentException(addPropertiesValueToRiRes);
2626             }
2627         } else {
2628             addInputsValuesToRi(uploadComponentInstanceInfo, resource, originResource, currentCompInstance, instInputs, allDataTypes);
2629         }
2630     }
2631
2632     private Resource getOriginResource(Map<String, Resource> originCompMap, ComponentInstance currentCompInstance) {
2633         Resource originResource;
2634         if (!originCompMap.containsKey(currentCompInstance.getComponentUid())) {
2635             Either<Resource, StorageOperationStatus> getOriginResourceRes = toscaOperationFacade
2636                 .getToscaFullElement(currentCompInstance.getComponentUid());
2637             if (getOriginResourceRes.isRight()) {
2638                 log.debug("failed to fetch resource with uniqueId {} and tosca component name {} status is {}", currentCompInstance.getComponentUid(),
2639                     currentCompInstance.getToscaComponentName(), getOriginResourceRes);
2640                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getOriginResourceRes.right().value()),
2641                     currentCompInstance.getComponentUid());
2642             }
2643             originResource = getOriginResourceRes.left().value();
2644             originCompMap.put(originResource.getUniqueId(), originResource);
2645         } else {
2646             originResource = originCompMap.get(currentCompInstance.getComponentUid());
2647         }
2648         return originResource;
2649     }
2650
2651     private void processComponentInstanceCapabilities(Map<String, DataTypeDefinition> allDataTypes,
2652                                                       Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2653                                                       UploadComponentInstanceInfo uploadComponentInstanceInfo, ComponentInstance currentCompInstance,
2654                                                       Resource originResource) {
2655         Map<String, List<CapabilityDefinition>> originCapabilities;
2656         if (isNotEmpty(uploadComponentInstanceInfo.getCapabilities())) {
2657             originCapabilities = new HashMap<>();
2658             Map<String, Map<String, UploadPropInfo>> newPropertiesMap = new HashMap<>();
2659             originResource.getCapabilities().forEach((k, v) -> addCapabilities(originCapabilities, k, v));
2660             uploadComponentInstanceInfo.getCapabilities().values().forEach(l -> addCapabilitiesProperties(newPropertiesMap, l));
2661             updateCapabilityPropertiesValues(originCapabilities, newPropertiesMap, allDataTypes);
2662         } else {
2663             originCapabilities = originResource.getCapabilities();
2664         }
2665         instCapabilties.put(currentCompInstance, originCapabilities);
2666     }
2667
2668     private void updateCapabilityPropertiesValues(Map<String, List<CapabilityDefinition>> originCapabilities,
2669                                                   Map<String, Map<String, UploadPropInfo>> newPropertiesMap,
2670                                                   Map<String, DataTypeDefinition> allDataTypes) {
2671         originCapabilities.values().stream().flatMap(Collection::stream).filter(c -> newPropertiesMap.containsKey(c.getName()))
2672             .forEach(c -> updatePropertyValues(c.getProperties(), newPropertiesMap.get(c.getName()), allDataTypes));
2673     }
2674
2675     private void addCapabilitiesProperties(Map<String, Map<String, UploadPropInfo>> newPropertiesMap, List<UploadCapInfo> capabilities) {
2676         for (UploadCapInfo capability : capabilities) {
2677             if (isNotEmpty(capability.getProperties())) {
2678                 newPropertiesMap.put(capability.getName(), capability.getProperties().stream().collect(toMap(UploadInfo::getName, p -> p)));
2679             }
2680         }
2681     }
2682
2683     private void addCapabilities(Map<String, List<CapabilityDefinition>> originCapabilities, String type, List<CapabilityDefinition> capabilities) {
2684         List<CapabilityDefinition> list = capabilities.stream().map(CapabilityDefinition::new).collect(toList());
2685         originCapabilities.put(type, list);
2686     }
2687
2688     private void updatePropertyValues(List<ComponentInstanceProperty> properties, Map<String, UploadPropInfo> newProperties,
2689                                       Map<String, DataTypeDefinition> allDataTypes) {
2690         properties.forEach(p -> updatePropertyValue(p, newProperties.get(p.getName()), allDataTypes));
2691     }
2692
2693     private String updatePropertyValue(ComponentInstanceProperty property, UploadPropInfo propertyInfo,
2694                                        Map<String, DataTypeDefinition> allDataTypes) {
2695         String value = null;
2696         List<GetInputValueDataDefinition> getInputs = null;
2697         boolean isValidate = true;
2698         if (null != propertyInfo && propertyInfo.getValue() != null) {
2699             getInputs = propertyInfo.getGet_input();
2700             isValidate = getInputs == null || getInputs.isEmpty();
2701             if (isValidate) {
2702                 value = getPropertyJsonStringValue(propertyInfo.getValue(), property.getType());
2703             } else {
2704                 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
2705             }
2706         }
2707         property.setValue(value);
2708         return validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
2709     }
2710
2711     private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappings(Resource resource,
2712                                                                                                     Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2713         Either<Resource, StorageOperationStatus> updateRes = null;
2714         Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2715         Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2716
2717         StorageOperationStatus status = toscaOperationFacade.deleteAllCalculatedCapabilitiesRequirements(resource.getUniqueId());
2718         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2719             log.debug("Failed to delete all calculated capabilities and requirements of resource {} upon update. Status is {}",
2720                 resource.getUniqueId(), status);
2721             updateRes = Either.right(status);
2722         }
2723         if (updateRes == null) {
2724             fillUpdatedInstCapabilitiesRequirements(resource.getComponentInstances(), uploadResInstancesMap, updatedInstCapabilities,
2725                 updatedInstRequirements);
2726             status = toscaOperationFacade.associateOrAddCalculatedCapReq(updatedInstCapabilities, updatedInstRequirements, resource);
2727             if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2728                 log.debug(
2729                     "Failed to associate capabilities and requirementss of resource {}, updated according to a substitution mapping. Status is {}",
2730                     resource.getUniqueId(), status);
2731                 updateRes = Either.right(status);
2732             }
2733         }
2734         if (updateRes == null) {
2735             updateRes = Either.left(resource);
2736         }
2737         return updateRes;
2738     }
2739
2740     private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappingsForVf(final Resource resource,
2741                                                                                                          final Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2742         Either<Resource, StorageOperationStatus> updateRes = null;
2743         final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2744         final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2745
2746         resource.getComponentInstances().forEach(i -> {
2747             setExternalCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2748             setExternalRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2749         });
2750
2751         final StorageOperationStatus status = toscaOperationFacade.updateCalculatedCapabilitiesRequirements(updatedInstCapabilities,
2752             updatedInstRequirements, resource);
2753         if (status != StorageOperationStatus.OK) {
2754             log.debug(
2755                 "Failed to update capabilities and requirements of resource {}. Status is {}",
2756                 resource.getUniqueId(), status);
2757             updateRes = Either.right(status);
2758         }
2759
2760         if (updateRes == null) {
2761             updateRes = Either.left(resource);
2762         }
2763         return updateRes;
2764     }
2765
2766     private void fillUpdatedInstCapabilitiesRequirements(List<ComponentInstance> componentInstances,
2767                                                          Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2768                                                          Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities,
2769                                                          Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements) {
2770         componentInstances.forEach(i -> {
2771             fillUpdatedInstCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2772             fillUpdatedInstRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2773         });
2774     }
2775
2776     private void fillUpdatedInstRequirements(Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2777                                              ComponentInstance instance, Map<String, String> requirementsNamesToUpdate) {
2778         Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2779         Set<String> updatedReqNames = new HashSet<>();
2780         if (isNotEmpty(requirementsNamesToUpdate)) {
2781             for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2782                 updatedRequirements.put(requirements.getKey(), requirements.getValue().stream().filter(
2783                         r -> requirementsNamesToUpdate.containsKey(r.getName()) && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2784                     .map(r -> {
2785                         r.setParentName(r.getName());
2786                         r.setName(requirementsNamesToUpdate.get(r.getName()));
2787                         updatedReqNames.add(r.getName());
2788                         return r;
2789                     }).collect(toList()));
2790             }
2791         }
2792         if (isNotEmpty(updatedRequirements)) {
2793             updatedInstRequirements.put(instance, updatedRequirements);
2794         }
2795     }
2796
2797     private void setExternalRequirements(
2798         final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2799         final ComponentInstance instance, final Map<String, String> requirementsNamesToUpdate) {
2800         final Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2801         final Set<String> updatedReqNames = new HashSet<>();
2802         if (isNotEmpty(requirementsNamesToUpdate)) {
2803             for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2804                 updatedRequirements.put(requirements.getKey(),
2805                     requirements.getValue().stream()
2806                         .filter(r -> requirementsNamesToUpdate.containsKey(r.getName())
2807                             && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2808                         .map(r -> {
2809                             r.setExternal(true);
2810                             r.setExternalName(requirementsNamesToUpdate.get(r.getName()));
2811                             updatedReqNames.add(r.getName());
2812                             return r;
2813                         }).collect(toList()));
2814             }
2815         }
2816         if (isNotEmpty(updatedRequirements)) {
2817             updatedInstRequirements.put(instance, updatedRequirements);
2818         }
2819     }
2820
2821     private void setExternalCapabilities(
2822         final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2823         final ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2824         final Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2825         final Set<String> updatedCapNames = new HashSet<>();
2826         if (isNotEmpty(capabilitiesNamesToUpdate)) {
2827             for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2828                 updatedCapabilities.put(requirements.getKey(),
2829                     requirements.getValue().stream()
2830                         .filter(c -> capabilitiesNamesToUpdate.containsKey(c.getName())
2831                             && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2832                         .map(c -> {
2833                             c.setExternal(true);
2834                             c.setExternalName(capabilitiesNamesToUpdate.get(c.getName()));
2835                             updatedCapNames.add(c.getName());
2836                             return c;
2837                         }).collect(toList()));
2838             }
2839         }
2840         if (isNotEmpty(updatedCapabilities)) {
2841             updatedInstCapabilties.put(instance, updatedCapabilities);
2842         }
2843     }
2844
2845     private void fillUpdatedInstCapabilities(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2846                                              ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2847         Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2848         Set<String> updatedCapNames = new HashSet<>();
2849         if (isNotEmpty(capabilitiesNamesToUpdate)) {
2850             for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2851                 updatedCapabilities.put(requirements.getKey(), requirements.getValue().stream().filter(
2852                         c -> capabilitiesNamesToUpdate.containsKey(c.getName()) && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2853                     .map(c -> {
2854                         c.setParentName(c.getName());
2855                         c.setName(capabilitiesNamesToUpdate.get(c.getName()));
2856                         updatedCapNames.add(c.getName());
2857                         return c;
2858                     }).collect(toList()));
2859             }
2860         }
2861         if (isNotEmpty(updatedCapabilities)) {
2862             updatedInstCapabilties.put(instance, updatedCapabilities);
2863         }
2864     }
2865
2866     private ResponseFormat addRelationToRI(String yamlName, Resource resource, UploadComponentInstanceInfo nodesInfoValue,
2867                                            List<RequirementCapabilityRelDef> relations) {
2868         List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2869         ComponentInstance currentCompInstance = null;
2870         for (ComponentInstance compInstance : componentInstancesList) {
2871             if (compInstance.getName().equals(nodesInfoValue.getName())) {
2872                 currentCompInstance = compInstance;
2873                 break;
2874             }
2875         }
2876         if (currentCompInstance == null) {
2877             log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, nodesInfoValue.getName(), resource.getUniqueId());
2878             BeEcompErrorManager.getInstance()
2879                 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + nodesInfoValue.getName() + IN_RESOURCE, resource.getUniqueId(),
2880                     ErrorSeverity.ERROR);
2881             return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2882         }
2883         String resourceInstanceId = currentCompInstance.getUniqueId();
2884         Map<String, List<UploadReqInfo>> regMap = nodesInfoValue.getRequirements();
2885         if (regMap != null) {
2886             for (Entry<String, List<UploadReqInfo>> nodesRegInfoEntry : regMap.entrySet()) {
2887                 List<UploadReqInfo> uploadRegInfoList = nodesRegInfoEntry.getValue();
2888                 for (UploadReqInfo uploadRegInfo : uploadRegInfoList) {
2889                     log.debug("Going to create  relation {}", uploadRegInfo.getName());
2890                     loggerSupportability
2891                         .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2892                             "Started to create relations on instance: {}", uploadRegInfo.getName());
2893                     String regName = uploadRegInfo.getName();
2894                     RequirementCapabilityRelDef regCapRelDef = new RequirementCapabilityRelDef();
2895                     regCapRelDef.setFromNode(resourceInstanceId);
2896                     log.debug("try to find available requirement {} ", regName);
2897                     Either<RequirementDefinition, ResponseFormat> eitherReqStatus = findAviableRequiremen(regName, yamlName, nodesInfoValue,
2898                         currentCompInstance, uploadRegInfo.getCapabilityName());
2899                     if (eitherReqStatus.isRight()) {
2900                         log.debug("failed to find available requirement {} status is {}", regName, eitherReqStatus.right().value());
2901                         loggerSupportability
2902                             .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2903                                 "ERROR while search available requirement {} status is: {}", regName, eitherReqStatus.right().value());
2904                         return eitherReqStatus.right().value();
2905                     }
2906                     RequirementDefinition validReq = eitherReqStatus.left().value();
2907                     List<CapabilityRequirementRelationship> reqAndRelationshipPairList = regCapRelDef.getRelationships();
2908                     if (reqAndRelationshipPairList == null) {
2909                         reqAndRelationshipPairList = new ArrayList<>();
2910                     }
2911                     RelationshipInfo reqAndRelationshipPair = new RelationshipInfo();
2912                     reqAndRelationshipPair.setRequirement(regName);
2913                     reqAndRelationshipPair.setRequirementOwnerId(validReq.getOwnerId());
2914                     reqAndRelationshipPair.setRequirementUid(validReq.getUniqueId());
2915                     RelationshipImpl relationship = new RelationshipImpl();
2916                     relationship.setType(validReq.getCapability());
2917                     reqAndRelationshipPair.setRelationships(relationship);
2918                     ComponentInstance currentCapCompInstance = null;
2919                     for (ComponentInstance compInstance : componentInstancesList) {
2920                         if (compInstance.getName().equals(uploadRegInfo.getNode())) {
2921                             currentCapCompInstance = compInstance;
2922                             break;
2923                         }
2924                     }
2925                     if (currentCapCompInstance == null) {
2926                         log.debug("The component instance  with name {} not found on resource {} ", uploadRegInfo.getNode(), resource.getUniqueId());
2927                         loggerSupportability
2928                             .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2929                                 "ERROR component instance  with name: {} not found on resource: {}", uploadRegInfo.getNode(), resource.getUniqueId());
2930                         BeEcompErrorManager.getInstance()
2931                             .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadRegInfo.getNode() + IN_RESOURCE, resource.getUniqueId(),
2932                                 ErrorSeverity.ERROR);
2933                         return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2934                     }
2935                     regCapRelDef.setToNode(currentCapCompInstance.getUniqueId());
2936                     log.debug("try to find aviable Capability  req name is {} ", validReq.getName());
2937                     CapabilityDefinition aviableCapForRel = findAvailableCapabilityByTypeOrName(validReq, currentCapCompInstance, uploadRegInfo);
2938                     if (aviableCapForRel == null) {
2939                         log.debug("aviable capability was not found. req name is {} component instance is {}", validReq.getName(),
2940                             currentCapCompInstance.getUniqueId());
2941                         loggerSupportability
2942                             .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2943                                 "ERROR available capability was not found. req name is: {} component instance is: {}", validReq.getName(),
2944                                 currentCapCompInstance.getUniqueId());
2945                         BeEcompErrorManager.getInstance().logInternalDataError(
2946                             "aviable capability was not found. req name is " + validReq.getName() + " component instance is " + currentCapCompInstance
2947                                 .getUniqueId(), resource.getUniqueId(), ErrorSeverity.ERROR);
2948                         return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2949                     }
2950                     reqAndRelationshipPair.setCapability(aviableCapForRel.getName());
2951                     reqAndRelationshipPair.setCapabilityUid(aviableCapForRel.getUniqueId());
2952                     reqAndRelationshipPair.setCapabilityOwnerId(aviableCapForRel.getOwnerId());
2953                     CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
2954                     capReqRel.setRelation(reqAndRelationshipPair);
2955                     reqAndRelationshipPairList.add(capReqRel);
2956                     regCapRelDef.setRelationships(reqAndRelationshipPairList);
2957                     relations.add(regCapRelDef);
2958                 }
2959             }
2960         } else if (resource.getResourceType() != ResourceTypeEnum.CVFC) {
2961             return componentsUtils.getResponseFormat(ActionStatus.OK, yamlName);
2962         }
2963         return componentsUtils.getResponseFormat(ActionStatus.OK);
2964     }
2965
2966     private void addInputsValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
2967                                      ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceInput>> instInputs,
2968                                      Map<String, DataTypeDefinition> allDataTypes) {
2969         Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
2970         if (MapUtils.isNotEmpty(propMap)) {
2971             Map<String, InputDefinition> currPropertiesMap = new HashMap<>();
2972             List<ComponentInstanceInput> instPropList = new ArrayList<>();
2973             if (CollectionUtils.isEmpty(originResource.getInputs())) {
2974                 log.debug("failed to find properties ");
2975                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2976                     "ERROR while try to find properties");
2977                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND);
2978             }
2979             originResource.getInputs().forEach(p -> addInput(currPropertiesMap, p));
2980             for (List<UploadPropInfo> propertyList : propMap.values()) {
2981                 processProperty(resource, currentCompInstance, allDataTypes, currPropertiesMap, instPropList, propertyList);
2982             }
2983             currPropertiesMap.values().forEach(p -> instPropList.add(new ComponentInstanceInput(p)));
2984             instInputs.put(currentCompInstance.getUniqueId(), instPropList);
2985         }
2986     }
2987
2988     private void processProperty(Resource resource, ComponentInstance currentCompInstance, Map<String, DataTypeDefinition> allDataTypes,
2989                                  Map<String, InputDefinition> currPropertiesMap, List<ComponentInstanceInput> instPropList,
2990                                  List<UploadPropInfo> propertyList) {
2991         UploadPropInfo propertyInfo = propertyList.get(0);
2992         String propName = propertyInfo.getName();
2993         if (!currPropertiesMap.containsKey(propName)) {
2994             loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2995                 "ERROR failed to find property: {}", propName);
2996             log.debug("failed to find property {} ", propName);
2997             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, propName);
2998         }
2999         InputDefinition curPropertyDef = currPropertiesMap.get(propName);
3000         ComponentInstanceInput property = null;
3001         String value = null;
3002         List<GetInputValueDataDefinition> getInputs = null;
3003         boolean isValidate = true;
3004         if (propertyInfo.getValue() != null) {
3005             getInputs = propertyInfo.getGet_input();
3006             isValidate = getInputs == null || getInputs.isEmpty();
3007             if (isValidate) {
3008                 value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3009             } else {
3010                 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3011             }
3012         }
3013         property = new ComponentInstanceInput(curPropertyDef, value, null);
3014         String validPropertyVAlue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3015         property.setValue(validPropertyVAlue);
3016         if (isNotEmpty(getInputs)) {
3017             List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3018             for (GetInputValueDataDefinition getInput : getInputs) {
3019                 List<InputDefinition> inputs = resource.getInputs();
3020                 if (CollectionUtils.isEmpty(inputs)) {
3021                     loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3022                         "ERROR Failed to add property: " + propName + " to resource instance: {}. Inputs list is empty ",
3023                         currentCompInstance.getUniqueId());
3024                     log.debug("Failed to add property {} to resource instance {}. Inputs list is empty ", property,
3025                         currentCompInstance.getUniqueId());
3026                     throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3027                 }
3028                 Optional<InputDefinition> optional = inputs.stream().filter(p -> p.getName().equals(getInput.getInputName())).findAny();
3029                 if (optional.isEmpty()) {
3030                     loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3031                         "ERROR Failed to find input: " + getInput.getInputName());
3032                     log.debug("Failed to find input {} ", getInput.getInputName());
3033                     // @@TODO error message
3034                     throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3035                 }
3036                 InputDefinition input = optional.get();
3037                 getInput.setInputId(input.getUniqueId());
3038                 getInputValues.add(getInput);
3039                 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3040                 processGetInput(getInputValues, inputs, getInputIndex);
3041             }
3042             property.setGetInputValues(getInputValues);
3043         }
3044         instPropList.add(property);
3045         // delete overriden property
3046         currPropertiesMap.remove(property.getName());
3047     }
3048
3049     private void processGetInput(List<GetInputValueDataDefinition> getInputValues, List<InputDefinition> inputs,
3050                                  GetInputValueDataDefinition getInputIndex) {
3051         Optional<InputDefinition> optional;
3052         if (getInputIndex != null) {
3053             optional = inputs.stream().filter(p -> p.getName().equals(getInputIndex.getInputName())).findAny();
3054             if (optional.isEmpty()) {
3055                 log.debug("Failed to find input {} ", getInputIndex.getInputName());
3056                 // @@TODO error message
3057                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3058             }
3059             InputDefinition inputIndex = optional.get();
3060             getInputIndex.setInputId(inputIndex.getUniqueId());
3061             getInputValues.add(getInputIndex);
3062         }
3063     }
3064
3065     private void addInput(Map<String, InputDefinition> currPropertiesMap, InputDefinition prop) {
3066         String propName = prop.getName();
3067         if (!currPropertiesMap.containsKey(propName)) {
3068             currPropertiesMap.put(propName, prop);
3069         }
3070     }
3071
3072     private ResponseFormat addPropertyValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
3073                                                  ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceProperty>> instProperties,
3074                                                  Map<String, DataTypeDefinition> allDataTypes) {
3075         Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
3076         Map<String, PropertyDefinition> currPropertiesMap = new HashMap<>();
3077         List<PropertyDefinition> listFromMap = originResource.getProperties();
3078         if ((propMap != null && !propMap.isEmpty()) && (listFromMap == null || listFromMap.isEmpty())) {
3079             loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3080                 "ERROR Failed to find properties");
3081             log.debug("failed to find properties");
3082             return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND);
3083         }
3084         if (listFromMap == null || listFromMap.isEmpty()) {
3085             return componentsUtils.getResponseFormat(ActionStatus.OK);
3086         }
3087         for (PropertyDefinition prop : listFromMap) {
3088             String propName = prop.getName();
3089             if (!currPropertiesMap.containsKey(propName)) {
3090                 currPropertiesMap.put(propName, prop);
3091             }
3092         }
3093         List<ComponentInstanceProperty> instPropList = new ArrayList<>();
3094         if (propMap != null && propMap.size() > 0) {
3095             for (List<UploadPropInfo> propertyList : propMap.values()) {
3096                 UploadPropInfo propertyInfo = propertyList.get(0);
3097                 String propName = propertyInfo.getName();
3098                 if (!currPropertiesMap.containsKey(propName)) {
3099                     log.debug("failed to find property {} ", propName);
3100                     loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3101                         "ERROR Failed to find property: {}", propName);
3102                     return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, propName);
3103                 }
3104                 PropertyDefinition curPropertyDef = currPropertiesMap.get(propName);
3105                 ComponentInstanceProperty property = null;
3106                 String value = null;
3107                 List<GetInputValueDataDefinition> getInputs = null;
3108                 boolean isValidate = true;
3109                 if (propertyInfo.getValue() != null) {
3110                     getInputs = propertyInfo.getGet_input();
3111                     isValidate = getInputs == null || getInputs.isEmpty();
3112                     if (isValidate) {
3113                         value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3114                     } else {
3115                         value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3116                     }
3117                 }
3118                 property = new ComponentInstanceProperty(curPropertyDef, value, null);
3119                 String validatePropValue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3120                 property.setValue(validatePropValue);
3121                 if (getInputs != null && !getInputs.isEmpty()) {
3122                     List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3123                     for (GetInputValueDataDefinition getInput : getInputs) {
3124                         List<InputDefinition> inputs = resource.getInputs();
3125                         if (inputs == null || inputs.isEmpty()) {
3126                             log.debug("Failed to add property {} to instance. Inputs list is empty ", property);
3127                             loggerSupportability
3128                                 .log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3129                                     "Failed to add property: {} to instance. Inputs list is empty", propName);
3130                             rollbackWithException(ActionStatus.INPUTS_NOT_FOUND,
3131                                 property.getGetInputValues().stream().map(GetInputValueDataDefinition::getInputName).collect(toList()).toString());
3132                         }
3133                         Either<InputDefinition, RuntimeException> inputEither = findInputByName(inputs, getInput);
3134                         if (inputEither.isRight()) {
3135                             throw inputEither.right().value();
3136                         } else {
3137                             InputDefinition input = inputEither.left().value();
3138                             getInput.setInputId(input.getUniqueId());
3139                             getInputValues.add(getInput);
3140                             GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3141                             if (getInputIndex != null) {
3142                                 Either<InputDefinition, RuntimeException> newInputEither = findInputByName(inputs, getInputIndex);
3143                                 if (inputEither.isRight()) {
3144                                     throw newInputEither.right().value();
3145                                 } else {
3146                                     InputDefinition newInput = newInputEither.left().value();
3147                                     getInputIndex.setInputId(newInput.getUniqueId());
3148                                 }
3149                                 getInputValues.add(getInputIndex);
3150                             }
3151                         }
3152                     }
3153                     property.setGetInputValues(getInputValues);
3154                 }
3155                 instPropList.add(property);
3156                 // delete overriden property
3157                 currPropertiesMap.remove(property.getName());
3158             }
3159         }
3160         // add rest of properties
3161         if (!currPropertiesMap.isEmpty()) {
3162             for (PropertyDefinition value : currPropertiesMap.values()) {
3163                 instPropList.add(new ComponentInstanceProperty(value));
3164             }
3165         }
3166         instProperties.put(currentCompInstance.getUniqueId(), instPropList);
3167         return componentsUtils.getResponseFormat(ActionStatus.OK);
3168     }
3169
3170     // US740820 Relate RIs according to capability name
3171     private CapabilityDefinition findAvailableCapabilityByTypeOrName(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3172                                                                      UploadReqInfo uploadReqInfo) {
3173         if (null == uploadReqInfo.getCapabilityName() || validReq.getCapability()
3174             .equals(uploadReqInfo.getCapabilityName())) {// get
3175
3176             // by
3177
3178             // capability
3179
3180             // type
3181             return findAvailableCapability(validReq, currentCapCompInstance);
3182         }
3183         return findAvailableCapability(validReq, currentCapCompInstance, uploadReqInfo);
3184     }
3185
3186     private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3187                                                          UploadReqInfo uploadReqInfo) {
3188         CapabilityDefinition cap = null;
3189         Map<String, List<CapabilityDefinition>> capMap = currentCapCompInstance.getCapabilities();
3190         if (!capMap.containsKey(validReq.getCapability())) {
3191             return null;
3192         }
3193         Optional<CapabilityDefinition> capByName = capMap.get(validReq.getCapability()).stream()
3194             .filter(p -> p.getName().equals(uploadReqInfo.getCapabilityName())).findAny();
3195         if (capByName.isEmpty()) {
3196             return null;
3197         }
3198         cap = capByName.get();
3199         if (isBoundedByOccurrences(cap)) {
3200             String leftOccurrences = cap.getLeftOccurrences();
3201             int left = Integer.parseInt(leftOccurrences);
3202             if (left > 0) {
3203                 --left;
3204                 cap.setLeftOccurrences(String.valueOf(left));
3205             }
3206         }
3207         return cap;
3208     }
3209
3210     private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance instance) {
3211         Map<String, List<CapabilityDefinition>> capMap = instance.getCapabilities();
3212         if (capMap.containsKey(validReq.getCapability())) {
3213             List<CapabilityDefinition> capList = capMap.get(validReq.getCapability());
3214             for (CapabilityDefinition cap : capList) {
3215                 if (isBoundedByOccurrences(cap)) {
3216                     String leftOccurrences = cap.getLeftOccurrences() != null ? cap.getLeftOccurrences() : cap.getMaxOccurrences();
3217                     int left = Integer.parseInt(leftOccurrences);
3218                     if (left > 0) {
3219                         --left;
3220                         cap.setLeftOccurrences(String.valueOf(left));
3221                         return cap;
3222                     }
3223                 } else {
3224                     return cap;
3225                 }
3226             }
3227         }
3228         return null;
3229     }
3230
3231     private boolean isBoundedByOccurrences(CapabilityDefinition cap) {
3232         return cap.getMaxOccurrences() != null && !cap.getMaxOccurrences().equals(CapabilityDataDefinition.MAX_OCCURRENCES);
3233     }
3234
3235     private Either<RequirementDefinition, ResponseFormat> findAviableRequiremen(String regName, String yamlName,
3236                                                                                 UploadComponentInstanceInfo uploadComponentInstanceInfo,
3237                                                                                 ComponentInstance currentCompInstance, String capName) {
3238         Map<String, List<RequirementDefinition>> comInstRegDefMap = currentCompInstance.getRequirements();
3239         List<RequirementDefinition> list = comInstRegDefMap.get(capName);
3240         RequirementDefinition validRegDef = null;
3241         if (list == null) {
3242             for (Entry<String, List<RequirementDefinition>> entry : comInstRegDefMap.entrySet()) {
3243                 for (RequirementDefinition reqDef : entry.getValue()) {
3244                     if (reqDef.getName().equals(regName)) {
3245                         if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3246                             String leftOccurrences = reqDef.getLeftOccurrences();
3247                             if (leftOccurrences == null) {
3248                                 leftOccurrences = reqDef.getMaxOccurrences();
3249                             }
3250                             int left = Integer.parseInt(leftOccurrences);
3251                             if (left > 0) {
3252                                 --left;
3253                                 reqDef.setLeftOccurrences(String.valueOf(left));
3254                                 validRegDef = reqDef;
3255                                 break;
3256                             } else {
3257                                 continue;
3258                             }
3259                         } else {
3260                             validRegDef = reqDef;
3261                             break;
3262                         }
3263                     }
3264                 }
3265                 if (validRegDef != null) {
3266                     break;
3267                 }
3268             }
3269         } else {
3270             for (RequirementDefinition reqDef : list) {
3271                 if (reqDef.getName().equals(regName)) {
3272                     if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3273                         String leftOccurrences = reqDef.getLeftOccurrences();
3274                         if (leftOccurrences == null) {
3275                             leftOccurrences = reqDef.getMaxOccurrences();
3276                         }
3277                         int left = Integer.parseInt(leftOccurrences);
3278                         if (left > 0) {
3279                             --left;
3280                             reqDef.setLeftOccurrences(String.valueOf(left));
3281                             validRegDef = reqDef;
3282                             break;
3283                         } else {
3284                             continue;
3285                         }
3286                     } else {
3287                         validRegDef = reqDef;
3288                         break;
3289                     }
3290                 }
3291             }
3292         }
3293         if (validRegDef == null) {
3294             ResponseFormat responseFormat = componentsUtils
3295                 .getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3296                     uploadComponentInstanceInfo.getType());
3297             return Either.right(responseFormat);
3298         }
3299         return Either.left(validRegDef);
3300     }
3301
3302     private Resource createResourceInstances(String yamlName, Resource resource, Resource oldResource,
3303                                              Map<String, UploadComponentInstanceInfo> uploadResInstancesMap, Map<String, Resource> nodeNamespaceMap,
3304                                              Map<String, Resource> existingNodeTypesByResourceNames) {
3305         Either<Resource, ResponseFormat> eitherResource;
3306         log.debug("createResourceInstances is {} - going to create resource instanse from CSAR", yamlName);
3307         if (isEmpty(uploadResInstancesMap) && resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3308             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
3309             throw new ByResponseFormatComponentException(responseFormat);
3310         }
3311         if (MapUtils.isNotEmpty(nodeNamespaceMap)) {
3312             nodeNamespaceMap.forEach((k, v) -> existingNodeTypesByResourceNames.put(v.getToscaResourceName(), v));
3313         }
3314         Map<ComponentInstance, Resource> resourcesInstancesMap = new HashMap<>();
3315         uploadResInstancesMap.values().forEach(
3316             i -> createAndAddResourceInstance(i, yamlName, resource, nodeNamespaceMap, existingNodeTypesByResourceNames, resourcesInstancesMap));
3317         if (oldResource != null && oldResource.getResourceType() != ResourceTypeEnum.CVFC && oldResource.getComponentInstances() != null) {
3318             Map<String, Resource> existingNodeTypesByUids = existingNodeTypesByResourceNames.values().stream()
3319                 .collect(toMap(Resource::getUniqueId, r -> r));
3320             oldResource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar())
3321                 .forEach(uiInst -> resourcesInstancesMap.put(uiInst, getOriginResource(existingNodeTypesByUids, uiInst)));
3322         }
3323         if (isNotEmpty(resourcesInstancesMap)) {
3324             try {
3325                 toscaOperationFacade.associateComponentInstancesToComponent(resource, resourcesInstancesMap, false, oldResource != null);
3326             } catch (StorageException exp) {
3327                 if (exp.getStorageOperationStatus() != null && exp.getStorageOperationStatus() != StorageOperationStatus.OK) {
3328                     log.debug("Failed to add component instances to container component {}", resource.getName());
3329                     ResponseFormat responseFormat = componentsUtils
3330                         .getResponseFormat(componentsUtils.convertFromStorageResponse(exp.getStorageOperationStatus()));
3331                     eitherResource = Either.right(responseFormat);
3332                     throw new ByResponseFormatComponentException(eitherResource.right().value());
3333                 }
3334             }
3335         }
3336         if (CollectionUtils.isEmpty(resource.getComponentInstances()) &&
3337             resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3338             log.debug("Error when create resource instance from csar. ComponentInstances list empty");
3339             BeEcompErrorManager.getInstance().logBeDaoSystemError("Error when create resource instance from csar. ComponentInstances list empty");
3340             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE));
3341         }
3342         return resource;
3343     }
3344
3345     private void createAndAddResourceInstance(UploadComponentInstanceInfo uploadComponentInstanceInfo, String yamlName, Resource resource,
3346                                               Map<String, Resource> nodeNamespaceMap, Map<String, Resource> existingnodeTypeMap,
3347                                               Map<ComponentInstance, Resource> resourcesInstancesMap) {
3348         Either<Resource, ResponseFormat> eitherResource;
3349         log.debug("*************Going to create  resource instances {}", yamlName);
3350         // updating type if the type is node type name - we need to take the
3351
3352         // updated name
3353         log.debug("*************Going to create  resource instances {}", uploadComponentInstanceInfo.getName());
3354         if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3355             uploadComponentInstanceInfo.setType(nodeNamespaceMap.get(uploadComponentInstanceInfo.getType()).getToscaResourceName());
3356         }
3357         Resource refResource = validateResourceInstanceBeforeCreate(yamlName, uploadComponentInstanceInfo, existingnodeTypeMap, resource);
3358         ComponentInstance componentInstance = new ComponentInstance();
3359         componentInstance.setComponentUid(refResource.getUniqueId());
3360         Collection<String> directives = uploadComponentInstanceInfo.getDirectives();
3361         if (directives != null && !directives.isEmpty()) {
3362             componentInstance.setDirectives(new ArrayList<>(directives));
3363         }
3364         UploadNodeFilterInfo uploadNodeFilterInfo = uploadComponentInstanceInfo.getUploadNodeFilterInfo();
3365         if (uploadNodeFilterInfo != null) {
3366             componentInstance
3367                 .setNodeFilter(new CINodeFilterUtils().getNodeFilterDataDefinition(uploadNodeFilterInfo, componentInstance.getUniqueId()));
3368         }
3369         ComponentTypeEnum containerComponentType = resource.getComponentType();
3370         NodeTypeEnum containerNodeType = containerComponentType.getNodeType();
3371         if (containerNodeType == NodeTypeEnum.Resource && isNotEmpty(uploadComponentInstanceInfo.getCapabilities()) && isNotEmpty(
3372             refResource.getCapabilities())) {
3373             setCapabilityNamesTypes(refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3374             Map<String, List<CapabilityDefinition>> validComponentInstanceCapabilities = getValidComponentInstanceCapabilities(
3375                 refResource.getUniqueId(), refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3376             componentInstance.setCapabilities(validComponentInstanceCapabilities);
3377         }
3378         if (isNotEmpty(uploadComponentInstanceInfo.getArtifacts())) {
3379             Map<String, Map<String, UploadArtifactInfo>> artifacts = uploadComponentInstanceInfo.getArtifacts();
3380             Map<String, ToscaArtifactDataDefinition> toscaArtifacts = new HashMap<>();
3381             Map<String, Map<String, UploadArtifactInfo>> arts = artifacts.entrySet().stream()
3382                 .filter(e -> e.getKey().contains(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName()))
3383                 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
3384             Map<String, UploadArtifactInfo> artifact = arts.get(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName());
3385             for (Map.Entry<String, UploadArtifactInfo> entry : artifact.entrySet()) {
3386                 ToscaArtifactDataDefinition to = new ToscaArtifactDataDefinition();
3387                 to.setFile(entry.getValue().getFile());
3388                 to.setType(entry.getValue().getType());
3389                 if (isNotEmpty(entry.getValue().getProperties())) {
3390                     Map<String, Object> newPropertiesMap = new HashMap<>();
3391                     List<UploadPropInfo> artifactPropsInfo = entry.getValue().getProperties();
3392                     for (UploadPropInfo propInfo : artifactPropsInfo) {
3393                         newPropertiesMap.put(propInfo.getName(), propInfo.getValue());
3394                     }
3395                     to.setProperties(newPropertiesMap);
3396                 }
3397                 toscaArtifacts.put(entry.getKey(), to);
3398             }
3399             componentInstance.setToscaArtifacts(toscaArtifacts);
3400         }
3401         if (!existingnodeTypeMap.containsKey(uploadComponentInstanceInfo.getType())) {
3402             log.debug("createResourceInstances - not found lates version for resource instance with name {} and type {}",
3403                 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3404             throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3405                 uploadComponentInstanceInfo.getType());
3406         }
3407         Resource origResource = existingnodeTypeMap.get(uploadComponentInstanceInfo.getType());
3408         componentInstance.setName(uploadComponentInstanceInfo.getName());
3409         componentInstance.setIcon(origResource.getIcon());
3410         componentInstance.setCreatedFrom(CreatedFrom.CSAR);
3411         resourcesInstancesMap.put(componentInstance, origResource);
3412     }
3413
3414     private void setCapabilityNamesTypes(Map<String, List<CapabilityDefinition>> originCapabilities,
3415                                          Map<String, List<UploadCapInfo>> uploadedCapabilities) {
3416         for (Entry<String, List<UploadCapInfo>> currEntry : uploadedCapabilities.entrySet()) {
3417             if (originCapabilities.containsKey(currEntry.getKey())) {
3418                 currEntry.getValue().forEach(cap -> cap.setType(currEntry.getKey()));
3419             }
3420         }
3421         for (Map.Entry<String, List<CapabilityDefinition>> capabilities : originCapabilities.entrySet()) {
3422             capabilities.getValue().forEach(cap -> {
3423                 if (uploadedCapabilities.containsKey(cap.getName())) {
3424                     uploadedCapabilities.get(cap.getName()).forEach(c -> {
3425                         c.setName(cap.getName());
3426                         c.setType(cap.getType());
3427                     });
3428                 }
3429             });
3430         }
3431     }
3432
3433     private Resource validateResourceInstanceBeforeCreate(String yamlName, UploadComponentInstanceInfo uploadComponentInstanceInfo,
3434                                                           Map<String, Resource> nodeNamespaceMap, Resource resource) {
3435         log.debug("validateResourceInstanceBeforeCreate - going to validate resource instance with name {} and type {} before create",
3436             uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3437         Resource refResource;
3438         if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3439             refResource = nodeNamespaceMap.get(uploadComponentInstanceInfo.getType());
3440         } else {
3441             Either<Resource, StorageOperationStatus> findResourceEither = StringUtils.isEmpty(resource.getModel()) ?
3442                 toscaOperationFacade.getByToscaResourceNameMatchingVendorRelease(uploadComponentInstanceInfo.getType(),
3443                     ((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()).getVendorRelease()) :
3444                 toscaOperationFacade.getLatestByToscaResourceNameAndModel(uploadComponentInstanceInfo.getType(), resource.getModel());
3445             if (findResourceEither.isRight()) {
3446                 log.debug("validateResourceInstanceBeforeCreate - not found latest version for resource instance with name {} and type {}",
3447                     uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3448                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(findResourceEither.right().value()));
3449             }
3450             refResource = findResourceEither.left().value();
3451             nodeNamespaceMap.put(refResource.getToscaResourceName(), refResource);
3452         }
3453         String componentState = refResource.getComponentMetadataDefinition().getMetadataDataDefinition().getState();
3454         if (componentState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3455             log.debug(
3456                 "validateResourceInstanceBeforeCreate - component instance of component {} can not be created because the component is in an illegal state {}.",
3457                 refResource.getName(), componentState);
3458             throw new ByActionStatusComponentException(ActionStatus.ILLEGAL_COMPONENT_STATE, refResource.getComponentType().getValue(),
3459                 refResource.getName(), componentState);
3460         }
3461         if (!ModelConverter.isAtomicComponent(refResource) && refResource.getResourceType() != ResourceTypeEnum.CVFC) {
3462             log.debug("validateResourceInstanceBeforeCreate -  ref resource type is {} ", refResource.getResourceType());
3463             throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3464                 uploadComponentInstanceInfo.getType());
3465         }
3466         return refResource;
3467     }
3468
3469     public Resource propagateStateToCertified(User user, Resource resource, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3470                                               boolean needLock, boolean forceCertificationAllowed) {
3471         boolean failed = false;
3472         try {
3473             if (resource.getLifecycleState() != LifecycleStateEnum.CERTIFIED && forceCertificationAllowed && lifecycleBusinessLogic
3474                 .isFirstCertification(resource.getVersion())) {
3475                 nodeForceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3476             }
3477             if (resource.getLifecycleState() == LifecycleStateEnum.CERTIFIED) {
3478                 Either<ArtifactDefinition, Operation> eitherPopulated = populateToscaArtifacts(resource, user, false, inTransaction, needLock, false);
3479                 return resource;
3480             }
3481             return nodeFullCertification(resource.getUniqueId(), user, lifecycleChangeInfo, inTransaction, needLock);
3482         } catch (ComponentException e) {
3483             failed = true;
3484             log.debug("The exception has occurred upon certification of resource {}. ", resource.getName(), e);
3485             throw e;
3486         } finally {
3487             if (failed) {
3488                 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3489                 if (!inTransaction) {
3490                     janusGraphDao.rollback();
3491                 }
3492             } else if (!inTransaction) {
3493                 janusGraphDao.commit();
3494             }
3495         }
3496     }
3497
3498     private Resource nodeFullCertification(String uniqueId, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3499                                            boolean needLock) {
3500         Either<Resource, ResponseFormat> resourceResponse = lifecycleBusinessLogic
3501             .changeState(uniqueId, user, LifeCycleTransitionEnum.CERTIFY, lifecycleChangeInfo, inTransaction, needLock);
3502         if (resourceResponse.isRight()) {
3503             throw new ByResponseFormatComponentException(resourceResponse.right().value());
3504         }
3505         return resourceResponse.left().value();
3506     }
3507
3508     private Resource nodeForceCertification(Resource resource, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3509                                             boolean needLock) {
3510         return lifecycleBusinessLogic.forceResourceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3511     }
3512
3513     public ImmutablePair<Resource, ActionStatus> createOrUpdateResourceByImport(final Resource resource, final User user, final boolean isNormative,
3514                                                                                 final boolean isInTransaction, final boolean needLock,
3515                                                                                 final CsarInfo csarInfo, final String nodeName,
3516                                                                                 final boolean isNested) {
3517         ImmutablePair<Resource, ActionStatus> result = null;
3518         // check if resource already exists (search by tosca name = type)
3519         final boolean isNestedResource = isNestedResourceUpdate(csarInfo, nodeName);
3520         final String resourceName = resource.getToscaResourceName();
3521         final Either<Resource, StorageOperationStatus> latestByToscaName = toscaOperationFacade
3522             .getLatestByToscaResourceNameAndModel(resourceName, resource.getModel());
3523         if (latestByToscaName.isLeft() && Objects.nonNull(latestByToscaName.left().value())) {
3524             final Resource foundResource = latestByToscaName.left().value();
3525             // we don't allow updating names of top level types
3526             if (!isNestedResource && !StringUtils.equals(resource.getName(), foundResource.getName())) {
3527                 BeEcompErrorManager.getInstance()
3528                     .logBeComponentMissingError("Create / Update resource by import", ComponentTypeEnum.RESOURCE.getValue(), resource.getName());
3529                 log.debug("resource already exist new name={} old name={} same type={}", resource.getName(), foundResource.getName(),
3530                     resource.getToscaResourceName());
3531                 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
3532                 componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3533                 throwComponentException(responseFormat);
3534             }
3535             result = updateExistingResourceByImport(resource, foundResource, user, isNormative, needLock, isNested);
3536         } else if (isNotFound(latestByToscaName)) {
3537             if (isNestedResource) {
3538                 result = createOrUpdateNestedResource(resource, user, isNormative, isInTransaction, needLock, csarInfo, isNested, nodeName);
3539             } else {
3540                 result = createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3541             }
3542         } else {
3543             StorageOperationStatus status = latestByToscaName.right().value();
3544             log.debug("failed to get latest version of resource {}. status={}", resource.getName(), status);
3545             ResponseFormat responseFormat = componentsUtils
3546                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(latestByToscaName.right().value()), resource);
3547             componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3548             throwComponentException(responseFormat);
3549         }
3550         return result;
3551     }
3552
3553     private boolean isNestedResourceUpdate(CsarInfo csarInfo, String nodeName) {
3554         return csarInfo != null && csarInfo.isUpdate() && nodeName != null;
3555     }
3556
3557     private ImmutablePair<Resource, ActionStatus> createOrUpdateNestedResource(final Resource resource, final User user, final boolean isNormative,
3558                                                                                final boolean isInTransaction, final boolean needLock,
3559                                                                                final CsarInfo csarInfo, final boolean isNested,
3560                                                                                final String nodeName) {
3561         final Either<Component, StorageOperationStatus> latestByToscaName = toscaOperationFacade.getLatestByToscaResourceName(
3562             buildNestedToscaResourceName(resource.getResourceType().name(), csarInfo.getVfResourceName(), nodeName).getRight(), resource.getModel());
3563         if (latestByToscaName.isLeft()) {
3564             final Resource nestedResource = (Resource) latestByToscaName.left().value();
3565             log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
3566             final Either<Boolean, ResponseFormat> eitherValidation = validateNestedDerivedFromDuringUpdate(nestedResource, resource,
3567                 ValidationUtils.hasBeenCertified(nestedResource.getVersion()));
3568             if (eitherValidation.isRight()) {
3569                 return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3570             }
3571             return updateExistingResourceByImport(resource, nestedResource, user, isNormative, needLock, isNested);
3572         } else {
3573             return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3574         }
3575     }
3576
3577     private boolean isNotFound(Either<Resource, StorageOperationStatus> getResourceEither) {
3578         return getResourceEither.isRight() && getResourceEither.right().value() == StorageOperationStatus.NOT_FOUND;
3579     }
3580
3581     private ImmutablePair<Resource, ActionStatus> createResourceByImport(Resource resource, User user, boolean isNormative, boolean isInTransaction,
3582                                                                          CsarInfo csarInfo) {
3583         log.debug("resource with name {} does not exist. create new resource", resource.getName());
3584         validateResourceBeforeCreate(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isInTransaction, csarInfo);
3585         final Resource createResourceByDao = createResourceByDao(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isNormative, isInTransaction);
3586         Resource createdResource = updateCatalog(createResourceByDao, ChangeTypeEnum.LIFECYCLE).left().map(r -> (Resource) r).left().value();
3587         ImmutablePair<Resource, ActionStatus> resourcePair = new ImmutablePair<>(createdResource, ActionStatus.CREATED);
3588         ASDCKpiApi.countImportResourcesKPI();
3589         return resourcePair;
3590     }
3591
3592     public boolean isResourceExist(String resourceName) {
3593         Either<Resource, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByName(resourceName, null);
3594         return latestByName.isLeft();
3595     }
3596
3597     private ImmutablePair<Resource, ActionStatus> updateExistingResourceByImport(Resource newResource, Resource oldResource, User user,
3598                                                                                  boolean inTransaction, boolean needLock, boolean isNested) {
3599         String lockedResourceId = oldResource.getUniqueId();
3600         log.debug("found resource: name={}, id={}, version={}, state={}", oldResource.getName(), lockedResourceId, oldResource.getVersion(),
3601             oldResource.getLifecycleState());
3602         ImmutablePair<Resource, ActionStatus> resourcePair = null;
3603         try {
3604             lockComponent(lockedResourceId, oldResource, needLock, "Update Resource by Import");
3605             oldResource = prepareResourceForUpdate(oldResource, newResource, user, inTransaction, false);
3606             mergeOldResourceMetadataWithNew(oldResource, newResource);
3607             validateResourceFieldsBeforeUpdate(oldResource, newResource, inTransaction, isNested);
3608             validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), newResource, AuditingActionEnum.IMPORT_RESOURCE, inTransaction);
3609             // contact info normalization
3610             newResource.setContactId(newResource.getContactId().toLowerCase());
3611             PropertyConstraintsUtils.validatePropertiesConstraints(newResource, oldResource);
3612             // non-updatable fields
3613             newResource.setCreatorUserId(user.getUserId());
3614             newResource.setCreatorFullName(user.getFullName());
3615             newResource.setLastUpdaterUserId(user.getUserId());
3616             newResource.setLastUpdaterFullName(user.getFullName());
3617             newResource.setUniqueId(oldResource.getUniqueId());
3618             newResource.setVersion(oldResource.getVersion());
3619             newResource.setInvariantUUID(oldResource.getInvariantUUID());
3620             newResource.setLifecycleState(oldResource.getLifecycleState());
3621             newResource.setUUID(oldResource.getUUID());
3622             newResource.setNormalizedName(oldResource.getNormalizedName());
3623             newResource.setSystemName(oldResource.getSystemName());
3624             newResource.setModel(oldResource.getModel());
3625             if (oldResource.getCsarUUID() != null) {
3626                 newResource.setCsarUUID(oldResource.getCsarUUID());
3627             }
3628             if (oldResource.getImportedToscaChecksum() != null) {
3629                 newResource.setImportedToscaChecksum(oldResource.getImportedToscaChecksum());
3630             }
3631             newResource.setAbstract(oldResource.isAbstract());
3632             if (CollectionUtils.isEmpty(newResource.getDerivedFrom())) {
3633                 newResource.setDerivedFrom(oldResource.getDerivedFrom());
3634             }
3635             if (CollectionUtils.isEmpty(newResource.getDataTypes())) {
3636                 newResource.setDataTypes(oldResource.getDataTypes());
3637             }
3638             if (StringUtils.isEmpty(newResource.getDerivedFromGenericType())) {
3639                 newResource.setDerivedFromGenericType(oldResource.getDerivedFromGenericType());
3640             }
3641             if (StringUtils.isEmpty(newResource.getDerivedFromGenericVersion())) {
3642                 newResource.setDerivedFromGenericVersion(oldResource.getDerivedFromGenericVersion());
3643             }
3644             // add for new)
3645
3646             // created without tosca artifacts - add the placeholders
3647             if (MapUtils.isEmpty(newResource.getToscaArtifacts())) {
3648                 setToscaArtifactsPlaceHolders(newResource, user);
3649             }
3650             if (MapUtils.isEmpty(newResource.getInterfaces())) {
3651                 newResource.setInterfaces(oldResource.getInterfaces());
3652             }
3653             if (CollectionUtils.isEmpty(newResource.getAttributes())) {
3654                 newResource.setAttributes(oldResource.getAttributes());
3655             }
3656             if (CollectionUtils.isEmpty(newResource.getProperties())) {
3657                 newResource.setProperties(oldResource.getProperties());
3658             }
3659             Either<Resource, StorageOperationStatus> overrideResource = toscaOperationFacade.overrideComponent(newResource, oldResource);
3660             if (overrideResource.isRight()) {
3661                 ResponseFormat responseFormat = componentsUtils
3662                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(overrideResource.right().value()), newResource);
3663                 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE);
3664                 throwComponentException(responseFormat);
3665             }
3666             updateCatalog(overrideResource.left().value(), ChangeTypeEnum.LIFECYCLE);
3667             log.debug("Resource updated successfully!!!");
3668             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3669             componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3670                 ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3671             resourcePair = new ImmutablePair<>(overrideResource.left().value(), ActionStatus.OK);
3672             return resourcePair;
3673         } finally {
3674             if (resourcePair == null) {
3675                 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3676                 janusGraphDao.rollback();
3677             } else if (!inTransaction) {
3678                 janusGraphDao.commit();
3679             }
3680             if (needLock) {
3681                 log.debug("unlock resource {}", lockedResourceId);
3682                 graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource);
3683             }
3684         }
3685     }
3686
3687     /**
3688      * Merge old resource with new. Keep old category and vendor name without change
3689      *
3690      * @param oldResource
3691      * @param newResource
3692      */
3693     private void mergeOldResourceMetadataWithNew(Resource oldResource, Resource newResource) {
3694         // keep old category and vendor name without change
3695
3696         // merge the rest of the resource metadata
3697         if (newResource.getTags() == null || newResource.getTags().isEmpty()) {
3698             newResource.setTags(oldResource.getTags());
3699         }
3700         if (newResource.getDescription() == null) {
3701             newResource.setDescription(oldResource.getDescription());
3702         }
3703         if (newResource.getVendorRelease() == null) {
3704             newResource.setVendorRelease(oldResource.getVendorRelease());
3705         }
3706         if (newResource.getResourceVendorModelNumber() == null) {
3707             newResource.setResourceVendorModelNumber(oldResource.getResourceVendorModelNumber());
3708         }
3709         if (newResource.getModel() == null) {
3710             newResource.setModel(oldResource.getModel());
3711         }
3712         if (newResource.getContactId() == null) {
3713             newResource.setContactId(oldResource.getContactId());
3714         }
3715         newResource.setCategories(oldResource.getCategories());
3716         if (newResource.getVendorName() == null) {
3717             newResource.setVendorName(oldResource.getVendorName());
3718         }
3719         List<GroupDefinition> oldForUpdate = oldResource.getGroups();
3720         if (CollectionUtils.isNotEmpty(oldForUpdate)) {
3721             List<GroupDefinition> groupForUpdate = oldForUpdate.stream().map(GroupDefinition::new).collect(Collectors.toList());
3722             groupForUpdate.stream().filter(GroupDataDefinition::isVspOriginated).forEach(group -> group.setName(group.getInvariantName()));
3723             newResource.setGroups(groupForUpdate);
3724         }
3725         if (newResource.getResourceType().isAtomicType() && !newResource.getName().equals("Root")
3726             && newResource.getResourceType() != ResourceTypeEnum.CVFC) {
3727             ResourceTypeEnum updatedResourceType = newResource.getResourceType();
3728             Optional<Component> derivedFromResourceOptional = getParentComponent(newResource);
3729             if (derivedFromResourceOptional.isPresent() && derivedFromResourceOptional.get().getComponentType() == ComponentTypeEnum.RESOURCE) {
3730                 Resource parentResource = (Resource) derivedFromResourceOptional.get();
3731                 if (!(parentResource.isAbstract() && (ResourceTypeEnum.VFC == parentResource.getResourceType()
3732                     || ResourceTypeEnum.ABSTRACT == parentResource.getResourceType())) && parentResource.getResourceType() != updatedResourceType
3733                     && oldResource.getResourceType() != updatedResourceType) {
3734                     BeEcompErrorManager.getInstance().logInternalDataError("mergeOldResourceMetadataWithNew",
3735                         "resource type of the resource does not match to derived from resource type", ErrorSeverity.ERROR);
3736                     log.debug(
3737                         "#mergeOldResourceMetadataWithNew - resource type {} of the resource {} does not match to derived from resource type {}",
3738                         newResource.getResourceType(), newResource.getToscaResourceName(), parentResource.getResourceType());
3739                     throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_TYPE);
3740                 }
3741             }
3742         }
3743     }
3744
3745     private Optional<Component> getParentComponent(Resource newResource) {
3746         if (newResource.getDerivedFrom() == null) {
3747             return Optional.empty();
3748         }
3749         String toscaResourceNameDerivedFrom = newResource.getDerivedFrom().get(0);
3750         Either<Component, StorageOperationStatus> latestByToscaResourceName = toscaOperationFacade
3751             .getLatestByToscaResourceName(toscaResourceNameDerivedFrom, newResource.getModel());
3752         if (latestByToscaResourceName.isRight()) {
3753             BeEcompErrorManager.getInstance()
3754                 .logInternalDataError("mergeOldResourceMetadataWithNew", "derived from resource not found", ErrorSeverity.ERROR);
3755             log.debug("#mergeOldResourceMetadataWithNew - derived from resource {} not found", toscaResourceNameDerivedFrom);
3756             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, toscaResourceNameDerivedFrom);
3757         }
3758         return Optional.of(latestByToscaResourceName.left().value());
3759     }
3760
3761     private Resource prepareResourceForUpdate(Resource oldResource, Resource newResource, User user, boolean inTransaction, boolean needLock) {
3762         if (!ComponentValidationUtils.canWorkOnResource(oldResource, user.getUserId())) {
3763             // checkout
3764             return lifecycleBusinessLogic
3765                 .changeState(oldResource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, new LifecycleChangeInfoWithAction("update by import"),
3766                     inTransaction, needLock).left().on(response -> failOnChangeState(response, user, oldResource, newResource));
3767         }
3768         return oldResource;
3769     }
3770
3771     private Resource failOnChangeState(ResponseFormat response, User user, Resource oldResource, Resource newResource) {
3772         log.info("resource {} cannot be updated. reason={}", oldResource.getUniqueId(), response.getFormattedMessage());
3773         componentsUtils.auditResource(response, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3774             ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3775         throw new ByResponseFormatComponentException(response);
3776     }
3777
3778     public Resource validateResourceBeforeCreate(Resource resource, User user, AuditingActionEnum actionEnum, boolean inTransaction,
3779                                                  CsarInfo csarInfo) {
3780         validateResourceFieldsBeforeCreate(user, resource, actionEnum, inTransaction);
3781         validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), resource, actionEnum, inTransaction);
3782         validateLifecycleTypesCreate(user, resource, actionEnum);
3783         validateResourceType(user, resource, actionEnum);
3784         resource.setCreatorUserId(user.getUserId());
3785         resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
3786         resource.setContactId(resource.getContactId().toLowerCase());
3787         if (StringUtils.isEmpty(resource.getToscaResourceName()) && !ModelConverter.isAtomicComponent(resource)) {
3788             String resourceSystemName;
3789             if (csarInfo != null && StringUtils.isNotEmpty(csarInfo.getVfResourceName())) {
3790                 resourceSystemName = ValidationUtils.convertToSystemName(csarInfo.getVfResourceName());
3791             } else {
3792                 resourceSystemName = resource.getSystemName();
3793             }
3794             resource
3795                 .setToscaResourceName(CommonBeUtils.generateToscaResourceName(resource.getResourceType().name().toLowerCase(), resourceSystemName));
3796         }
3797         // Generate invariant UUID - must be here and not in operation since it
3798
3799         // should stay constant during clone
3800
3801         // TODO
3802         String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
3803         resource.setInvariantUUID(invariantUUID);
3804         return resource;
3805     }
3806
3807     private Either<Boolean, ResponseFormat> validateResourceType(User user, Resource resource, AuditingActionEnum actionEnum) {
3808         Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3809         if (resource.getResourceType() == null) {
3810             log.debug("Invalid resource type for resource");
3811             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
3812             eitherResult = Either.right(errorResponse);
3813             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3814         }
3815         return eitherResult;
3816     }
3817
3818     private Either<Boolean, ResponseFormat> validateLifecycleTypesCreate(User user, Resource resource, AuditingActionEnum actionEnum) {
3819         Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3820         if (resource.getInterfaces() != null && resource.getInterfaces().size() > 0) {
3821             log.debug("validate interface lifecycle Types Exist");
3822             Iterator<InterfaceDefinition> intItr = resource.getInterfaces().values().iterator();
3823             while (intItr.hasNext() && eitherResult.isLeft()) {
3824                 InterfaceDefinition interfaceDefinition = intItr.next();
3825                 String intType = interfaceDefinition.getUniqueId();
3826                 Either<InterfaceDefinition, StorageOperationStatus> eitherCapTypeFound = interfaceTypeOperation.getInterface(intType);
3827                 if (eitherCapTypeFound.isRight()) {
3828                     if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3829                         BeEcompErrorManager.getInstance()
3830                             .logBeGraphObjectMissingError("Create Resource - validateLifecycleTypesCreate", "Interface", intType);
3831                         log.debug("Lifecycle Type: {} is required by resource: {} but does not exist in the DB", intType, resource.getName());
3832                         BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateLifecycleTypesCreate");
3833                         log.debug("request to data model failed with error: {}", eitherCapTypeFound.right().value().name());
3834                     }
3835                     ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_LIFECYCLE_TYPE, intType);
3836                     eitherResult = Either.right(errorResponse);
3837                     componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3838                 }
3839             }
3840         }
3841         return eitherResult;
3842     }
3843
3844     private Either<Boolean, ResponseFormat> validateCapabilityTypesCreate(User user, ICapabilityTypeOperation capabilityTypeOperation,
3845                                                                           Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
3846         Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3847         if (resource.getCapabilities() != null && resource.getCapabilities().size() > 0) {
3848             log.debug("validate capability Types Exist - capabilities section");
3849             for (Entry<String, List<CapabilityDefinition>> typeEntry : resource.getCapabilities().entrySet()) {
3850                 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, actionEnum, eitherResult, typeEntry,
3851                     inTransaction);
3852                 if (eitherResult.isRight()) {
3853                     return Either.right(eitherResult.right().value());
3854                 }
3855             }
3856         }
3857         if (resource.getRequirements() != null && resource.getRequirements().size() > 0) {
3858             log.debug("validate capability Types Exist - requirements section");
3859             for (String type : resource.getRequirements().keySet()) {
3860                 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, resource.getRequirements().get(type), actionEnum,
3861                     eitherResult, type, inTransaction);
3862                 if (eitherResult.isRight()) {
3863                     return Either.right(eitherResult.right().value());
3864                 }
3865             }
3866         }
3867         return eitherResult;
3868     }
3869
3870     // @param typeObject- the object to which the validation is done
3871     private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3872                                                                          Resource resource, List<?> validationObjects, AuditingActionEnum actionEnum,
3873                                                                          Either<Boolean, ResponseFormat> eitherResult, String type,
3874                                                                          boolean inTransaction) {
3875         Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation.getCapabilityType(
3876             UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), type), inTransaction);
3877         if (eitherCapTypeFound.isRight()) {
3878             if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3879                 BeEcompErrorManager.getInstance().logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", type);
3880                 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", type, resource.getName());
3881                 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3882             }
3883             log.debug("Trying to get capability type {} failed with error: {}", type, eitherCapTypeFound.right().value().name());
3884             ResponseFormat errorResponse = null;
3885             if (type != null) {
3886                 errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, type);
3887             } else {
3888                 errorResponse = componentsUtils.getResponseFormatByElement(ActionStatus.MISSING_CAPABILITY_TYPE, validationObjects);
3889             }
3890             eitherResult = Either.right(errorResponse);
3891             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3892         }
3893         return eitherResult;
3894     }
3895
3896     private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3897                                                                          Resource resource, AuditingActionEnum actionEnum,
3898                                                                          Either<Boolean, ResponseFormat> eitherResult,
3899                                                                          Entry<String, List<CapabilityDefinition>> typeEntry, boolean inTransaction) {
3900         Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation
3901             .getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), typeEntry.getKey()), inTransaction);
3902         if (eitherCapTypeFound.isRight()) {
3903             if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3904                 BeEcompErrorManager.getInstance()
3905                     .logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", typeEntry.getKey());
3906                 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", typeEntry.getKey(), resource.getName());
3907                 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3908             }
3909             log.debug("Trying to get capability type {} failed with error: {}", typeEntry.getKey(), eitherCapTypeFound.right().value().name());
3910             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, typeEntry.getKey());
3911             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3912             return Either.right(errorResponse);
3913         }
3914         CapabilityTypeDefinition capabilityTypeDefinition = eitherCapTypeFound.left().value();
3915         if (capabilityTypeDefinition.getProperties() != null) {
3916             for (CapabilityDefinition capDef : typeEntry.getValue()) {
3917                 List<ComponentInstanceProperty> properties = capDef.getProperties();
3918                 List<ComponentInstanceProperty> changedProperties = new ArrayList<>();
3919                 if (properties == null || properties.isEmpty()) {
3920                     for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
3921                         ComponentInstanceProperty newProp = new ComponentInstanceProperty(prop.getValue());
3922                         changedProperties.add(newProp);
3923                     }
3924                 } else {
3925                     List<ComponentInstanceProperty> propsToAdd = new ArrayList<>();
3926                     for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
3927                         PropertyDefinition propFromDef = prop.getValue();
3928                         boolean propFound = false;
3929                         for (ComponentInstanceProperty cip : properties) {
3930                             if (propFromDef.getName().equals(cip.getName())) {
3931                                 //merge property value and property description only, ignore other fields
3932                                 if (cip.getDescription() != null && !cip.getDescription().equals(propFromDef.getDescription())) {
3933                                     propFromDef.setDescription(cip.getDescription());
3934                                 }
3935                                 propertyDataValueMergeBusinessLogic.mergePropertyValue(propFromDef, cip, new ArrayList<>());
3936                                 if (cip.getValue() != null) {
3937                                     propFromDef.setValue(cip.getValue());
3938                                 }
3939                                 propsToAdd.add(new ComponentInstanceProperty(propFromDef));
3940                                 propFound = true;
3941                                 properties.remove(cip);
3942                                 break;
3943                             }
3944                         }
3945                         if (!propFound) {
3946                             propsToAdd.add(new ComponentInstanceProperty(propFromDef));
3947                         }
3948                     }
3949                     if (!propsToAdd.isEmpty()) {
3950                         changedProperties.addAll(propsToAdd);
3951                     }
3952                 }
3953                 capDef.setProperties(changedProperties);
3954             }
3955         }
3956         return eitherResult;
3957     }
3958
3959     public Resource createResourceByDao(Resource resource, User user, AuditingActionEnum actionEnum, boolean isNormative, boolean inTransaction) {
3960         // create resource
3961
3962         // lock new resource name in order to avoid creation resource with same
3963
3964         // name
3965         Resource createdResource = null;
3966         if (!inTransaction) {
3967             Either<Boolean, ResponseFormat> lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE);
3968             if (lockResult.isRight()) {
3969                 ResponseFormat responseFormat = lockResult.right().value();
3970                 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3971                 throw new ByResponseFormatComponentException(responseFormat);
3972             }
3973             log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult);
3974         }
3975         try {
3976             if (resource.deriveFromGeneric()) {
3977                 handleResourceGenericType(resource);
3978             }
3979             createdResource = createResourceTransaction(resource, user, isNormative);
3980             componentsUtils.auditResource(componentsUtils.getResponseFormat(ActionStatus.CREATED), user, createdResource, actionEnum);
3981             ASDCKpiApi.countCreatedResourcesKPI();
3982         } catch (ComponentException e) {
3983             ResponseFormat responseFormat =
3984                 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
3985             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3986             throw e;
3987         } catch (StorageException e) {
3988             ResponseFormat responseFormat = componentsUtils
3989                 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
3990             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3991             throw e;
3992         } finally {
3993             if (!inTransaction) {
3994                 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
3995             }
3996         }
3997         return createdResource;
3998     }
3999
4000     private Resource createResourceTransaction(Resource resource, User user, boolean isNormative) {
4001         final String resourceName = resource.getName();
4002         final String modelName = resource.getModel();
4003         final ResourceTypeEnum resourceType = resource.getResourceType();
4004         final ComponentTypeEnum componentType = resource.getComponentType();
4005         final Either<Boolean, StorageOperationStatus> eitherValidation = toscaOperationFacade
4006             .validateComponentNameAndModelExists(resourceName, modelName, resourceType, componentType);
4007         if (eitherValidation.isRight()) {
4008             loggerSupportability.log(LoggerSupportabilityActions.VALIDATE_NAME, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4009                 "ERROR while validate component name {} Status is: {}", resource.getName(), eitherValidation.right().value());
4010             log.debug("Failed to validate component name {}. Status is {}. ", resource.getName(), eitherValidation.right().value());
4011             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(eitherValidation.right().value()));
4012         }
4013         if (eitherValidation.left().value()) {
4014             log.debug("resource with name: {}, already exists", resource.getName());
4015             loggerSupportability
4016                 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4017                     "resource with name: {} already exists", resource.getName());
4018             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4019                 resource.getName());
4020         }
4021         log.debug("send resource {} to dao for create", resource.getName());
4022         createArtifactsPlaceHolderData(resource, user);
4023         // enrich object
4024         if (!isNormative) {
4025             log.debug("enrich resource with creator, version and state");
4026             resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
4027             resource.setVersion(INITIAL_VERSION);
4028             resource.setHighestVersion(true);
4029             if (resource.getResourceType() != null && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4030                 resource.setAbstract(false);
4031             }
4032         }
4033         return toscaOperationFacade.createToscaComponent(resource).left().on(r -> throwComponentExceptionByResource(r, resource));
4034     }
4035
4036     private Resource throwComponentExceptionByResource(StorageOperationStatus status, Resource resource) {
4037         ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(status), resource);
4038         throw new ByResponseFormatComponentException(responseFormat);
4039     }
4040
4041     private void createArtifactsPlaceHolderData(Resource resource, User user) {
4042         // create mandatory artifacts
4043
4044         // TODO it must be removed after that artifact uniqueId creation will be
4045
4046         // moved to ArtifactOperation
4047         setInformationalArtifactsPlaceHolder(resource, user);
4048         setDeploymentArtifactsPlaceHolder(resource, user);
4049         setToscaArtifactsPlaceHolders(resource, user);
4050     }
4051
4052     @SuppressWarnings("unchecked")
4053     @Override
4054     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
4055         Resource resource = (Resource) component;
4056         Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
4057         if (artifactMap == null) {
4058             artifactMap = new HashMap<>();
4059         }
4060         Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4061             .getDeploymentResourceArtifacts();
4062         if (deploymentResourceArtifacts != null) {
4063             Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
4064             deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
4065         }
4066         resource.setDeploymentArtifacts(artifactMap);
4067     }
4068
4069     private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
4070         Map<String, Object> artifactDetails = (Map<String, Object>) v;
4071         Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
4072         if (object != null) {
4073             List<String> artifactTypes = (List<String>) object;
4074             if (!artifactTypes.contains(resource.getResourceType().name())) {
4075                 return;
4076             }
4077         } else {
4078             log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
4079         }
4080         if (artifactsBusinessLogic != null) {
4081             ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4082                 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
4083             if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
4084                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4085             }
4086         }
4087     }
4088
4089     @SuppressWarnings("unchecked")
4090     private void setInformationalArtifactsPlaceHolder(Resource resource, User user) {
4091         Map<String, ArtifactDefinition> artifactMap = resource.getArtifacts();
4092         if (artifactMap == null) {
4093             artifactMap = new HashMap<>();
4094         }
4095         String resourceUniqueId = resource.getUniqueId();
4096         List<String> exludeResourceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceCategory();
4097         List<String> exludeResourceType = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceType();
4098         Map<String, Object> informationalResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4099             .getInformationalResourceArtifacts();
4100         List<CategoryDefinition> categories = resource.getCategories();
4101         boolean isCreateArtifact = true;
4102         if (exludeResourceCategory != null) {
4103             String category = categories.get(0).getName();
4104             isCreateArtifact = exludeResourceCategory.stream().noneMatch(e -> e.equalsIgnoreCase(category));
4105         }
4106         if (isCreateArtifact && exludeResourceType != null) {
4107             String resourceType = resource.getResourceType().name();
4108             isCreateArtifact = exludeResourceType.stream().noneMatch(e -> e.equalsIgnoreCase(resourceType));
4109         }
4110         if (informationalResourceArtifacts != null && isCreateArtifact) {
4111             Set<String> keys = informationalResourceArtifacts.keySet();
4112             for (String informationalResourceArtifactName : keys) {
4113                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalResourceArtifacts.get(informationalResourceArtifactName);
4114                 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4115                     .createArtifactPlaceHolderInfo(resourceUniqueId, informationalResourceArtifactName, artifactInfoMap, user,
4116                         ArtifactGroupTypeEnum.INFORMATIONAL);
4117                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4118             }
4119         }
4120         resource.setArtifacts(artifactMap);
4121     }
4122
4123     /**
4124      * deleteResource
4125      *
4126      * @param resourceId
4127      * @param user
4128      * @return
4129      */
4130     public ResponseFormat deleteResource(String resourceId, User user) {
4131         ResponseFormat responseFormat;
4132         validateUserExists(user);
4133         Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4134         if (resourceStatus.isRight()) {
4135             log.debug("failed to get resource {}", resourceId);
4136             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), "");
4137         }
4138         Resource resource = resourceStatus.left().value();
4139         StorageOperationStatus result = StorageOperationStatus.OK;
4140         lockComponent(resourceId, resource, "Mark resource to delete");
4141         try {
4142             result = markComponentToDelete(resource);
4143             if (result == StorageOperationStatus.OK) {
4144                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4145             } else {
4146                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4147                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4148             }
4149             return responseFormat;
4150         } finally {
4151             if (!StorageOperationStatus.OK.equals(result)) {
4152                 janusGraphDao.rollback();
4153             } else {
4154                 janusGraphDao.commit();
4155             }
4156             graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
4157         }
4158     }
4159
4160     private boolean isComponentSystemDeployed(Resource resource) {
4161         return resource.getComponentMetadataDefinition().getMetadataDataDefinition().isNormative();
4162     }
4163
4164     /**
4165      * Deletes every version of the provided resource
4166      *
4167      * @param resourceId the resource identifier
4168      * @param user       the user that performs the deletion
4169      * @return
4170      * @throws ComponentException if there is any error in the deletion of the resource operation
4171      */
4172     public void deleteResourceAllVersions(String resourceId, User user) {
4173         validateUserExists(user);
4174         Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4175         if (resourceStatus.isRight()) {
4176             log.debug("Failed to get resource {}", resourceId);
4177             componentException(resourceStatus.right().value());
4178         }
4179         Resource resource = resourceStatus.left().value();
4180         if (isComponentSystemDeployed(resource)) {
4181             throw new ByActionStatusComponentException(ActionStatus.CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES, ComponentTypeEnum.RESOURCE.getValue(),
4182                 resource.getName());
4183         }
4184         if (Boolean.FALSE.equals(resource.isArchived())) {
4185             log.debug("The resource, {}, requested for delete has not been archived.", resourceId);
4186             throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, resourceId);
4187         }
4188         try {
4189             String model = resource.getModel();
4190             final Optional<Model> modelOptional = modelOperation.findModelByName(model);
4191             List<String> deletedResourceList = toscaOperationFacade.deleteComponent(resource.getInvariantUUID(), NodeTypeEnum.Resource, true);
4192             if (log.isDebugEnabled()) {
4193                 deletedResourceList.forEach(deletedR -> log.debug("Component {} was deleted.", deletedR));
4194             }
4195             if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
4196                 modelOperation.deleteModel(modelOptional.get(), true);
4197             }
4198             toscaOperationFacade.commitAndCheck(resource.getUniqueId());
4199             updateCatalog(resource, ChangeTypeEnum.DELETE);
4200         } catch (ComponentException exception) {
4201             log.debug("Failed to delete resource, {} ", resourceId);
4202             janusGraphDao.rollback();
4203             throw exception;
4204         }
4205     }
4206
4207     public ResponseFormat deleteResourceByNameAndVersion(String resourceName, String version, User user) {
4208         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4209         validateUserExists(user);
4210         Resource resource = null;
4211         StorageOperationStatus result = StorageOperationStatus.OK;
4212         boolean failed = false;
4213         try {
4214             Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade
4215                 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, version);
4216             if (resourceStatus.isRight()) {
4217                 log.debug("failed to get resource {} version {}", resourceName, version);
4218                 return componentsUtils
4219                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), resourceName);
4220             }
4221             resource = resourceStatus.left().value();
4222         } finally {
4223             janusGraphDao.commit();
4224         }
4225         if (resource != null) {
4226             lockComponent(resource.getUniqueId(), resource, DELETE_RESOURCE);
4227             try {
4228                 result = markComponentToDelete(resource);
4229                 if (result != StorageOperationStatus.OK) {
4230                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4231                     responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4232                     return responseFormat;
4233                 }
4234             } catch (ComponentException e) {
4235                 failed = true;
4236                 throw e;
4237             } finally {
4238                 if (failed || !StorageOperationStatus.OK.equals(result)) {
4239                     janusGraphDao.rollback();
4240                 } else {
4241                     janusGraphDao.commit();
4242                 }
4243                 graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource);
4244             }
4245         }
4246         return responseFormat;
4247     }
4248
4249     public Either<Resource, ResponseFormat> getResource(String resourceId, User user) {
4250         if (user != null) {
4251             validateUserExists(user);
4252         }
4253         Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceId);
4254         if (storageStatus.isRight()) {
4255             log.debug("failed to get resource by id {}", resourceId);
4256             return Either.right(
4257                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), resourceId));
4258         }
4259         if (storageStatus.left().value() == null) {
4260             return Either.right(componentsUtils
4261                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), resourceId));
4262         }
4263         return Either.left(storageStatus.left().value());
4264     }
4265
4266     public Either<Resource, ResponseFormat> getResourceByNameAndVersion(String resourceName, String resourceVersion, String userId) {
4267         validateUserExists(userId);
4268         Either<Resource, StorageOperationStatus> getResource = toscaOperationFacade
4269             .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion);
4270         if (getResource.isRight()) {
4271             log.debug("failed to get resource by name {} and version {}", resourceName, resourceVersion);
4272             return Either.right(
4273                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResource.right().value()), resourceName));
4274         }
4275         return Either.left(getResource.left().value());
4276     }
4277
4278     /**
4279      * updateResourceMetadata
4280      *
4281      * @param user               - modifier data (userId)
4282      * @param inTransaction      TODO
4283      * @param resourceIdToUpdate - the resource identifier
4284      * @param newResource
4285      * @return Either<Resource, responseFormat>
4286      */
4287     public Resource updateResourceMetadata(String resourceIdToUpdate, Resource newResource, Resource currentResource, User user,
4288                                            boolean inTransaction) {
4289         validateUserExists(user.getUserId());
4290         log.debug("Get resource with id {}", resourceIdToUpdate);
4291         boolean needToUnlock = false;
4292         try {
4293             if (currentResource == null) {
4294                 Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceIdToUpdate);
4295                 if (storageStatus.isRight()) {
4296                     throw new ByResponseFormatComponentException(
4297                         componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), ""));
4298                 }
4299                 currentResource = storageStatus.left().value();
4300             }
4301             // verify that resource is checked-out and the user is the last
4302
4303             // updater
4304             if (!ComponentValidationUtils.canWorkOnResource(currentResource, user.getUserId())) {
4305                 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
4306             }
4307             // lock resource
4308             StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4309             if (lockResult != StorageOperationStatus.OK) {
4310                 BeEcompErrorManager.getInstance()
4311                     .logBeFailedLockObjectError("Upload Artifact - lock ", NodeTypeEnum.Resource.getName(), resourceIdToUpdate);
4312                 log.debug("Failed to lock resource: {}, error - {}", resourceIdToUpdate, lockResult);
4313                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult));
4314                 throw new ByResponseFormatComponentException(responseFormat);
4315             }
4316             needToUnlock = true;
4317             // critical section starts here
4318
4319             // convert json to object
4320
4321             // Update and updated resource must have a non-empty "derivedFrom"
4322
4323             // list
4324
4325             // This code is not called from import resources, because of root
4326
4327             // VF "derivedFrom" should be null (or ignored)
4328             if (ModelConverter.isAtomicComponent(currentResource)) {
4329                 validateDerivedFromNotEmpty(null, newResource, null);
4330                 validateDerivedFromNotEmpty(null, currentResource, null);
4331             } else {
4332                 newResource.setDerivedFrom(null);
4333             }
4334             Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource, false,
4335                 true);
4336             if (dataModelResponse.isRight()) {
4337                 log.debug("failed to update resource metadata!!!");
4338                 throw new ByResponseFormatComponentException(dataModelResponse.right().value());
4339             }
4340             log.debug("Resource metadata updated successfully!!!");
4341             return dataModelResponse.left().value();
4342         } catch (ComponentException | StorageException e) {
4343             rollback(inTransaction, newResource, null, null);
4344             throw e;
4345         } finally {
4346             if (!inTransaction) {
4347                 janusGraphDao.commit();
4348             }
4349             if (needToUnlock) {
4350                 graphLockOperation.unlockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4351             }
4352         }
4353     }
4354
4355     private Either<Resource, ResponseFormat> updateResourceMetadata(String resourceIdToUpdate, Resource newResource, User user,
4356                                                                     Resource currentResource, boolean shouldLock, boolean inTransaction) {
4357         updateVfModuleGroupsNames(currentResource, newResource);
4358         validateResourceFieldsBeforeUpdate(currentResource, newResource, inTransaction, false);
4359         // Setting last updater and uniqueId
4360         newResource.setContactId(newResource.getContactId().toLowerCase());
4361         newResource.setLastUpdaterUserId(user.getUserId());
4362         newResource.setUniqueId(resourceIdToUpdate);
4363         // Cannot set highest version through UI
4364         newResource.setHighestVersion(currentResource.isHighestVersion());
4365         newResource.setCreationDate(currentResource.getCreationDate());
4366         Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom = processUpdateOfDerivedFrom(currentResource, newResource, user.getUserId(),
4367             inTransaction);
4368         if (processUpdateOfDerivedFrom.isRight()) {
4369             log.debug("Couldn't update derived from for resource {}", resourceIdToUpdate);
4370             return Either.right(processUpdateOfDerivedFrom.right().value());
4371         }
4372         log.debug("send resource {} to dao for update", newResource.getUniqueId());
4373         if (isNotEmpty(newResource.getGroups())) {
4374             for (GroupDefinition group : newResource.getGroups()) {
4375                 if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
4376                     groupBusinessLogic
4377                         .validateAndUpdateGroupMetadata(newResource.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId(), user,
4378                             newResource.getComponentType(), group, true, false);
4379                 }
4380             }
4381         }
4382         Either<Resource, StorageOperationStatus> dataModelResponse = toscaOperationFacade.updateToscaElement(newResource);
4383         if (dataModelResponse.isRight()) {
4384             ResponseFormat responseFormat = componentsUtils
4385                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), newResource);
4386             return Either.right(responseFormat);
4387         } else if (dataModelResponse.left().value() == null) {
4388             log.debug("No response from updateResource");
4389             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
4390         }
4391         return Either.left(dataModelResponse.left().value());
4392     }
4393
4394     private void updateVfModuleGroupsNames(Resource currentResource, Resource newResource) {
4395         if (currentResource.getGroups() != null && !currentResource.getName().equals(newResource.getName())) {
4396             List<GroupDefinition> updatedGroups = currentResource.getGroups().stream()
4397                 .map(group -> getUpdatedGroup(group, currentResource.getName(), newResource.getName())).collect(toList());
4398             newResource.setGroups(updatedGroups);
4399         }
4400     }
4401
4402     private GroupDefinition getUpdatedGroup(GroupDefinition currGroup, String replacePattern, String with) {
4403         GroupDefinition updatedGroup = new GroupDefinition(currGroup);
4404         if (updatedGroup.isSamePrefix(replacePattern) && updatedGroup.getType().equals(DEFAULT_GROUP_VF_MODULE)) {
4405             String prefix = updatedGroup.getName().substring(0, replacePattern.length());
4406             String newGroupName = updatedGroup.getName().replaceFirst(prefix, with);
4407             updatedGroup.setName(newGroupName);
4408         }
4409         return updatedGroup;
4410     }
4411
4412     /**
4413      * validateResourceFieldsBeforeCreate
4414      *
4415      * @param user - modifier data (userId)
4416      */
4417     private void validateResourceFieldsBeforeCreate(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4418         componentValidator.validate(user, resource, actionEnum);
4419         // validate category
4420         log.debug("validate category");
4421         validateCategory(user, resource, actionEnum, inTransaction);
4422         // validate vendor name & release & model number
4423         log.debug("validate vendor name");
4424         validateVendorName(user, resource, actionEnum);
4425         log.debug("validate vendor release");
4426         validateVendorReleaseName(user, resource, actionEnum);
4427         log.debug("validate resource vendor model number");
4428         validateResourceVendorModelNumber(user, resource, actionEnum);
4429         // validate cost
4430         log.debug("validate cost");
4431         validateCost(resource);
4432         // validate licenseType
4433         log.debug("validate licenseType");
4434         validateLicenseType(user, resource, actionEnum);
4435         // validate template (derived from)
4436         log.debug("validate derived from");
4437         if (!ModelConverter.isAtomicComponent(resource) && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4438             resource.setDerivedFrom(null);
4439         }
4440         validateDerivedFromExist(user, resource, actionEnum);
4441         // warn about non-updatable fields
4442         checkComponentFieldsForOverrideAttempt(resource);
4443         String currentCreatorFullName = resource.getCreatorFullName();
4444         if (currentCreatorFullName != null) {
4445             log.debug("Resource Creator fullname is automatically set and cannot be updated");
4446         }
4447         String currentLastUpdaterFullName = resource.getLastUpdaterFullName();
4448         if (currentLastUpdaterFullName != null) {
4449             log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4450         }
4451         Long currentLastUpdateDate = resource.getLastUpdateDate();
4452         if (currentLastUpdateDate != null) {
4453             log.debug("Resource last update date is automatically set and cannot be updated");
4454         }
4455         Boolean currentAbstract = resource.isAbstract();
4456         if (currentAbstract != null) {
4457             log.debug("Resource abstract is automatically set and cannot be updated");
4458         }
4459     }
4460
4461     /**
4462      * validateResourceFieldsBeforeUpdate
4463      *
4464      * @param currentResource - Resource object to validate
4465      * @param isNested
4466      */
4467     private void validateResourceFieldsBeforeUpdate(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4468         validateFields(currentResource, updateInfoResource, inTransaction, isNested);
4469         warnNonEditableFields(currentResource, updateInfoResource);
4470     }
4471
4472     private void warnNonEditableFields(Resource currentResource, Resource updateInfoResource) {
4473         String currentResourceVersion = currentResource.getVersion();
4474         String updatedResourceVersion = updateInfoResource.getVersion();
4475         if ((updatedResourceVersion != null) && (!updatedResourceVersion.equals(currentResourceVersion))) {
4476             log.debug("Resource version is automatically set and cannot be updated");
4477         }
4478         String currentCreatorUserId = currentResource.getCreatorUserId();
4479         String updatedCreatorUserId = updateInfoResource.getCreatorUserId();
4480         if ((updatedCreatorUserId != null) && (!updatedCreatorUserId.equals(currentCreatorUserId))) {
4481             log.debug("Resource Creator UserId is automatically set and cannot be updated");
4482         }
4483         String currentCreatorFullName = currentResource.getCreatorFullName();
4484         String updatedCreatorFullName = updateInfoResource.getCreatorFullName();
4485         if ((updatedCreatorFullName != null) && (!updatedCreatorFullName.equals(currentCreatorFullName))) {
4486             log.debug("Resource Creator fullname is automatically set and cannot be updated");
4487         }
4488         String currentLastUpdaterUserId = currentResource.getLastUpdaterUserId();
4489         String updatedLastUpdaterUserId = updateInfoResource.getLastUpdaterUserId();
4490         if ((updatedLastUpdaterUserId != null) && (!updatedLastUpdaterUserId.equals(currentLastUpdaterUserId))) {
4491             log.debug("Resource LastUpdater userId is automatically set and cannot be updated");
4492         }
4493         String currentLastUpdaterFullName = currentResource.getLastUpdaterFullName();
4494         String updatedLastUpdaterFullName = updateInfoResource.getLastUpdaterFullName();
4495         if ((updatedLastUpdaterFullName != null) && (!updatedLastUpdaterFullName.equals(currentLastUpdaterFullName))) {
4496             log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4497         }
4498         Long currentCreationDate = currentResource.getCreationDate();
4499         Long updatedCreationDate = updateInfoResource.getCreationDate();
4500         if ((updatedCreationDate != null) && (!updatedCreationDate.equals(currentCreationDate))) {
4501             log.debug("Resource Creation date is automatically set and cannot be updated");
4502         }
4503         Long currentLastUpdateDate = currentResource.getLastUpdateDate();
4504         Long updatedLastUpdateDate = updateInfoResource.getLastUpdateDate();
4505         if ((updatedLastUpdateDate != null) && (!updatedLastUpdateDate.equals(currentLastUpdateDate))) {
4506             log.debug("Resource last update date is automatically set and cannot be updated");
4507         }
4508         LifecycleStateEnum currentLifecycleState = currentResource.getLifecycleState();
4509         LifecycleStateEnum updatedLifecycleState = updateInfoResource.getLifecycleState();
4510         if ((updatedLifecycleState != null) && (!updatedLifecycleState.equals(currentLifecycleState))) {
4511             log.debug("Resource lifecycle state date is automatically set and cannot be updated");
4512         }
4513         Boolean currentAbstract = currentResource.isAbstract();
4514         Boolean updatedAbstract = updateInfoResource.isAbstract();
4515         if ((updatedAbstract != null) && (!updatedAbstract.equals(currentAbstract))) {
4516             log.debug("Resource abstract is automatically set and cannot be updated");
4517         }
4518         Boolean currentHighestVersion = currentResource.isHighestVersion();
4519         Boolean updatedHighestVersion = updateInfoResource.isHighestVersion();
4520         if ((updatedHighestVersion != null) && (!updatedHighestVersion.equals(currentHighestVersion))) {
4521             log.debug("Resource highest version is automatically set and cannot be updated");
4522         }
4523         String currentUuid = currentResource.getUUID();
4524         String updatedUuid = updateInfoResource.getUUID();
4525         if ((updatedUuid != null) && (!updatedUuid.equals(currentUuid))) {
4526             log.debug("Resource UUID is automatically set and cannot be updated");
4527         }
4528         log.debug("Resource Type  cannot be updated");
4529         String currentInvariantUuid = currentResource.getInvariantUUID();
4530         String updatedInvariantUuid = updateInfoResource.getInvariantUUID();
4531         if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
4532             log.debug("Resource invariant UUID is automatically set and cannot be updated");
4533             updateInfoResource.setInvariantUUID(currentInvariantUuid);
4534         }
4535     }
4536
4537     private void validateFields(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4538         boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentResource.getVersion());
4539         log.debug("validate resource name before update");
4540         validateResourceName(currentResource, updateInfoResource, hasBeenCertified, isNested);
4541         log.debug("validate description before update");
4542         componentDescriptionValidator.validateAndCorrectField(null, updateInfoResource, null);
4543         log.debug("validate icon before update");
4544         validateIcon(currentResource, updateInfoResource, hasBeenCertified);
4545         log.debug("validate tags before update");
4546         componentTagsValidator.validateAndCorrectField(null, updateInfoResource, null);
4547         log.debug("validate vendor name before update");
4548         validateVendorName(null, updateInfoResource, null);
4549         log.debug("validate resource vendor model number before update");
4550         validateResourceVendorModelNumber(currentResource, updateInfoResource);
4551         log.debug("validate vendor release before update");
4552         validateVendorReleaseName(null, updateInfoResource, null);
4553         log.debug("validate contact info before update");
4554         componentContactIdValidator.validateAndCorrectField(null, updateInfoResource, null);
4555         log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
4556         validateDerivedFromDuringUpdate(currentResource, updateInfoResource, hasBeenCertified);
4557         log.debug("validate category before update");
4558         validateCategory(currentResource, updateInfoResource, hasBeenCertified, inTransaction);
4559     }
4560
4561     private boolean isResourceNameEquals(Resource currentResource, Resource updateInfoResource) {
4562         String resourceNameUpdated = updateInfoResource.getName();
4563         String resourceNameCurrent = currentResource.getName();
4564         if (resourceNameCurrent.equals(resourceNameUpdated)) {
4565             return true;
4566         }
4567         // In case of CVFC type we should support the case of old VF with CVFC
4568
4569         // instances that were created without the "Cvfc" suffix
4570         return currentResource.getResourceType() == ResourceTypeEnum.CVFC && resourceNameUpdated
4571             .equals(addCvfcSuffixToResourceName(resourceNameCurrent));
4572     }
4573
4574     private String addCvfcSuffixToResourceName(String resourceName) {
4575         return resourceName + "Cvfc";
4576     }
4577
4578     private void validateResourceName(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified, boolean isNested) {
4579         String resourceNameUpdated = updateInfoResource.getName();
4580         if (!isResourceNameEquals(currentResource, updateInfoResource)) {
4581             if (isNested || !hasBeenCertified) {
4582                 componentNameValidator.validateAndCorrectField(null, updateInfoResource, null);
4583                 validateResourceNameUniqueness(updateInfoResource);
4584                 currentResource.setName(resourceNameUpdated);
4585                 currentResource.setNormalizedName(ValidationUtils.normaliseComponentName(resourceNameUpdated));
4586                 currentResource.setSystemName(ValidationUtils.convertToSystemName(resourceNameUpdated));
4587             } else {
4588                 log.info("Resource name: {}, cannot be updated once the resource has been certified once.", resourceNameUpdated);
4589                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NAME_CANNOT_BE_CHANGED);
4590             }
4591         }
4592     }
4593
4594     private void validateIcon(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) {
4595         String iconUpdated = updateInfoResource.getIcon();
4596         String iconCurrent = currentResource.getIcon();
4597         if (!iconCurrent.equals(iconUpdated)) {
4598             if (!hasBeenCertified) {
4599                 componentIconValidator.validateAndCorrectField(null, updateInfoResource, null);
4600             } else {
4601                 log.info("Icon {} cannot be updated once the resource has been certified once.", iconUpdated);
4602                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_ICON_CANNOT_BE_CHANGED);
4603             }
4604         }
4605     }
4606
4607     private void validateResourceVendorModelNumber(Resource currentResource, Resource updateInfoResource) {
4608         String updatedResourceVendorModelNumber = updateInfoResource.getResourceVendorModelNumber();
4609         String currentResourceVendorModelNumber = currentResource.getResourceVendorModelNumber();
4610         if (!currentResourceVendorModelNumber.equals(updatedResourceVendorModelNumber)) {
4611             validateResourceVendorModelNumber(null, updateInfoResource, null);
4612         }
4613     }
4614
4615     private Either<Boolean, ResponseFormat> validateCategory(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified,
4616                                                              boolean inTransaction) {
4617         validateCategory(null, updateInfoResource, null, inTransaction);
4618         if (hasBeenCertified) {
4619             CategoryDefinition currentCategory = currentResource.getCategories().get(0);
4620             SubCategoryDefinition currentSubCategory = currentCategory.getSubcategories().get(0);
4621             CategoryDefinition updateCategory = updateInfoResource.getCategories().get(0);
4622             SubCategoryDefinition updtaeSubCategory = updateCategory.getSubcategories().get(0);
4623             if (!currentCategory.getName().equals(updateCategory.getName()) || !currentSubCategory.getName().equals(updtaeSubCategory.getName())) {
4624                 log.info("Category {} cannot be updated once the resource has been certified once.", currentResource.getCategories());
4625                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CATEGORY_CANNOT_BE_CHANGED);
4626                 return Either.right(errorResponse);
4627             }
4628         }
4629         return Either.left(true);
4630     }
4631
4632     private Either<Boolean, ResponseFormat> validateDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4633                                                                             boolean hasBeenCertified) {
4634         List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4635         List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4636         if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4637             log.trace("Update normative types");
4638             return Either.left(true);
4639         }
4640         String derivedFromCurrent = currentDerivedFrom.get(0);
4641         String derivedFromUpdated = updatedDerivedFrom.get(0);
4642         if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4643             if (!hasBeenCertified) {
4644                 validateDerivedFromExist(null, updateInfoResource, null);
4645             } else {
4646                 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4647                     null);
4648                 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4649                     log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4650                     return validateDerivedFromExtending;
4651                 }
4652             }
4653         } else {
4654             // For derived from, we must know whether it was actually changed,
4655
4656             // otherwise we must do no action.
4657
4658             // Due to changes it inflicts on data model (remove artifacts,
4659
4660             // properties...), it's not like a flat field which can be
4661
4662             // overwritten if not changed.
4663
4664             // So we must indicate that derived from is not changed
4665             updateInfoResource.setDerivedFrom(null);
4666         }
4667         return Either.left(true);
4668     }
4669
4670     private Either<Boolean, ResponseFormat> validateNestedDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4671                                                                                   boolean hasBeenCertified) {
4672         List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4673         List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4674         if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4675             log.trace("Update normative types");
4676             return Either.left(true);
4677         }
4678         String derivedFromCurrent = currentDerivedFrom.get(0);
4679         String derivedFromUpdated = updatedDerivedFrom.get(0);
4680         if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4681             if (!hasBeenCertified) {
4682                 validateDerivedFromExist(null, updateInfoResource, null);
4683             } else {
4684                 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4685                     null);
4686                 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4687                     log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4688                     return validateDerivedFromExtending;
4689                 }
4690             }
4691         }
4692         return Either.left(true);
4693     }
4694
4695     private void validateDerivedFromExist(User user, Resource resource, AuditingActionEnum actionEnum) {
4696         if (resource.getDerivedFrom() == null || resource.getDerivedFrom().isEmpty()) {
4697             return;
4698         }
4699         String templateName = resource.getDerivedFrom().get(0);
4700         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateToscaResourceNameExists(templateName);
4701         if (dataModelResponse.isRight()) {
4702             StorageOperationStatus storageStatus = dataModelResponse.right().value();
4703             BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateDerivedFromExist");
4704             log.debug("request to data model failed with error: {}", storageStatus);
4705             ResponseFormat responseFormat = componentsUtils
4706                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), resource);
4707             log.trace("audit before sending response");
4708             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4709             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageStatus));
4710         } else if (!dataModelResponse.left().value()) {
4711             log.info("resource template with name: {}, does not exists", templateName);
4712             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4713             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4714             throw new ByActionStatusComponentException(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4715         }
4716     }
4717
4718     // Tal G for extending inheritance US815447
4719     private Either<Boolean, ResponseFormat> validateDerivedFromExtending(User user, Resource currentResource, Resource updateInfoResource,
4720                                                                          AuditingActionEnum actionEnum) {
4721         String currentTemplateName = currentResource.getDerivedFrom().get(0);
4722         String updatedTemplateName = updateInfoResource.getDerivedFrom().get(0);
4723         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
4724             .validateToscaResourceNameExtends(currentTemplateName, updatedTemplateName, currentResource.getModel());
4725         if (dataModelResponse.isRight()) {
4726             StorageOperationStatus storageStatus = dataModelResponse.right().value();
4727             BeEcompErrorManager.getInstance().logBeDaoSystemError("Create/Update Resource - validateDerivingFromExtendingType");
4728             ResponseFormat responseFormat = componentsUtils
4729                 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), currentResource);
4730             log.trace("audit before sending response");
4731             componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4732             return Either.right(responseFormat);
4733         }
4734         if (!dataModelResponse.left().value()) {
4735             log.info("resource template with name {} does not inherit as original {}", updatedTemplateName, currentTemplateName);
4736             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_DOES_NOT_EXTEND);
4737             componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4738             return Either.right(responseFormat);
4739         }
4740         return Either.left(true);
4741     }
4742
4743     public void validateDerivedFromNotEmpty(User user, Resource resource, AuditingActionEnum actionEnum) {
4744         log.debug("validate resource derivedFrom field");
4745         if ((resource.getDerivedFrom() == null) || (resource.getDerivedFrom().isEmpty()) || (resource.getDerivedFrom().get(0)) == null || (resource
4746             .getDerivedFrom().get(0).trim().isEmpty())) {
4747             log.info("derived from (template) field is missing for the resource");
4748             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4749             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4750             throw new ByActionStatusComponentException(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4751         }
4752     }
4753
4754     private void validateResourceNameUniqueness(Resource resource) {
4755         Either<Boolean, StorageOperationStatus> resourceOperationResponse = toscaOperationFacade
4756             .validateComponentNameExists(resource.getName(), resource.getResourceType(), resource.getComponentType());
4757         if (resourceOperationResponse.isLeft() && resourceOperationResponse.left().value()) {
4758             log.debug("resource with name: {}, already exists", resource.getName());
4759             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4760                 resource.getName());
4761         } else if (resourceOperationResponse.isRight()) {
4762             log.debug("error while validateResourceNameExists for resource: {}", resource.getName());
4763             throw new StorageException(resourceOperationResponse.right().value());
4764         }
4765     }
4766
4767     private void validateCategory(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4768         List<CategoryDefinition> categories = resource.getCategories();
4769         if (CollectionUtils.isEmpty(categories)) {
4770             log.debug(CATEGORY_IS_EMPTY);
4771             ResponseFormat responseFormat = componentsUtils
4772                 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4773             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4774             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4775         }
4776         if (categories.size() > 1) {
4777             log.debug("Must be only one category for resource");
4778             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.RESOURCE.getValue());
4779         }
4780         CategoryDefinition category = categories.get(0);
4781         List<SubCategoryDefinition> subcategories = category.getSubcategories();
4782         if (CollectionUtils.isEmpty(subcategories)) {
4783             log.debug("Missinig subcategory for resource");
4784             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY);
4785         }
4786         if (subcategories.size() > 1) {
4787             log.debug("Must be only one sub category for resource");
4788             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_TOO_MUCH_SUBCATEGORIES);
4789         }
4790         SubCategoryDefinition subcategory = subcategories.get(0);
4791         if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
4792             log.debug(CATEGORY_IS_EMPTY);
4793             ResponseFormat responseFormat = componentsUtils
4794                 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4795             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4796             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4797         }
4798         if (!ValidationUtils.validateStringNotEmpty(subcategory.getName())) {
4799             log.debug(CATEGORY_IS_EMPTY);
4800             ResponseFormat responseFormat = componentsUtils
4801                 .getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4802             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4803             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4804         }
4805         validateCategoryListed(category, subcategory, user, resource, actionEnum, inTransaction);
4806     }
4807
4808     private void validateCategoryListed(CategoryDefinition category, SubCategoryDefinition subcategory, User user, Resource resource,
4809                                         AuditingActionEnum actionEnum, boolean inTransaction) {
4810         ResponseFormat responseFormat;
4811         if (category != null && subcategory != null) {
4812             log.debug("validating resource category {} against valid categories list", category);
4813             Either<List<CategoryDefinition>, ActionStatus> categories = elementDao.getAllCategories(NodeTypeEnum.ResourceNewCategory, inTransaction);
4814             if (categories.isRight()) {
4815                 log.debug("failed to retrieve resource categories from JanusGraph");
4816                 responseFormat = componentsUtils.getResponseFormat(categories.right().value());
4817                 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4818                 throw new ByActionStatusComponentException(categories.right().value());
4819             }
4820             List<CategoryDefinition> categoryList = categories.left().value();
4821             Optional<CategoryDefinition> foundCategory = categoryList.stream().filter(cat -> cat.getName().equals(category.getName())).findFirst();
4822             if (foundCategory.isEmpty()) {
4823                 log.debug("Category {} is not part of resource category group. Resource category valid values are {}", category, categoryList);
4824                 failOnInvalidCategory(user, resource, actionEnum);
4825                 return; // explisite output even if failOnInvalidCategory throw an exception
4826             }
4827             Optional<SubCategoryDefinition> foundSubcategory = foundCategory.get().getSubcategories().stream()
4828                 .filter(subcat -> subcat.getName().equals(subcategory.getName())).findFirst();
4829             if (foundSubcategory.isEmpty()) {
4830                 log.debug("SubCategory {} is not part of resource category group. Resource subcategory valid values are {}", subcategory,
4831                     foundCategory.get().getSubcategories());
4832                 failOnInvalidCategory(user, resource, actionEnum);
4833             }
4834         }
4835     }
4836
4837     private void failOnInvalidCategory(User user, Resource resource, AuditingActionEnum actionEnum) {
4838         ResponseFormat responseFormat;
4839         responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4840         componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4841         throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4842     }
4843
4844     public void validateVendorReleaseName(User user, Resource resource, AuditingActionEnum actionEnum) {
4845         String vendorRelease = resource.getVendorRelease();
4846         log.debug("validate vendor relese name");
4847         if (!ValidationUtils.validateStringNotEmpty(vendorRelease)) {
4848             log.info("vendor relese name is missing.");
4849             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_RELEASE);
4850             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4851             throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_RELEASE);
4852         }
4853         validateVendorReleaseName(vendorRelease, user, resource, actionEnum);
4854     }
4855
4856     public void validateVendorReleaseName(String vendorRelease, User user, Resource resource, AuditingActionEnum actionEnum) {
4857         if (vendorRelease != null) {
4858             if (!ValidationUtils.validateVendorReleaseLength(vendorRelease)) {
4859                 log.info("vendor release exceds limit.");
4860                 ResponseFormat errorResponse = componentsUtils
4861                     .getResponseFormat(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4862                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4863                 throw new ByActionStatusComponentException(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4864             }
4865             if (!ValidationUtils.validateVendorRelease(vendorRelease)) {
4866                 log.info("vendor release  is not valid.");
4867                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_RELEASE);
4868                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4869                 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_RELEASE, vendorRelease);
4870             }
4871         }
4872     }
4873
4874     private void validateVendorName(User user, Resource resource, AuditingActionEnum actionEnum) {
4875         String vendorName = resource.getVendorName();
4876         if (!ValidationUtils.validateStringNotEmpty(vendorName)) {
4877             log.info("vendor name is missing.");
4878             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_NAME);
4879             componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4880             throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_NAME);
4881         }
4882         validateVendorName(vendorName, user, resource, actionEnum);
4883     }
4884
4885     private void validateVendorName(String vendorName, User user, Resource resource, AuditingActionEnum actionEnum) {
4886         if (vendorName != null) {
4887             if (!ValidationUtils.validateVendorNameLength(vendorName)) {
4888                 log.info("vendor name exceds limit.");
4889                 ResponseFormat errorResponse = componentsUtils
4890                     .getResponseFormat(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4891                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4892                 throw new ByActionStatusComponentException(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4893             }
4894             if (!ValidationUtils.validateVendorName(vendorName)) {
4895                 log.info("vendor name  is not valid.");
4896                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_NAME);
4897                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4898                 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_NAME, vendorName);
4899             }
4900         }
4901     }
4902
4903     private void validateResourceVendorModelNumber(User user, Resource resource, AuditingActionEnum actionEnum) {
4904         String resourceVendorModelNumber = resource.getResourceVendorModelNumber();
4905         if (StringUtils.isNotEmpty(resourceVendorModelNumber)) {
4906             if (!ValidationUtils.validateResourceVendorModelNumberLength(resourceVendorModelNumber)) {
4907                 log.info("resource vendor model number exceeds limit.");
4908                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4909                     "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4910                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4911                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4912                     "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4913             }
4914             // resource vendor model number is currently validated as vendor
4915
4916             // name
4917             if (!ValidationUtils.validateVendorName(resourceVendorModelNumber)) {
4918                 log.info("resource vendor model number  is not valid.");
4919                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4920                 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4921                 throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4922             }
4923         }
4924     }
4925
4926     private void validateCost(Resource resource) {
4927         String cost = resource.getCost();
4928         if (cost != null) {
4929             if (!ValidationUtils.validateCost(cost)) {
4930                 log.debug("resource cost is invalid.");
4931                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4932             }
4933         }
4934     }
4935
4936     private void validateLicenseType(User user, Resource resource, AuditingActionEnum actionEnum) {
4937         log.debug("validate licenseType");
4938         String licenseType = resource.getLicenseType();
4939         if (licenseType != null) {
4940             List<String> licenseTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getLicenseTypes();
4941             if (!licenseTypes.contains(licenseType)) {
4942                 log.debug("License type {} isn't configured", licenseType);
4943                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
4944                 if (actionEnum != null) {
4945                     // In update case, no audit is required
4946                     componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4947                 }
4948                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4949             }
4950         }
4951     }
4952
4953     private Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom(Resource currentResource, Resource updatedResource, String userId,
4954                                                                        boolean inTransaction) {
4955         if (updatedResource.getDerivedFrom() != null) {
4956             log.debug("Starting derived from update for resource {}", updatedResource.getUniqueId());
4957             log.debug("1. Removing interface artifacts from graph");
4958             // Remove all interface artifacts of resource
4959             String resourceId = updatedResource.getUniqueId();
4960             Map<String, InterfaceDefinition> interfaces = currentResource.getInterfaces();
4961             if (interfaces != null) {
4962                 Collection<InterfaceDefinition> values = interfaces.values();
4963                 for (InterfaceDefinition interfaceDefinition : values) {
4964                     String interfaceType = interfaceTypeOperation.getShortInterfaceName(interfaceDefinition);
4965                     log.trace("Starting interface artifacts removal for interface type {}", interfaceType);
4966                     Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
4967                     if (operations != null) {
4968                         for (Entry<String, Operation> operationEntry : operations.entrySet()) {
4969                             Operation operation = operationEntry.getValue();
4970                             ArtifactDefinition implementation = operation.getImplementationArtifact();
4971                             if (implementation != null) {
4972                                 String uniqueId = implementation.getUniqueId();
4973                                 log.debug("Removing interface artifact definition {}, operation {}, interfaceType {}", uniqueId,
4974                                     operationEntry.getKey(), interfaceType);
4975                                 // only thing that transacts and locks here
4976                                 Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface = artifactsBusinessLogic
4977                                     .deleteArtifactByInterface(resourceId, userId, uniqueId, true);
4978                                 if (deleteArtifactByInterface.isRight()) {
4979                                     log.debug("Couldn't remove artifact definition with id {}", uniqueId);
4980                                     if (!inTransaction) {
4981                                         janusGraphDao.rollback();
4982                                     }
4983                                     return Either.right(deleteArtifactByInterface.right().value());
4984                                 }
4985                             } else {
4986                                 log.trace("No implementation found for operation {} - nothing to delete", operationEntry.getKey());
4987                             }
4988                         }
4989                     } else {
4990                         log.trace("No operations found for interface type {}", interfaceType);
4991                     }
4992                 }
4993             }
4994             log.debug("2. Removing properties");
4995             Either<Map<String, PropertyDefinition>, StorageOperationStatus> findPropertiesOfNode = propertyOperation
4996                 .deleteAllPropertiesAssociatedToNode(NodeTypeEnum.Resource, resourceId);
4997             if (findPropertiesOfNode.isRight() && findPropertiesOfNode.right().value() != StorageOperationStatus.OK) {
4998                 log.debug("Failed to remove all properties of resource");
4999                 if (!inTransaction) {
5000                     janusGraphDao.rollback();
5001                 }
5002                 return Either
5003                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findPropertiesOfNode.right().value())));
5004             }
5005         } else {
5006             log.debug("Derived from wasn't changed during update");
5007         }
5008         if (inTransaction) {
5009             return Either.left(true);
5010         }
5011         janusGraphDao.commit();
5012         return Either.left(true);
5013     }
5014
5015     public ICapabilityTypeOperation getCapabilityTypeOperation() {
5016         return capabilityTypeOperation;
5017     }
5018
5019     @Autowired
5020     public void setCapabilityTypeOperation(ICapabilityTypeOperation capabilityTypeOperation) {
5021         this.capabilityTypeOperation = capabilityTypeOperation;
5022     }
5023
5024     public Boolean validatePropertiesDefaultValues(Resource resource) {
5025         log.debug("validate resource properties default values");
5026         List<PropertyDefinition> properties = resource.getProperties();
5027         if (properties != null) {
5028             iterateOverProperties(properties, resource.getModel());
5029         }
5030         return true;
5031     }
5032
5033     public void iterateOverProperties(List<PropertyDefinition> properties, String model) {
5034         String type = null;
5035         String innerType = null;
5036         for (PropertyDefinition property : properties) {
5037             if (!propertyOperation.isPropertyTypeValid(property, model)) {
5038                 log.info("Invalid type for property {}", property);
5039                 throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
5040             }
5041             Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
5042             type = property.getType();
5043             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5044                 ResponseFormat responseFormat = validateMapOrListPropertyType(property, innerType, allDataTypes);
5045                 if (responseFormat != null) {
5046                     break;
5047                 }
5048             }
5049             validateDefaultPropertyValue(property, allDataTypes, type, innerType);
5050         }
5051     }
5052
5053     private void validateDefaultPropertyValue(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes, String type,
5054                                               String innerType) {
5055         if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes)) {
5056             log.info("Invalid default value for property {}", property);
5057             ResponseFormat responseFormat;
5058             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5059                 throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
5060                     property.getDefaultValue());
5061             }
5062             throw new ByActionStatusComponentException(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
5063         }
5064     }
5065
5066     private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property, String innerType,
5067                                                          Map<String, DataTypeDefinition> allDataTypes) {
5068         ResponseFormat responseFormat = null;
5069         ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, allDataTypes);
5070         innerType = propertyInnerTypeValid.getLeft();
5071         if (!propertyInnerTypeValid.getRight()) {
5072             log.info("Invalid inner type for property {}", property);
5073             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
5074         }
5075         return responseFormat;
5076     }
5077
5078     @Override
5079     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
5080         return deleteMarkedComponents(ComponentTypeEnum.RESOURCE);
5081     }
5082
5083     @Override
5084     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
5085         return componentInstanceBusinessLogic;
5086     }
5087
5088     private String getComponentTypeForResponse(Component component) {
5089         String componentTypeForResponse = "SERVICE";
5090         if (component instanceof Resource) {
5091             componentTypeForResponse = ((Resource) component).getResourceType().name();
5092         }
5093         return componentTypeForResponse;
5094     }
5095
5096     public Either<Resource, ResponseFormat> getLatestResourceFromCsarUuid(String csarUuid, User user) {
5097         // validate user
5098         if (user != null) {
5099             validateUserExists(user);
5100         }
5101         // get resource from csar uuid
5102         Either<Resource, StorageOperationStatus> either = toscaOperationFacade
5103             .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUuid, "");
5104         if (either.isRight()) {
5105             ResponseFormat resp = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUuid);
5106             return Either.right(resp);
5107         }
5108         return Either.left(either.left().value());
5109     }
5110
5111     @Override
5112     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
5113         return null;
5114     }
5115
5116     private Map<String, List<CapabilityDefinition>> getValidComponentInstanceCapabilities(String resourceId,
5117                                                                                           Map<String, List<CapabilityDefinition>> defaultCapabilities,
5118                                                                                           Map<String, List<UploadCapInfo>> uploadedCapabilities) {
5119         Map<String, List<CapabilityDefinition>> validCapabilitiesMap = new HashMap<>();
5120         uploadedCapabilities.forEach((k, v) -> addValidComponentInstanceCapabilities(k, v, resourceId, defaultCapabilities, validCapabilitiesMap));
5121         return validCapabilitiesMap;
5122     }
5123
5124     private void addValidComponentInstanceCapabilities(String key, List<UploadCapInfo> capabilities, String resourceId,
5125                                                        Map<String, List<CapabilityDefinition>> defaultCapabilities,
5126                                                        Map<String, List<CapabilityDefinition>> validCapabilitiesMap) {
5127         String capabilityType = capabilities.get(0).getType();
5128         if (defaultCapabilities.containsKey(capabilityType)) {
5129             CapabilityDefinition defaultCapability = getCapability(resourceId, defaultCapabilities, capabilityType);
5130             validateCapabilityProperties(capabilities, resourceId, defaultCapability);
5131             List<CapabilityDefinition> validCapabilityList = new ArrayList<>();
5132             validCapabilityList.add(defaultCapability);
5133             validCapabilitiesMap.put(key, validCapabilityList);
5134         } else {
5135             throw new ByActionStatusComponentException(ActionStatus.MISSING_CAPABILITY_TYPE, capabilityType);
5136         }
5137     }
5138
5139     private void validateCapabilityProperties(List<UploadCapInfo> capabilities, String resourceId, CapabilityDefinition defaultCapability) {
5140         if (CollectionUtils.isEmpty(defaultCapability.getProperties()) && isNotEmpty(capabilities.get(0).getProperties())) {
5141             log.debug("Failed to validate capability {} of component {}. Property list is empty. ", defaultCapability.getName(), resourceId);
5142             log.debug("Failed to update capability property values. Property list of fetched capability {} is empty. ", defaultCapability.getName());
5143             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, resourceId);
5144         } else if (isNotEmpty(capabilities.get(0).getProperties())) {
5145             validateUniquenessUpdateUploadedComponentInstanceCapability(defaultCapability, capabilities.get(0));
5146         }
5147     }
5148
5149     private CapabilityDefinition getCapability(String resourceId, Map<String, List<CapabilityDefinition>> defaultCapabilities,
5150                                                String capabilityType) {
5151         CapabilityDefinition defaultCapability;
5152         if (isNotEmpty(defaultCapabilities.get(capabilityType).get(0).getProperties())) {
5153             defaultCapability = defaultCapabilities.get(capabilityType).get(0);
5154         } else {
5155             Either<Component, StorageOperationStatus> getFullComponentRes = toscaOperationFacade.getToscaFullElement(resourceId);
5156             if (getFullComponentRes.isRight()) {
5157                 log.debug("Failed to get full component {}. Status is {}. ", resourceId, getFullComponentRes.right().value());
5158                 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, resourceId);
5159             }
5160             defaultCapability = getFullComponentRes.left().value().getCapabilities().get(capabilityType).get(0);
5161         }
5162         return defaultCapability;
5163     }
5164
5165     private void validateUniquenessUpdateUploadedComponentInstanceCapability(CapabilityDefinition defaultCapability,
5166                                                                              UploadCapInfo uploadedCapability) {
5167         List<ComponentInstanceProperty> validProperties = new ArrayList<>();
5168         Map<String, PropertyDefinition> defaultProperties = defaultCapability.getProperties().stream()
5169             .collect(toMap(PropertyDefinition::getName, Function.identity()));
5170         List<UploadPropInfo> uploadedProperties = uploadedCapability.getProperties();
5171         for (UploadPropInfo property : uploadedProperties) {
5172             String propertyName = property.getName().toLowerCase();
5173             String propertyType = property.getType();
5174             ComponentInstanceProperty validProperty;
5175             if (defaultProperties.containsKey(propertyName) && propertTypeEqualsTo(defaultProperties, propertyName, propertyType)) {
5176                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, propertyName);
5177             }
5178             validProperty = new ComponentInstanceProperty();
5179             validProperty.setName(propertyName);
5180             if (property.getValue() != null) {
5181                 validProperty.setValue(property.getValue().toString());
5182             }
5183             validProperty.setDescription(property.getDescription());
5184             validProperty.setPassword(property.isPassword());
5185             validProperties.add(validProperty);
5186         }
5187         defaultCapability.setProperties(validProperties);
5188     }
5189
5190     private boolean propertTypeEqualsTo(Map<String, PropertyDefinition> defaultProperties, String propertyName, String propertyType) {
5191         return propertyType != null && !defaultProperties.get(propertyName).getType().equals(propertyType);
5192     }
5193
5194     private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> organizeVfCsarArtifactsByArtifactOperation(
5195         List<NonMetaArtifactInfo> artifactPathAndNameList, List<ArtifactDefinition> existingArtifactsToHandle, Resource resource, User user) {
5196         EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
5197         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
5198         Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> nodeTypeArtifactsToHandleRes = Either
5199             .left(nodeTypeArtifactsToHandle);
5200         try {
5201             // add all found Csar artifacts to list to upload
5202             List<NonMetaArtifactInfo> artifactsToUpload = new ArrayList<>(artifactPathAndNameList);
5203             List<NonMetaArtifactInfo> artifactsToUpdate = new ArrayList<>();
5204             List<NonMetaArtifactInfo> artifactsToDelete = new ArrayList<>();
5205             for (NonMetaArtifactInfo currNewArtifact : artifactPathAndNameList) {
5206                 ArtifactDefinition foundArtifact;
5207                 if (!existingArtifactsToHandle.isEmpty()) {
5208                     foundArtifact = existingArtifactsToHandle.stream().filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName()))
5209                         .findFirst().orElse(null);
5210                     if (foundArtifact != null) {
5211                         if (foundArtifact.getArtifactType().equals(currNewArtifact.getArtifactType())) {
5212                             if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
5213                                 currNewArtifact.setArtifactUniqueId(foundArtifact.getUniqueId());
5214                                 // if current artifact already exists, but has
5215
5216                                 // different content, add him to the list to
5217
5218                                 // update
5219                                 artifactsToUpdate.add(currNewArtifact);
5220                             }
5221                             // remove found artifact from the list of existing
5222
5223                             // artifacts to handle, because it was already
5224
5225                             // handled
5226                             existingArtifactsToHandle.remove(foundArtifact);
5227                             // and remove found artifact from the list to
5228
5229                             // upload, because it should either be updated or be
5230
5231                             // ignored
5232                             artifactsToUpload.remove(currNewArtifact);
5233                         } else {
5234                             log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
5235                             ResponseFormat responseFormat = ResponseFormatManager.getInstance()
5236                                 .getResponseFormat(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, currNewArtifact.getArtifactName(),
5237                                     currNewArtifact.getArtifactType(), foundArtifact.getArtifactType());
5238                             AuditingActionEnum auditingAction = artifactsBusinessLogic
5239                                 .detectAuditingType(new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE),
5240                                     foundArtifact.getArtifactChecksum());
5241                             artifactsBusinessLogic
5242                                 .handleAuditing(auditingAction, resource, resource.getUniqueId(), user, null, null, foundArtifact.getUniqueId(),
5243                                     responseFormat, resource.getComponentType(), null);
5244                             responseWrapper.setInnerElement(responseFormat);
5245                             break;
5246                         }
5247                     }
5248                 }
5249             }
5250             if (responseWrapper.isEmpty()) {
5251                 for (ArtifactDefinition currArtifact : existingArtifactsToHandle) {
5252                     if (currArtifact.getIsFromCsar()) {
5253                         artifactsToDelete.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5254                             currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5255                     } else {
5256                         artifactsToUpdate.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5257                             currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5258                     }
5259                 }
5260             }
5261             if (responseWrapper.isEmpty()) {
5262                 if (!artifactsToUpload.isEmpty()) {
5263                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
5264                 }
5265                 if (!artifactsToUpdate.isEmpty()) {
5266                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
5267                 }
5268                 if (!artifactsToDelete.isEmpty()) {
5269                     nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
5270                 }
5271             }
5272             if (!responseWrapper.isEmpty()) {
5273                 nodeTypeArtifactsToHandleRes = Either.right(responseWrapper.getInnerElement());
5274             }
5275         } catch (Exception e) {
5276             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
5277             responseWrapper.setInnerElement(responseFormat);
5278             log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
5279         }
5280         return nodeTypeArtifactsToHandleRes;
5281     }
5282
5283     ImmutablePair<String, String> buildNestedToscaResourceName(final String nodeResourceType, final String vfResourceName,
5284                                                                final String nodeTypeFullName) {
5285         String actualType;
5286         String actualVfName;
5287         if (ResourceTypeEnum.CVFC.name().equals(nodeResourceType)) {
5288             actualVfName = vfResourceName + ResourceTypeEnum.CVFC.name();
5289             actualType = ResourceTypeEnum.VFC.name();
5290         } else {
5291             actualVfName = vfResourceName;
5292             actualType = nodeResourceType;
5293         }
5294         String nameWithouNamespacePrefix;
5295         try {
5296             final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
5297             log.debug("####### buildNestedToscaResourceName nodeResourceType {}, vfResourceName {}, "
5298                     + "nodeTypeFullName {}, actualType {}, vfResourceName {} ", nodeResourceType, vfResourceName, nodeTypeFullName, actualType,
5299                 vfResourceName);
5300             final StringBuilder toscaResourceName = new StringBuilder(nodeTypeNamePrefix);
5301             if (!nodeTypeFullName.contains(nodeTypeNamePrefix)) {
5302                 nameWithouNamespacePrefix = nodeTypeFullName;
5303             } else {
5304                 nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.length());
5305             }
5306             final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
5307             String actualName;
5308             if (nodeResourceType.equalsIgnoreCase(findTypes[0])) {
5309                 actualName = nameWithouNamespacePrefix.substring(nodeResourceType.length());
5310             } else {
5311                 actualName = "." + nameWithouNamespacePrefix;
5312             }
5313             if (actualName.startsWith(Constants.ABSTRACT)) {
5314                 toscaResourceName.append(nodeResourceType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName));
5315             } else {
5316                 toscaResourceName.append(actualType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName)).append('.')
5317                     .append(Constants.ABSTRACT);
5318             }
5319             final StringBuilder previousToscaResourceName = new StringBuilder(toscaResourceName);
5320             final String[] actualNames = actualName.split("\\.");
5321             if (actualNames.length < 3) {
5322                 return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5323                     previousToscaResourceName.append(actualName).toString());
5324             }
5325             return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5326                 previousToscaResourceName.append(actualName.substring(actualNames[1].length() + 1).toLowerCase()).toString());
5327         } catch (final Exception e) {
5328             log.debug("Exception occured when buildNestedToscaResourceName, error is:{}", e.getMessage(), e);
5329             throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE, vfResourceName);
5330         }
5331     }
5332
5333     /**
5334      * Extracts a Node Type Name prefix from the given Node Type Name.
5335      *
5336      * @param fullName Node Type Name
5337      * @return Node Type Name Prefix
5338      */
5339     private String getNodeTypeNamePrefix(final String fullName) {
5340         String tempPrefix = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX;
5341         final List<String> definedNodeTypeNamespaceList = getDefinedNodeTypeNamespaceList();
5342         log.debug("************* getPrefiX fullName {} FROM {}", fullName, definedNodeTypeNamespaceList);
5343         final Optional<String> validNameSpace = validateNodeTypeNamePrefix(fullName, definedNodeTypeNamespaceList);
5344         if (validNameSpace.isPresent()) {
5345             tempPrefix = validNameSpace.get();
5346         }
5347         log.debug("************* getNodeTypeNamePrefix return fullName {} ", tempPrefix);
5348         return tempPrefix;
5349     }
5350
5351     @Override
5352     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId,
5353                                                                                                    List<String> dataParamsToReturn) {
5354         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
5355         Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, paramsToReturn);
5356         if (resourceResultEither.isRight()) {
5357             if (resourceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
5358                 log.debug("Failed to found resource with id {} ", resourceId);
5359                 Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
5360             }
5361             log.debug("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn);
5362             return Either.right(
5363                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceResultEither.right().value()), ""));
5364         }
5365         Resource resource = resourceResultEither.left().value();
5366         if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
5367             ListUtils.emptyIfNull(resource.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
5368         }
5369         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromResourceByParams(resource, dataParamsToReturn);
5370         return Either.left(dataTransfer);
5371     }
5372
5373     @Override
5374     public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
5375         Resource resource = (Resource) clonedComponent;
5376         if (ModelConverter.isAtomicComponent(resource.getResourceType())) {
5377             Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived = toscaOperationFacade.shouldUpgradeToLatestDerived(resource);
5378             if (shouldUpgradeToLatestDerived.isRight()) {
5379                 return Either.right(componentsUtils.convertFromStorageResponse(shouldUpgradeToLatestDerived.right().value()));
5380             }
5381             return Either.left(shouldUpgradeToLatestDerived.left().value());
5382         } else {
5383             return super.shouldUpgradeToLatestDerived(clonedComponent);
5384         }
5385     }
5386 }