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