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