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