2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.openecomp.sdc.be.components.impl;
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;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.EnumMap;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.ListIterator;
43 import java.util.Map.Entry;
44 import java.util.Objects;
45 import java.util.Optional;
47 import java.util.function.Function;
48 import java.util.regex.Pattern;
49 import java.util.stream.Collectors;
51 import org.apache.commons.codec.binary.Base64;
52 import org.apache.commons.collections.CollectionUtils;
53 import org.apache.commons.collections.MapUtils;
54 import org.apache.commons.collections4.ListUtils;
55 import org.apache.commons.lang3.StringUtils;
56 import org.apache.commons.lang3.tuple.ImmutablePair;
57 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
58 import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic;
59 import org.openecomp.sdc.be.components.csar.CsarBusinessLogic;
60 import org.openecomp.sdc.be.components.csar.CsarInfo;
61 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
62 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
63 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
64 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
65 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
66 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
67 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
68 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
69 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
70 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
71 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
72 import org.openecomp.sdc.be.components.merge.TopologyComparator;
73 import org.openecomp.sdc.be.components.merge.property.PropertyDataValueMergeBusinessLogic;
74 import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic;
75 import org.openecomp.sdc.be.components.merge.utils.MergeInstanceUtils;
76 import org.openecomp.sdc.be.components.property.PropertyConstraintsUtils;
77 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
78 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
79 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
80 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
81 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
82 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
83 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
84 import org.openecomp.sdc.be.config.BeEcompErrorManager;
85 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
86 import org.openecomp.sdc.be.config.ConfigurationManager;
87 import org.openecomp.sdc.be.dao.api.ActionStatus;
88 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
89 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
90 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
91 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
92 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
93 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
94 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
95 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
96 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
97 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
98 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
99 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
100 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
101 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
102 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
103 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
104 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
105 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
106 import org.openecomp.sdc.be.impl.ComponentsUtils;
107 import org.openecomp.sdc.be.info.NodeTypeInfoToUpdateArtifacts;
108 import org.openecomp.sdc.be.model.ArtifactDefinition;
109 import org.openecomp.sdc.be.model.AttributeDefinition;
110 import org.openecomp.sdc.be.model.CapabilityDefinition;
111 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
112 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
113 import org.openecomp.sdc.be.model.Component;
114 import org.openecomp.sdc.be.model.ComponentInstance;
115 import org.openecomp.sdc.be.model.ComponentInstanceInput;
116 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
117 import org.openecomp.sdc.be.model.ComponentParametersView;
118 import org.openecomp.sdc.be.model.DataTypeDefinition;
119 import org.openecomp.sdc.be.model.GroupDefinition;
120 import org.openecomp.sdc.be.model.GroupProperty;
121 import org.openecomp.sdc.be.model.InputDefinition;
122 import org.openecomp.sdc.be.model.InterfaceDefinition;
123 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
124 import org.openecomp.sdc.be.model.LifecycleStateEnum;
125 import org.openecomp.sdc.be.model.Model;
126 import org.openecomp.sdc.be.model.NodeTypeInfo;
127 import org.openecomp.sdc.be.model.Operation;
128 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
129 import org.openecomp.sdc.be.model.PolicyDefinition;
130 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
131 import org.openecomp.sdc.be.model.PropertyDefinition;
132 import org.openecomp.sdc.be.model.RelationshipImpl;
133 import org.openecomp.sdc.be.model.RelationshipInfo;
134 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
135 import org.openecomp.sdc.be.model.RequirementDefinition;
136 import org.openecomp.sdc.be.model.Resource;
137 import org.openecomp.sdc.be.model.UploadArtifactInfo;
138 import org.openecomp.sdc.be.model.UploadCapInfo;
139 import org.openecomp.sdc.be.model.UploadComponentInstanceInfo;
140 import org.openecomp.sdc.be.model.UploadInfo;
141 import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
142 import org.openecomp.sdc.be.model.UploadPropInfo;
143 import org.openecomp.sdc.be.model.UploadReqInfo;
144 import org.openecomp.sdc.be.model.UploadResourceInfo;
145 import org.openecomp.sdc.be.model.User;
146 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
147 import org.openecomp.sdc.be.model.category.CategoryDefinition;
148 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
149 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
150 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
151 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
152 import org.openecomp.sdc.be.model.operations.StorageException;
153 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
154 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
155 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
156 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
157 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
158 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
159 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
160 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
161 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
162 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
163 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
164 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
165 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
166 import org.openecomp.sdc.be.tosca.CsarUtils;
167 import org.openecomp.sdc.be.tosca.CsarUtils.NonMetaArtifactInfo;
168 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
169 import org.openecomp.sdc.be.user.UserBusinessLogic;
170 import org.openecomp.sdc.be.utils.CommonBeUtils;
171 import org.openecomp.sdc.be.utils.TypeUtils;
172 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
173 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
174 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
175 import org.openecomp.sdc.common.api.Constants;
176 import org.openecomp.sdc.common.datastructure.Wrapper;
177 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
178 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
179 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
180 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
181 import org.openecomp.sdc.common.log.enums.StatusCode;
182 import org.openecomp.sdc.common.log.wrappers.Logger;
183 import org.openecomp.sdc.common.util.GeneralUtility;
184 import org.openecomp.sdc.common.util.ValidationUtils;
185 import org.openecomp.sdc.exception.ResponseFormat;
186 import org.springframework.beans.factory.annotation.Autowired;
187 import org.springframework.context.annotation.Lazy;
188 import org.yaml.snakeyaml.DumperOptions;
189 import org.yaml.snakeyaml.Yaml;
191 import com.google.common.annotations.VisibleForTesting;
193 import fj.data.Either;
195 @org.springframework.stereotype.Component("resourceBusinessLogic")
196 public class ResourceBusinessLogic extends ComponentBusinessLogic {
198 private static final String DELETE_RESOURCE = "Delete Resource";
199 private static final String IN_RESOURCE = " in resource {} ";
200 private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
201 private static final String INITIAL_VERSION = "0.1";
202 private static final Logger log = Logger.getLogger(ResourceBusinessLogic.class);
203 private static final String CERTIFICATION_ON_IMPORT = "certification on import";
204 private static final String CREATE_RESOURCE = "Create Resource";
205 private static final String VALIDATE_DERIVED_BEFORE_UPDATE = "validate derived before update";
206 private static final String CATEGORY_IS_EMPTY = "Resource category is empty";
207 private static final String CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES = "Create Resource - validateCapabilityTypesCreate";
208 private static final String COMPONENT_INSTANCE_WITH_NAME = "component instance with name ";
209 private static final String COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE = "component instance with name {} in resource {} ";
210 private static final String VALID_CHARACTERS_ARTIFACT_NAME = "'A-Z', 'a-z', '0-9', '.', '_', '-', '@' and space";
211 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourceBusinessLogic.class.getName());
212 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
213 private final ResourceImportManager resourceImportManager;
214 private final InputsBusinessLogic inputsBusinessLogic;
215 private final OutputsBusinessLogic outputsBusinessLogic;
216 private final CompositionBusinessLogic compositionBusinessLogic;
217 private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic;
218 private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic;
219 private final MergeInstanceUtils mergeInstanceUtils;
220 private final UiComponentDataConverter uiComponentDataConverter;
221 private final CsarBusinessLogic csarBusinessLogic;
222 private final PropertyBusinessLogic propertyBusinessLogic;
223 private final PolicyBusinessLogic policyBusinessLogic;
224 private final ModelBusinessLogic modelBusinessLogic;
225 private IInterfaceLifecycleOperation interfaceTypeOperation;
226 private LifecycleBusinessLogic lifecycleBusinessLogic;
227 private final DataTypeBusinessLogic dataTypeBusinessLogic;
228 private final PolicyTypeBusinessLogic policyTypeBusinessLogic;
231 private ICapabilityTypeOperation capabilityTypeOperation;
233 private TopologyComparator topologyComparator;
235 private ComponentValidator componentValidator;
237 private PropertyDataValueMergeBusinessLogic propertyDataValueMergeBusinessLogic;
239 private SoftwareInformationBusinessLogic softwareInformationBusinessLogic;
243 public ResourceBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
244 final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
245 final GroupBusinessLogic groupBusinessLogic, final InterfaceOperation interfaceOperation,
246 final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
247 final ArtifactsBusinessLogic artifactsBusinessLogic,
248 final ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
249 final @Lazy ResourceImportManager resourceImportManager, final InputsBusinessLogic inputsBusinessLogic,
250 final OutputsBusinessLogic outputsBusinessLogic, final CompositionBusinessLogic compositionBusinessLogic,
251 final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic,
252 final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic,
253 final MergeInstanceUtils mergeInstanceUtils, final UiComponentDataConverter uiComponentDataConverter,
254 final CsarBusinessLogic csarBusinessLogic, final ArtifactsOperations artifactToscaOperation,
255 final PropertyBusinessLogic propertyBusinessLogic, final ComponentContactIdValidator componentContactIdValidator,
256 final ComponentNameValidator componentNameValidator, final ComponentTagsValidator componentTagsValidator,
257 final ComponentValidator componentValidator, final ComponentIconValidator componentIconValidator,
258 final ComponentProjectCodeValidator componentProjectCodeValidator,
259 final ComponentDescriptionValidator componentDescriptionValidator, final PolicyBusinessLogic policyBusinessLogic,
260 final ModelBusinessLogic modelBusinessLogic,
261 final DataTypeBusinessLogic dataTypeBusinessLogic, final PolicyTypeBusinessLogic policyTypeBusinessLogic) {
262 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
263 interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
264 componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
265 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
266 this.resourceImportManager = resourceImportManager;
267 this.inputsBusinessLogic = inputsBusinessLogic;
268 this.outputsBusinessLogic = outputsBusinessLogic;
269 this.compositionBusinessLogic = compositionBusinessLogic;
270 this.resourceDataMergeBusinessLogic = resourceDataMergeBusinessLogic;
271 this.csarArtifactsAndGroupsBusinessLogic = csarArtifactsAndGroupsBusinessLogic;
272 this.mergeInstanceUtils = mergeInstanceUtils;
273 this.uiComponentDataConverter = uiComponentDataConverter;
274 this.csarBusinessLogic = csarBusinessLogic;
275 this.propertyBusinessLogic = propertyBusinessLogic;
276 this.policyBusinessLogic = policyBusinessLogic;
277 this.modelBusinessLogic = modelBusinessLogic;
278 this.dataTypeBusinessLogic = dataTypeBusinessLogic;
279 this.policyTypeBusinessLogic = policyTypeBusinessLogic;
282 static <T> Either<T, RuntimeException> rollbackWithEither(final JanusGraphDao janusGraphDao, final ActionStatus actionStatus,
283 final String... params) {
284 if (janusGraphDao != null) {
285 janusGraphDao.rollback();
287 return Either.right(new ByActionStatusComponentException(actionStatus, params));
290 public LifecycleBusinessLogic getLifecycleBusinessLogic() {
291 return lifecycleBusinessLogic;
295 public void setLifecycleManager(LifecycleBusinessLogic lifecycleBusinessLogic) {
296 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
300 protected void setComponentValidator(ComponentValidator componentValidator) {
301 this.componentValidator = componentValidator;
304 public IElementOperation getElementDao() {
308 public void setElementDao(IElementOperation elementDao) {
309 this.elementDao = elementDao;
312 public UserBusinessLogic getUserAdmin() {
313 return this.userAdmin;
318 public void setUserAdmin(UserBusinessLogic userAdmin) {
319 this.userAdmin = userAdmin;
322 public ComponentsUtils getComponentsUtils() {
323 return this.componentsUtils;
328 public void setComponentsUtils(ComponentsUtils componentsUtils) {
329 this.componentsUtils = componentsUtils;
332 public ArtifactsBusinessLogic getArtifactsManager() {
333 return artifactsBusinessLogic;
336 public void setArtifactsManager(ArtifactsBusinessLogic artifactsManager) {
337 this.artifactsBusinessLogic = artifactsManager;
340 public ApplicationDataTypeCache getApplicationDataTypeCache() {
341 return applicationDataTypeCache;
346 public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) {
347 this.applicationDataTypeCache = applicationDataTypeCache;
351 public void setInterfaceTypeOperation(IInterfaceLifecycleOperation interfaceTypeOperation) {
352 this.interfaceTypeOperation = interfaceTypeOperation;
356 * the method returns a list of all the resources that are certified, the returned resources are only abstract or only none abstract according to
363 public List<Resource> getAllCertifiedResources(boolean getAbstract, HighestFilterEnum highestFilter, String userId) {
364 User user = validateUserExists(userId);
365 Boolean isHighest = null;
366 switch (highestFilter) {
372 case NON_HIGHEST_ONLY:
378 Either<List<Resource>, StorageOperationStatus> getResponse = toscaOperationFacade.getAllCertifiedResources(getAbstract, isHighest);
379 if (getResponse.isRight()) {
380 throw new StorageException(getResponse.right().value());
382 return getResponse.left().value();
385 public Either<Map<String, Boolean>, ResponseFormat> validateResourceNameExists(String resourceName, ResourceTypeEnum resourceTypeEnum,
387 validateUserExists(userId);
388 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
389 .validateComponentNameUniqueness(resourceName, resourceTypeEnum, ComponentTypeEnum.RESOURCE);
391 janusGraphDao.commit();
392 if (dataModelResponse.isLeft()) {
393 Map<String, Boolean> result = new HashMap<>();
394 result.put("isValid", dataModelResponse.left().value());
395 log.debug("validation was successfully performed.");
396 return Either.left(result);
398 ResponseFormat responseFormat = componentsUtils
399 .getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
400 return Either.right(responseFormat);
403 public Resource createResource(Resource resource, AuditingActionEnum auditingAction, User user, Map<String, byte[]> csarUIPayload,
404 String payloadName) {
405 validateResourceBeforeCreate(resource, user, false);
406 String csarUUID = payloadName == null ? resource.getCsarUUID() : payloadName;
407 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
408 "Starting to create resource from CSAR by user {} ", user.getUserId());
409 if (StringUtils.isNotEmpty(csarUUID)) {
410 csarBusinessLogic.validateCsarBeforeCreate(resource, auditingAction, user, csarUUID);
411 log.debug("CsarUUID is {} - going to create resource from CSAR", csarUUID);
412 Resource createResourceFromCsar = createResourceFromCsar(resource, user, csarUIPayload, csarUUID);
413 return updateCatalog(createResourceFromCsar, ChangeTypeEnum.LIFECYCLE).left().map(Resource.class::cast).left().value();
415 final Resource createResourceByDao = createResourceByDao(resource, user, auditingAction, false, false);
416 return updateCatalog(createResourceByDao, ChangeTypeEnum.LIFECYCLE).left().map(Resource.class::cast).left().value();
419 public Resource validateAndUpdateResourceFromCsar(Resource resource, User user, Map<String, byte[]> csarUIPayload, String payloadName,
420 String resourceUniqueId) {
421 String csarUUID = payloadName;
422 String csarVersion = null;
423 Resource updatedResource = null;
424 if (payloadName == null) {
425 csarUUID = resource.getCsarUUID();
426 csarVersion = resource.getCsarVersion();
428 if (csarUUID != null && !csarUUID.isEmpty()) {
429 Resource oldResource = getResourceByUniqueId(resourceUniqueId);
430 validateCsarUuidMatching(oldResource, resource, csarUUID, resourceUniqueId, user);
431 validateCsarIsNotAlreadyUsed(oldResource, resource, csarUUID, user);
432 if (oldResource != null && ValidationUtils.hasBeenCertified(oldResource.getVersion())) {
433 overrideImmutableMetadata(oldResource, resource);
435 validateResourceBeforeCreate(resource, user, false);
436 String oldCsarVersion = oldResource != null ? oldResource.getCsarVersion() : null;
437 log.debug("CsarUUID is {} - going to update resource with UniqueId {} from CSAR", csarUUID, resourceUniqueId);
438 // (on boarding flow): If the update includes same csarUUID and
440 // same csarVersion as already in the VF - no need to import the
442 // csar (do only metadata changes if there are).
443 if (csarVersion != null && oldCsarVersion != null && oldCsarVersion.equals(csarVersion)) {
444 updatedResource = updateResourceMetadata(resourceUniqueId, resource, oldResource, user, false);
446 updatedResource = updateResourceFromCsar(oldResource, resource, user, AuditingActionEnum.UPDATE_RESOURCE_METADATA, false,
447 csarUIPayload, csarUUID);
450 log.debug("Failed to update resource {}, csarUUID or payload name is missing", resource.getSystemName());
451 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CSAR_UUID, resource.getName());
452 componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.CREATE_RESOURCE);
453 throw new ByActionStatusComponentException(ActionStatus.MISSING_CSAR_UUID, resource.getName());
455 return updatedResource;
458 private void validateCsarIsNotAlreadyUsed(Resource oldResource, Resource resource, String csarUUID, User user) {
459 // (on boarding flow): If the update includes a csarUUID: verify this
461 // csarUUID is not in use by another VF, If it is - use same error as
465 // "Error: The VSP with UUID %1 was already imported for VF %2. Please
467 // select another or update the existing VF." %1 - csarUUID, %2 - VF
470 Either<Resource, StorageOperationStatus> resourceLinkedToCsarRes = toscaOperationFacade
471 .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUUID, resource.getSystemName());
472 if (resourceLinkedToCsarRes.isRight()) {
473 if (StorageOperationStatus.NOT_FOUND != resourceLinkedToCsarRes.right().value()) {
474 log.debug("Failed to find previous resource by CSAR {} and system name {}", csarUUID, resource.getSystemName());
475 throw new StorageException(resourceLinkedToCsarRes.right().value());
477 } else if (!resourceLinkedToCsarRes.left().value().getUniqueId().equals(oldResource.getUniqueId()) && !resourceLinkedToCsarRes.left().value()
478 .getName().equals(oldResource.getName())) {
479 ResponseFormat errorResponse = componentsUtils
480 .getResponseFormat(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, resourceLinkedToCsarRes.left().value().getName());
481 componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.UPDATE_RESOURCE_METADATA);
482 throw new ByActionStatusComponentException(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, resourceLinkedToCsarRes.left().value().getName());
486 private void validateCsarUuidMatching(Resource resource, Resource oldResource, String csarUUID, String resourceUniqueId, User user) {
487 // (on boarding flow): If the update includes csarUUID which is
489 // different from the csarUUID of the VF - fail with
491 // error: "Error: Resource %1 cannot be updated using since it is linked
493 // to a different VSP" %1 - VF name
494 String oldCsarUUID = oldResource.getCsarUUID();
495 if (oldCsarUUID != null && !oldCsarUUID.isEmpty() && !csarUUID.equals(oldCsarUUID)) {
496 log.debug("Failed to update resource with UniqueId {} using Csar {}, since the resource is linked to a different VSP {}",
497 resourceUniqueId, csarUUID, oldCsarUUID);
498 ResponseFormat errorResponse = componentsUtils
499 .getResponseFormat(ActionStatus.RESOURCE_LINKED_TO_DIFFERENT_VSP, resource.getName(), csarUUID, oldCsarUUID);
500 componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.UPDATE_RESOURCE_METADATA);
501 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_LINKED_TO_DIFFERENT_VSP, resource.getName(), csarUUID, oldCsarUUID);
505 private Resource getResourceByUniqueId(String resourceUniqueId) {
506 Either<Resource, StorageOperationStatus> oldResourceRes = toscaOperationFacade.getToscaFullElement(resourceUniqueId);
507 if (oldResourceRes.isRight()) {
508 log.debug("Failed to find previous resource by UniqueId {}, status: {}", resourceUniqueId, oldResourceRes.right().value());
509 throw new StorageException(oldResourceRes.right().value());
511 return oldResourceRes.left().value();
514 private void overrideImmutableMetadata(Resource oldResource, Resource resource) {
515 resource.setName(oldResource.getName());
516 resource.setIcon(oldResource.getIcon());
517 resource.setTags(oldResource.getTags());
518 resource.setCategories(oldResource.getCategories());
519 resource.setDerivedFrom(oldResource.getDerivedFrom());
522 private Resource updateResourceFromCsar(Resource oldResource, Resource newResource, User user, AuditingActionEnum updateResource,
523 boolean inTransaction, Map<String, byte[]> csarUIPayload, String csarUUID) {
524 Resource updatedResource = null;
525 validateLifecycleState(oldResource, user);
526 String lockedResourceId = oldResource.getUniqueId();
527 List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
528 CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(newResource, oldResource, user, csarUIPayload, csarUUID);
529 lockComponent(lockedResourceId, oldResource, "update Resource From Csar");
530 Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
531 Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
532 nodeTypesInfo, csarInfo, oldResource);
533 if (findNodeTypesArtifactsToHandleRes.isRight()) {
534 log.debug("failed to find node types for update with artifacts during import csar {}. ", csarInfo.getCsarUUID());
535 throw new ByResponseFormatComponentException(findNodeTypesArtifactsToHandleRes.right().value());
537 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = findNodeTypesArtifactsToHandleRes.left()
540 updatedResource = updateResourceFromYaml(oldResource, newResource, updateResource, createdArtifacts, csarInfo.getMainTemplateName(),
541 csarInfo.getMainTemplateContent(), csarInfo, nodeTypesInfo, nodeTypesArtifactsToHandle, null, false);
542 } catch (ComponentException | StorageException e) {
543 rollback(inTransaction, newResource, createdArtifacts, null);
546 janusGraphDao.commit();
547 log.debug("unlock resource {}", lockedResourceId);
548 graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource);
550 return updatedResource;
553 private void validateLifecycleState(Resource oldResource, User user) {
554 if (LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == oldResource.getLifecycleState() && !oldResource.getLastUpdaterUserId()
555 .equals(user.getUserId())) {
556 log.debug("#validateLifecycleState - Current user is not last updater, last updater userId: {}, current user userId: {}",
557 oldResource.getLastUpdaterUserId(), user.getUserId());
558 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
562 private Resource updateResourceFromYaml(Resource oldResource, Resource newResource, AuditingActionEnum actionEnum,
563 List<ArtifactDefinition> createdArtifacts, String yamlFileName, String yamlFileContent, CsarInfo csarInfo,
564 Map<String, NodeTypeInfo> nodeTypesInfo,
565 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
566 String nodeName, boolean isNested) {
567 boolean inTransaction = true;
568 boolean shouldLock = false;
569 Resource preparedResource = null;
570 ParsedToscaYamlInfo uploadComponentInstanceInfoMap;
572 uploadComponentInstanceInfoMap = csarBusinessLogic
573 .getParsedToscaYamlInfo(yamlFileContent, yamlFileName, nodeTypesInfo, csarInfo, nodeName, oldResource);
574 Map<String, UploadComponentInstanceInfo> instances = uploadComponentInstanceInfoMap.getInstances();
575 if (MapUtils.isEmpty(instances) && newResource.getResourceType() != ResourceTypeEnum.PNF) {
576 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlFileName);
578 preparedResource = updateExistingResourceByImport(newResource, oldResource, csarInfo.getModifier(), inTransaction, shouldLock,
580 log.trace("YAML topology file found in CSAR, file name: {}, contents: {}", yamlFileName, yamlFileContent);
581 handleResourceGenericType(preparedResource, yamlFileContent, uploadComponentInstanceInfoMap,
582 uploadComponentInstanceInfoMap.getSubstitutionMappingNodeType());
583 handleNodeTypes(yamlFileName, preparedResource, yamlFileContent, shouldLock, nodeTypesArtifactsToHandle, createdArtifacts, nodeTypesInfo,
584 csarInfo, nodeName, newResource.getModel());
585 preparedResource = createInputsOnResource(preparedResource, uploadComponentInstanceInfoMap.getInputs());
586 Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
587 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(uploadComponentInstanceInfoMap,
588 newResource.getModel());
589 preparedResource = createResourceInstances(yamlFileName, preparedResource, oldResource, instancesToCreate, csarInfo.getCreatedNodes(),
590 existingNodeTypesByResourceNames);
591 preparedResource = createResourceInstancesRelations(csarInfo.getModifier(), yamlFileName, preparedResource, oldResource,
593 existingNodeTypesByResourceNames);
594 } catch (ComponentException e) {
595 ResponseFormat responseFormat =
596 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
597 log.debug("#updateResourceFromYaml - failed to update newResource from yaml {} .The error is {}", yamlFileName, responseFormat);
599 .auditResource(responseFormat, csarInfo.getModifier(), preparedResource == null ? oldResource : preparedResource, actionEnum);
601 } catch (StorageException e) {
602 ResponseFormat responseFormat = componentsUtils
603 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
604 log.debug("#updateResourceFromYaml - failed to update newResource from yaml {} .The error is {}", yamlFileName, responseFormat);
606 .auditResource(responseFormat, csarInfo.getModifier(), preparedResource == null ? oldResource : preparedResource, actionEnum);
609 Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic
610 .validateUpdateVfGroupNames(uploadComponentInstanceInfoMap.getGroups(), preparedResource.getSystemName());
611 if (validateUpdateVfGroupNamesRes.isRight()) {
612 throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value());
614 // add groups to newResource
615 Map<String, GroupDefinition> groups;
616 if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) {
617 groups = validateUpdateVfGroupNamesRes.left().value();
619 groups = uploadComponentInstanceInfoMap.getGroups();
621 handleGroupsProperties(preparedResource, groups);
622 Either<Boolean, ActionStatus> isTopologyChanged = topologyComparator.isTopologyChanged(oldResource, preparedResource);
623 preparedResource = updateGroupsOnResource(preparedResource, groups);
624 NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName, nodeTypesArtifactsToHandle);
625 Either<Resource, ResponseFormat> updateArtifactsEither = createOrUpdateArtifacts(ArtifactOperationEnum.UPDATE, createdArtifacts, yamlFileName,
626 csarInfo, preparedResource, nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock);
627 if (updateArtifactsEither.isRight()) {
628 log.debug("failed to update artifacts {}", updateArtifactsEither.right().value());
629 throw new ByResponseFormatComponentException(updateArtifactsEither.right().value());
631 preparedResource = getResourceWithGroups(updateArtifactsEither.left().value().getUniqueId());
632 updateGroupsName(oldResource, preparedResource, isTopologyChanged.left().value());
633 updateResourceInstancesNames(oldResource, csarInfo, preparedResource, isTopologyChanged.left().value());
634 final String preparedResourceId = preparedResource != null ? preparedResource.getUniqueId() : "";
635 preparedResource = getResourceWithGroups(preparedResourceId);
636 updateVolumeGroup(preparedResource);
637 ActionStatus mergingPropsAndInputsStatus = resourceDataMergeBusinessLogic.mergeResourceEntities(oldResource, preparedResource);
638 if (mergingPropsAndInputsStatus != ActionStatus.OK) {
639 ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(mergingPropsAndInputsStatus, preparedResource);
640 throw new ByResponseFormatComponentException(responseFormat);
642 compositionBusinessLogic.setPositionsForComponentInstances(preparedResource, csarInfo.getModifier().getUserId());
643 return preparedResource;
646 protected void updateVolumeGroup(Resource preparedResource) {
647 List<GroupDefinition> groups = preparedResource.safeGetGroups();
648 for (GroupDefinition group : groups) {
649 Map<String, ArtifactDefinition> createdNewArtifacts = preparedResource.getDeploymentArtifacts();
650 if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
651 List<PropertyDataDefinition> volumePropList = group.getProperties().stream().filter(p -> "volume_group".equals(p.getName()))
652 .collect(Collectors.toList());
653 if (!volumePropList.isEmpty()) {
654 PropertyDataDefinition volumeProp = volumePropList.get(0);
655 if (volumeProp != null) {
656 boolean isVolumeGroup = isVolumeGroup(group.getArtifacts(), new ArrayList<>(createdNewArtifacts.values()));
657 if (!volumePropList.get(0).getValue().equals(String.valueOf(isVolumeGroup))) {
658 volumeProp.setValue(String.valueOf(isVolumeGroup));
659 volumeProp.setDefaultValue(String.valueOf(isVolumeGroup));
667 private void updateGroupsName(Resource oldResource, Resource preparedResource, boolean isTopologyChanged) {
668 if (oldResource == null || preparedResource == null) {
669 log.debug("Failed to update groups name : oldResource or preparedResource is null");
670 } else if (CollectionUtils.isNotEmpty(oldResource.getGroups()) && CollectionUtils.isNotEmpty(preparedResource.getGroups())) {
671 Map<String, String> oldGroups = oldResource.getGroups().stream()
672 .collect(toMap(GroupDataDefinition::getInvariantName, GroupDataDefinition::getName));
673 List<GroupDefinition> updatedGroups = preparedResource.getGroups().stream()
674 .filter(group -> oldGroups.containsKey(group.getInvariantName()) && !group.getName().equals(oldGroups.get(group.getInvariantName())))
676 if (CollectionUtils.isNotEmpty(updatedGroups)) {
677 if (isTopologyChanged) {
678 updatedGroups.stream().filter(group -> !group.isVspOriginated())
679 .forEach(group -> group.setName(oldGroups.get(group.getInvariantName())));
681 updatedGroups.forEach(group -> group.setName(oldGroups.get(group.getInvariantName())));
683 groupBusinessLogic.updateGroups(preparedResource, updatedGroups, false);
688 private void updateResourceInstancesNames(Resource oldResource, CsarInfo csarInfo, Resource preparedResource, boolean isTopologyChanged) {
689 if (oldResource == null || preparedResource == null) {
690 log.debug("Failed to update resource instances names : oldResource or preparedResource is null");
692 if (CollectionUtils.isNotEmpty(oldResource.getComponentInstances())) {
693 Map<String, String> oldInstances = oldResource.getComponentInstances().stream()
694 .collect(toMap(ComponentInstance::getInvariantName, ComponentInstance::getName));
695 List<ComponentInstance> updatedInstances = preparedResource.getComponentInstances().stream()
696 .filter(i -> oldInstances.containsKey(i.getInvariantName()) && !i.getName().equals(oldInstances.get(i.getInvariantName())))
698 if (CollectionUtils.isNotEmpty(updatedInstances)) {
699 if (isTopologyChanged) {
700 updatedInstances.stream().filter(i -> !i.isCreatedFromCsar()).forEach(i -> i.setName(oldInstances.get(i.getInvariantName())));
702 updatedInstances.forEach(i -> i.setName(oldInstances.get(i.getInvariantName())));
706 componentInstanceBusinessLogic.updateComponentInstance(ComponentTypeEnum.RESOURCE_PARAM_NAME, null, preparedResource.getUniqueId(),
707 csarInfo.getModifier().getUserId(), preparedResource.getComponentInstances(), false);
711 private Either<Resource, ResponseFormat> createOrUpdateArtifacts(ArtifactOperationEnum operation, List<ArtifactDefinition> createdArtifacts,
712 String yamlFileName, CsarInfo csarInfo, Resource preparedResource,
713 NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts,
714 boolean inTransaction, boolean shouldLock) {
715 String nodeName = nodeTypeInfoToUpdateArtifacts.getNodeName();
716 Resource resource = preparedResource;
717 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = nodeTypeInfoToUpdateArtifacts
718 .getNodeTypesArtifactsToHandle();
719 if (preparedResource.getResourceType() == ResourceTypeEnum.CVFC) {
720 if (nodeName != null && nodeTypesArtifactsToHandle.get(nodeName) != null && !nodeTypesArtifactsToHandle.get(nodeName).isEmpty()) {
721 Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes = handleNodeTypeArtifacts(preparedResource,
722 nodeTypesArtifactsToHandle.get(nodeName), createdArtifacts, csarInfo.getModifier(), inTransaction, true);
723 if (handleNodeTypeArtifactsRes.isRight()) {
724 return Either.right(handleNodeTypeArtifactsRes.right().value());
728 Either<Resource, ResponseFormat> createdCsarArtifactsEither = handleVfCsarArtifacts(preparedResource, csarInfo, createdArtifacts,
729 new ArtifactOperationInfo(false, false, operation), shouldLock, inTransaction);
730 log.trace("************* Finished to add artifacts from yaml {}", yamlFileName);
731 if (createdCsarArtifactsEither.isRight()) {
732 return createdCsarArtifactsEither;
734 resource = createdCsarArtifactsEither.left().value();
736 return Either.left(resource);
739 private Resource handleResourceGenericType(Resource resource) {
740 Resource genericResource = fetchAndSetDerivedFromGenericType(resource);
742 if (resource.shouldGenerateInputs()) {
743 generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
745 return genericResource;
748 private Resource handleResourceGenericType(final Resource resource, final String topologyTemplateYaml,
749 final ParsedToscaYamlInfo parsedToscaYamlInfo, final String substitutionMappingNodeType) {
750 if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
751 final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
752 (Map<String, Object>) new Yaml().load(topologyTemplateYaml), substitutionMappingNodeType);
753 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
754 (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
756 generatePropertiesFromGenericType(resource, genericResource);
757 generatePropertiesFromNodeType(resource, substitutableAsNodeType);
758 final String resourceId = resource.getUniqueId();
759 resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
760 UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
761 createResourcePropertiesOnGraph(resource);
762 return genericResource;
764 return handleResourceGenericType(resource);
767 private Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandle(
768 final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo, final Resource oldResource) {
769 final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = new HashMap<>();
770 Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> nodeTypesArtifactsToHandleRes = Either
771 .left(nodeTypesArtifactsToHandle);
773 final Map<String, List<ArtifactDefinition>> extractedVfcsArtifacts = CsarUtils.extractVfcsArtifactsFromCsar(csarInfo.getCsar());
774 final Map<String, ImmutablePair<String, String>> extractedVfcToscaNames = extractVfcToscaNames(nodeTypesInfo, oldResource.getName(),
776 log.debug("Going to fetch node types for resource with name {} during import csar with UUID {}. ", oldResource.getName(),
777 csarInfo.getCsarUUID());
778 extractedVfcToscaNames.forEach(
779 (namespace, vfcToscaNames) -> findAddNodeTypeArtifactsToHandle(csarInfo, nodeTypesArtifactsToHandle, oldResource,
780 extractedVfcsArtifacts, namespace, vfcToscaNames));
781 } catch (Exception e) {
782 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
783 nodeTypesArtifactsToHandleRes = Either.right(responseFormat);
784 log.debug("Exception occurred when findNodeTypesUpdatedArtifacts, error is:{}", e.getMessage(), e);
786 return nodeTypesArtifactsToHandleRes;
789 private void findAddNodeTypeArtifactsToHandle(CsarInfo csarInfo,
790 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
791 Resource resource, Map<String, List<ArtifactDefinition>> extractedVfcsArtifacts, String namespace,
792 ImmutablePair<String, String> vfcToscaNames) {
793 EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> curNodeTypeArtifactsToHandle = null;
794 log.debug("Going to fetch node type with tosca name {}. ", vfcToscaNames.getLeft());
795 Resource curNodeType = findVfcResource(csarInfo, resource, vfcToscaNames.getLeft(), vfcToscaNames.getRight(), null);
796 if (!isEmpty(extractedVfcsArtifacts)) {
797 List<ArtifactDefinition> currArtifacts = new ArrayList<>();
798 if (extractedVfcsArtifacts.containsKey(namespace)) {
799 handleAndAddExtractedVfcsArtifacts(currArtifacts, extractedVfcsArtifacts.get(namespace));
801 curNodeTypeArtifactsToHandle = findNodeTypeArtifactsToHandle(curNodeType, currArtifacts);
802 } else if (curNodeType != null) {
803 // delete all artifacts if have not received artifacts from
806 curNodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
807 List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
808 // delete all informational artifacts
809 artifactsToDelete.addAll(
810 curNodeType.getArtifacts().values().stream().filter(a -> a.getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL)
812 // delete all deployment artifacts
813 artifactsToDelete.addAll(curNodeType.getDeploymentArtifacts().values());
814 if (!artifactsToDelete.isEmpty()) {
815 curNodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
818 if (isNotEmpty(curNodeTypeArtifactsToHandle)) {
819 nodeTypesArtifactsToHandle.put(namespace, curNodeTypeArtifactsToHandle);
823 private Resource findVfcResource(CsarInfo csarInfo, Resource resource, String currVfcToscaName, String previousVfcToscaName,
824 StorageOperationStatus status) {
825 if (status != null && status != StorageOperationStatus.NOT_FOUND) {
826 log.debug("Error occurred during fetching node type with tosca name {}, error: {}", currVfcToscaName, status);
827 ResponseFormat responseFormat = componentsUtils
828 .getResponseFormat(componentsUtils.convertFromStorageResponse(status), csarInfo.getCsarUUID());
829 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.CREATE_RESOURCE);
830 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), csarInfo.getCsarUUID());
831 } else if (StringUtils.isNotEmpty(currVfcToscaName)) {
832 return (Resource) toscaOperationFacade.getLatestByToscaResourceName(currVfcToscaName, resource.getModel()).left()
833 .on(st -> findVfcResource(csarInfo, resource, previousVfcToscaName, null, st));
838 private EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> findNodeTypeArtifactsToHandle(Resource curNodeType,
839 List<ArtifactDefinition> extractedArtifacts) {
841 List<ArtifactDefinition> artifactsToUpload = new ArrayList<>(extractedArtifacts);
842 List<ArtifactDefinition> artifactsToUpdate = new ArrayList<>();
843 List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
844 processExistingNodeTypeArtifacts(extractedArtifacts, artifactsToUpload, artifactsToUpdate, artifactsToDelete,
845 collectExistingArtifacts(curNodeType));
846 return putFoundArtifacts(artifactsToUpload, artifactsToUpdate, artifactsToDelete);
847 } catch (Exception e) {
848 log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
849 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
853 private EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> putFoundArtifacts(List<ArtifactDefinition> artifactsToUpload,
854 List<ArtifactDefinition> artifactsToUpdate,
855 List<ArtifactDefinition> artifactsToDelete) {
856 EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle = null;
857 if (!artifactsToUpload.isEmpty() || !artifactsToUpdate.isEmpty() || !artifactsToDelete.isEmpty()) {
858 nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
859 if (!artifactsToUpload.isEmpty()) {
860 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
862 if (!artifactsToUpdate.isEmpty()) {
863 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
865 if (!artifactsToDelete.isEmpty()) {
866 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
869 return nodeTypeArtifactsToHandle;
872 private void processExistingNodeTypeArtifacts(List<ArtifactDefinition> extractedArtifacts, List<ArtifactDefinition> artifactsToUpload,
873 List<ArtifactDefinition> artifactsToUpdate, List<ArtifactDefinition> artifactsToDelete,
874 Map<String, ArtifactDefinition> existingArtifacts) {
875 if (!existingArtifacts.isEmpty()) {
876 extractedArtifacts.forEach(a -> processNodeTypeArtifact(artifactsToUpload, artifactsToUpdate, existingArtifacts, a));
877 artifactsToDelete.addAll(existingArtifacts.values());
881 private void processNodeTypeArtifact(List<ArtifactDefinition> artifactsToUpload, List<ArtifactDefinition> artifactsToUpdate,
882 Map<String, ArtifactDefinition> existingArtifacts, ArtifactDefinition currNewArtifact) {
883 Optional<ArtifactDefinition> foundArtifact = existingArtifacts.values().stream()
884 .filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName())).findFirst();
885 if (foundArtifact.isPresent()) {
886 if (foundArtifact.get().getArtifactType().equals(currNewArtifact.getArtifactType())) {
887 updateFoundArtifact(artifactsToUpdate, currNewArtifact, foundArtifact.get());
888 existingArtifacts.remove(foundArtifact.get().getArtifactLabel());
889 artifactsToUpload.remove(currNewArtifact);
891 log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
892 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR,
893 currNewArtifact.getArtifactName(), currNewArtifact.getArtifactType(), foundArtifact.get().getArtifactType());
898 private void updateFoundArtifact(List<ArtifactDefinition> artifactsToUpdate, ArtifactDefinition currNewArtifact,
899 ArtifactDefinition foundArtifact) {
900 if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
901 foundArtifact.setPayload(currNewArtifact.getPayloadData());
902 foundArtifact.setPayloadData(Base64.encodeBase64String(currNewArtifact.getPayloadData()));
903 foundArtifact.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(currNewArtifact.getPayloadData()));
904 artifactsToUpdate.add(foundArtifact);
908 private Map<String, ArtifactDefinition> collectExistingArtifacts(Resource curNodeType) {
909 Map<String, ArtifactDefinition> existingArtifacts = new HashMap<>();
910 if (curNodeType == null) {
911 return existingArtifacts;
913 if (MapUtils.isNotEmpty(curNodeType.getDeploymentArtifacts())) {
914 existingArtifacts.putAll(curNodeType.getDeploymentArtifacts());
916 if (MapUtils.isNotEmpty(curNodeType.getArtifacts())) {
917 existingArtifacts.putAll(
918 curNodeType.getArtifacts().entrySet().stream().filter(e -> e.getValue().getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL)
919 .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)));
921 return existingArtifacts;
925 * Changes resource life cycle state to checked out
929 * @param inTransaction
932 private Either<Resource, ResponseFormat> checkoutResource(Resource resource, User user, boolean inTransaction) {
933 Either<Resource, ResponseFormat> checkoutResourceRes;
935 if (!resource.getComponentMetadataDefinition().getMetadataDataDefinition().getState()
936 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
937 log.debug("************* Going to change life cycle state of resource {} to not certified checked out. ", resource.getName());
938 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
939 .changeComponentState(resource.getComponentType(), resource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT,
940 new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT, LifecycleChanceActionEnum.CREATE_FROM_CSAR), inTransaction, true);
941 if (checkoutRes.isRight()) {
942 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ",
943 resource.getComponentType().getNodeType(), resource.getUniqueId(), checkoutRes.right().value().getStatus());
944 checkoutResourceRes = Either.right(checkoutRes.right().value());
946 checkoutResourceRes = Either.left((Resource) checkoutRes.left().value());
949 checkoutResourceRes = Either.left(resource);
951 } catch (Exception e) {
952 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
953 checkoutResourceRes = Either.right(responseFormat);
954 log.debug("Exception occurred when checkoutResource {} , error is:{}", resource.getName(), e.getMessage(), e);
956 return checkoutResourceRes;
960 * Handles Artifacts of NodeType
962 * @param nodeTypeResource
963 * @param nodeTypeArtifactsToHandle
965 * @param inTransaction
968 public Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifacts(Resource nodeTypeResource,
969 Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
970 List<ArtifactDefinition> createdArtifacts, User user,
971 boolean inTransaction, boolean ignoreLifecycleState) {
972 List<ArtifactDefinition> handleNodeTypeArtifactsRequestRes;
973 Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes = null;
974 Either<Resource, ResponseFormat> changeStateResponse;
976 changeStateResponse = checkoutResource(nodeTypeResource, user, inTransaction);
977 if (changeStateResponse.isRight()) {
978 return Either.right(changeStateResponse.right().value());
980 nodeTypeResource = changeStateResponse.left().value();
981 List<ArtifactDefinition> handledNodeTypeArtifacts = new ArrayList<>();
982 log.debug("************* Going to handle artifacts of node type resource {}. ", nodeTypeResource.getName());
983 for (Entry<ArtifactOperationEnum, List<ArtifactDefinition>> curOperationEntry : nodeTypeArtifactsToHandle.entrySet()) {
984 ArtifactOperationEnum curOperation = curOperationEntry.getKey();
985 List<ArtifactDefinition> curArtifactsToHandle = curOperationEntry.getValue();
986 if (curArtifactsToHandle != null && !curArtifactsToHandle.isEmpty()) {
987 log.debug("************* Going to {} artifact to vfc {}", curOperation.name(), nodeTypeResource.getName());
988 handleNodeTypeArtifactsRequestRes = artifactsBusinessLogic
989 .handleArtifactsRequestForInnerVfcComponent(curArtifactsToHandle, nodeTypeResource, user, createdArtifacts,
990 new ArtifactOperationInfo(false, ignoreLifecycleState, curOperation), false, inTransaction);
991 if (ArtifactOperationEnum.isCreateOrLink(curOperation)) {
992 createdArtifacts.addAll(handleNodeTypeArtifactsRequestRes);
994 handledNodeTypeArtifacts.addAll(handleNodeTypeArtifactsRequestRes);
997 handleNodeTypeArtifactsRes = Either.left(handledNodeTypeArtifacts);
998 } catch (Exception e) {
999 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1000 handleNodeTypeArtifactsRes = Either.right(responseFormat);
1001 log.debug("Exception occurred when handleVfcArtifacts, error is:{}", e.getMessage(), e);
1003 return handleNodeTypeArtifactsRes;
1006 private Map<String, ImmutablePair<String, String>> extractVfcToscaNames(final Map<String, NodeTypeInfo> nodeTypesInfo,
1007 final String vfResourceName, final CsarInfo csarInfo) {
1008 final Map<String, ImmutablePair<String, String>> vfcToscaNames = new HashMap<>();
1009 final Map<String, Object> nodes = extractAllNodes(nodeTypesInfo, csarInfo);
1010 if (!nodes.isEmpty()) {
1011 for (Entry<String, Object> nodeType : nodes.entrySet()) {
1012 final ImmutablePair<String, String> toscaResourceName = buildNestedToscaResourceName(ResourceTypeEnum.VFC.name(), vfResourceName,
1014 vfcToscaNames.put(nodeType.getKey(), toscaResourceName);
1017 for (final NodeTypeInfo cvfc : nodeTypesInfo.values()) {
1018 vfcToscaNames.put(cvfc.getType(), buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), vfResourceName, cvfc.getType()));
1020 return vfcToscaNames;
1023 private Map<String, Object> extractAllNodes(Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo) {
1024 Map<String, Object> nodes = new HashMap<>();
1025 for (NodeTypeInfo nodeTypeInfo : nodeTypesInfo.values()) {
1026 extractNodeTypes(nodes, nodeTypeInfo.getMappedToscaTemplate());
1028 extractNodeTypes(nodes, csarInfo.getMappedToscaMainTemplate());
1032 private void extractNodeTypes(Map<String, Object> nodes, Map<String, Object> mappedToscaTemplate) {
1033 Either<Map<String, Object>, ResultStatusEnum> eitherNodeTypes = ImportUtils
1034 .findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
1035 if (eitherNodeTypes.isLeft()) {
1036 nodes.putAll(eitherNodeTypes.left().value());
1040 public Resource createResourceFromCsar(Resource resource, User user, Map<String, byte[]> csarUIPayload, String csarUUID) {
1041 log.trace("************* created successfully from YAML, resource TOSCA ");
1042 loggerSupportability
1043 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.STARTED, "Starting to create Resource From Csar by user {}",
1045 CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID);
1046 Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
1047 final String model = resource.getModel();
1048 if (StringUtils.isNotEmpty(model)) {
1049 final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(model, csarInfo.getDataTypes());
1050 final Map<String, Object> policyTypesToCreate = getPolicytypesToCreate(model, csarInfo.getPolicyTypes());
1051 if (MapUtils.isNotEmpty(dataTypesToCreate) || MapUtils.isNotEmpty(policyTypesToCreate)) {
1052 createModel(resource, csarInfo.getVfResourceName());
1054 if (MapUtils.isNotEmpty(dataTypesToCreate)) {
1055 dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), model, true);
1057 if (MapUtils.isNotEmpty(policyTypesToCreate)) {
1058 policyTypeBusinessLogic.createPolicyTypeFromYaml(new Yaml().dump(policyTypesToCreate), model, true);
1062 Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
1063 nodeTypesInfo, csarInfo, resource);
1064 if (findNodeTypesArtifactsToHandleRes.isRight()) {
1065 log.debug("failed to find node types for update with artifacts during import csar {}. ", csarInfo.getCsarUUID());
1066 loggerSupportability
1067 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1068 "error: {}", findNodeTypesArtifactsToHandleRes.right().value());
1069 throw new ByResponseFormatComponentException(findNodeTypesArtifactsToHandleRes.right().value());
1071 Resource vfResource = createResourceFromYaml(resource, csarInfo.getMainTemplateContent(), csarInfo.getMainTemplateName(), nodeTypesInfo,
1072 csarInfo, findNodeTypesArtifactsToHandleRes.left().value(), true, false, null);
1073 log.trace("*************VF Resource created successfully from YAML, resource TOSCA name: {}", vfResource.getToscaResourceName());
1074 loggerSupportability
1075 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.COMPLETE, "Ended create Resource From Csar by user {}",
1080 private Resource validateResourceBeforeCreate(Resource resource, User user, boolean inTransaction) {
1081 log.trace("validating resource before create");
1082 user.copyData(validateUser(user, CREATE_RESOURCE, resource, AuditingActionEnum.CREATE_RESOURCE, false));
1083 // validate user role
1084 validateUserRole(user, resource, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
1085 // VF / PNF "derivedFrom" should be null (or ignored)
1086 if (ModelConverter.isAtomicComponent(resource)) {
1087 validateDerivedFromNotEmpty(user, resource, AuditingActionEnum.CREATE_RESOURCE);
1089 return validateResourceBeforeCreate(resource, user, AuditingActionEnum.CREATE_RESOURCE, inTransaction, null);
1092 private Resource createResourceFromYaml(Resource resource, String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo,
1094 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1095 boolean shouldLock, boolean inTransaction, String nodeName) {
1096 List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
1097 Resource createdResource;
1099 ParsedToscaYamlInfo parsedToscaYamlInfo = csarBusinessLogic
1100 .getParsedToscaYamlInfo(topologyTemplateYaml, yamlName, nodeTypesInfo, csarInfo, nodeName, resource);
1101 if (MapUtils.isEmpty(parsedToscaYamlInfo.getInstances()) && resource.getResourceType() != ResourceTypeEnum.PNF) {
1102 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
1104 log.debug("#createResourceFromYaml - Going to create resource {} and RIs ", resource.getName());
1105 loggerSupportability
1106 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED, "");
1107 createdResource = createResourceAndRIsFromYaml(yamlName, resource, parsedToscaYamlInfo, AuditingActionEnum.IMPORT_RESOURCE, false,
1108 createdArtifacts, topologyTemplateYaml, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, shouldLock, inTransaction, nodeName);
1109 log.debug("#createResourceFromYaml - The resource {} has been created ", resource.getName());
1110 loggerSupportability
1111 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1112 "The resource has been created: {}", resource.getName());
1113 } catch (ComponentException e) {
1114 ResponseFormat responseFormat =
1115 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
1116 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
1118 } catch (StorageException e) {
1119 ResponseFormat responseFormat = componentsUtils
1120 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
1121 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
1124 return createdResource;
1127 public Map<String, Resource> createResourcesFromYamlNodeTypesList(String yamlName, Resource resource, Map<String, Object> mappedToscaTemplate,
1129 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
1130 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1131 Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1132 final String substitutableAsNodeType) {
1133 Either<String, ResultStatusEnum> toscaVersion = findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
1134 if (toscaVersion.isRight()) {
1135 throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE);
1137 Map<String, Object> mapToConvert = new HashMap<>();
1138 mapToConvert.put(TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION.getElementName(), toscaVersion.left().value());
1139 final Map<String, Object> nodeTypes = getNodeTypesFromTemplate(mappedToscaTemplate, substitutableAsNodeType);
1140 createNodeTypes(yamlName, resource, needLock, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, mapToConvert,
1142 return csarInfo.getCreatedNodes();
1145 private Map<String, Object> getNodeTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, final String substitutableAsNodeType) {
1146 final Map<String, Object> nodeTypes = getAllNodeTypesInTemplate(mappedToscaTemplate);
1147 if (StringUtils.isNotEmpty(substitutableAsNodeType)) {
1148 nodeTypes.remove(substitutableAsNodeType);
1153 @SuppressWarnings("unchecked")
1154 private Map<String, Object> getSubstitutableAsNodeTypeFromTemplate(final Map<String, Object> mappedToscaTemplate,
1155 final String substitutableAsNodeType) {
1156 return (Map<String, Object>) getAllNodeTypesInTemplate(mappedToscaTemplate).get(substitutableAsNodeType);
1159 private Map<String, Object> getAllNodeTypesInTemplate(final Map<String, Object> mappedToscaTemplate) {
1160 return ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES).left().orValue(HashMap::new);
1163 private void createModel(final Resource resource, final String vfResourcename) {
1164 final String nameForGeneratedModel = resource.getModel() + "_" + vfResourcename + resource.getCsarVersion();
1165 Model model = new Model(nameForGeneratedModel, resource.getModel(), ModelTypeEnum.NORMATIVE_EXTENSION);
1166 modelBusinessLogic.createModel(model);
1167 resource.setModel(nameForGeneratedModel);
1170 private Map<String, Object> getDatatypesToCreate(final String model, final Map<String, Object> dataTypes) {
1171 final Map<String, Object> dataTypesToCreate = new HashMap<>();
1172 for (final String dataType : dataTypes.keySet()) {
1173 final Either<DataTypeDefinition, StorageOperationStatus> result =
1174 propertyOperation.getDataTypeByName(dataType, model);
1175 if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
1176 dataTypesToCreate.put(dataType, dataTypes.get(dataType));
1179 return dataTypesToCreate;
1182 private Map<String, Object> getPolicytypesToCreate(final String model, final Map<String, Object> policyTypes) {
1183 final Map<String, Object> policyTypesToCreate = new HashMap<>();
1184 for (final String policyType : policyTypes.keySet()) {
1185 final Either<PolicyTypeDefinition, StorageOperationStatus> result =
1186 policyTypeOperation.getLatestPolicyTypeByType(policyType, model);
1187 if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
1188 policyTypesToCreate.put(policyType, policyTypes.get(policyType));
1191 return policyTypesToCreate;
1194 private void createNodeTypes(String yamlName, Resource resource, boolean needLock,
1195 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
1196 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1197 Map<String, Object> mapToConvert, Map<String, Object> nodeTypes) {
1198 Iterator<Entry<String, Object>> nodesNameValueIter = nodeTypes.entrySet().iterator();
1199 Resource vfcCreated = null;
1200 while (nodesNameValueIter.hasNext()) {
1201 Entry<String, Object> nodeType = nodesNameValueIter.next();
1202 Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle =
1203 nodeTypesArtifactsToHandle == null || nodeTypesArtifactsToHandle.isEmpty() ? null : nodeTypesArtifactsToHandle.get(nodeType.getKey());
1204 if (nodeTypesInfo.containsKey(nodeType.getKey())) {
1205 log.trace("************* Going to handle nested vfc {}", nodeType.getKey());
1206 vfcCreated = handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
1208 log.trace("************* Finished to handle nested vfc {}", nodeType.getKey());
1209 } else if (csarInfo.getCreatedNodesToscaResourceNames() != null && !csarInfo.getCreatedNodesToscaResourceNames()
1210 .containsKey(nodeType.getKey())) {
1211 log.trace("************* Going to create node {}", nodeType.getKey());
1212 ImmutablePair<Resource, ActionStatus> resourceCreated = createNodeTypeResourceFromYaml(yamlName, nodeType, csarInfo.getModifier(),
1213 mapToConvert, resource, needLock, nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, true, csarInfo, true);
1214 log.debug("************* Finished to create node {}", nodeType.getKey());
1215 vfcCreated = resourceCreated.getLeft();
1216 csarInfo.getCreatedNodesToscaResourceNames().put(nodeType.getKey(), vfcCreated.getToscaResourceName());
1218 if (vfcCreated != null) {
1219 csarInfo.getCreatedNodes().put(nodeType.getKey(), vfcCreated);
1221 mapToConvert.remove(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName());
1225 private Resource handleNestedVfc(Resource resource, Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1226 List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1228 String yamlName = nodesInfo.get(nodeName).getTemplateFileName();
1229 Map<String, Object> nestedVfcJsonMap = nodesInfo.get(nodeName).getMappedToscaTemplate();
1230 log.debug("************* Going to create node types from yaml {}", yamlName);
1231 createResourcesFromYamlNodeTypesList(yamlName, resource, nestedVfcJsonMap, false, nodesArtifactsToHandle, createdArtifacts,
1232 Collections.emptyMap(), csarInfo, resource.getModel());
1233 log.debug("************* Finished to create node types from yaml {}", yamlName);
1234 if (nestedVfcJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE.getElementName())) {
1235 log.debug("************* Going to handle complex VFC from yaml {}", yamlName);
1236 resource = handleComplexVfc(resource, nodesArtifactsToHandle, createdArtifacts, nodesInfo, csarInfo, nodeName, yamlName);
1241 private Resource handleComplexVfc(final Resource resource,
1242 final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1243 final List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1244 final String nodeName, final String yamlName) {
1245 Resource oldComplexVfc = null;
1246 Resource newComplexVfc = buildValidComplexVfc(resource, csarInfo, nodeName, nodesInfo);
1247 Either<Resource, StorageOperationStatus> oldComplexVfcRes = toscaOperationFacade
1248 .getFullLatestComponentByToscaResourceName(newComplexVfc.getToscaResourceName());
1249 if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() == StorageOperationStatus.NOT_FOUND) {
1250 oldComplexVfcRes = toscaOperationFacade.getFullLatestComponentByToscaResourceName(
1251 buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getRight());
1253 if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() != StorageOperationStatus.NOT_FOUND) {
1254 log.debug("Failed to fetch previous complex VFC by tosca resource name {}. Status is {}. ", newComplexVfc.getToscaResourceName(),
1255 oldComplexVfcRes.right().value());
1256 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1257 } else if (oldComplexVfcRes.isLeft()) {
1258 log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
1259 final Either<Boolean, ResponseFormat> eitherValidation = validateNestedDerivedFromDuringUpdate(oldComplexVfcRes.left().value(),
1260 newComplexVfc, ValidationUtils.hasBeenCertified(oldComplexVfcRes.left().value().getVersion()));
1261 if (eitherValidation.isLeft()) {
1262 oldComplexVfc = oldComplexVfcRes.left().value();
1265 newComplexVfc = handleComplexVfc(nodesArtifactsToHandle, createdArtifacts, nodesInfo, csarInfo, nodeName, yamlName, oldComplexVfc,
1267 csarInfo.getCreatedNodesToscaResourceNames().put(nodeName, newComplexVfc.getToscaResourceName());
1268 final LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT,
1269 LifecycleChanceActionEnum.CREATE_FROM_CSAR);
1270 log.debug("Going to certify cvfc {}. ", newComplexVfc.getName());
1271 final Resource result = propagateStateToCertified(csarInfo.getModifier(), newComplexVfc, lifecycleChangeInfo, true, false, true);
1272 csarInfo.getCreatedNodes().put(nodeName, result);
1273 csarInfo.removeNodeFromQueue();
1277 private Resource handleComplexVfc(Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1278 List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1279 String nodeName, String yamlName, Resource oldComplexVfc, Resource newComplexVfc) {
1280 Resource handleComplexVfcRes;
1281 Map<String, Object> mappedToscaTemplate = nodesInfo.get(nodeName).getMappedToscaTemplate();
1282 String yamlContent = new String(csarInfo.getCsar().get(yamlName));
1283 Map<String, NodeTypeInfo> newNodeTypesInfo = nodesInfo.entrySet().stream().collect(toMap(Entry::getKey, e -> e.getValue().getUnmarkedCopy()));
1284 CsarInfo.markNestedVfc(mappedToscaTemplate, newNodeTypesInfo);
1285 if (oldComplexVfc == null) {
1286 handleComplexVfcRes = createResourceFromYaml(newComplexVfc, yamlContent, yamlName, newNodeTypesInfo, csarInfo, nodesArtifactsToHandle,
1287 false, true, nodeName);
1289 handleComplexVfcRes = updateResourceFromYaml(oldComplexVfc, newComplexVfc, AuditingActionEnum.UPDATE_RESOURCE_METADATA, createdArtifacts,
1290 yamlContent, yamlName, csarInfo, newNodeTypesInfo, nodesArtifactsToHandle, nodeName, true);
1292 return handleComplexVfcRes;
1295 private Resource buildValidComplexVfc(Resource resource, CsarInfo csarInfo, String nodeName, Map<String, NodeTypeInfo> nodesInfo) {
1296 Resource complexVfc = buildComplexVfcMetadata(resource, csarInfo, nodeName, nodesInfo);
1297 log.debug("************* Going to validate complex VFC from yaml {}", complexVfc.getName());
1298 csarInfo.addNodeToQueue(nodeName);
1299 return validateResourceBeforeCreate(complexVfc, csarInfo.getModifier(), AuditingActionEnum.IMPORT_RESOURCE, true, csarInfo);
1302 private String getNodeTypeActualName(final String nodeTypefullName, final String nodeTypeNamePrefix) {
1303 final String nameWithouNamespacePrefix = nodeTypefullName.substring(nodeTypeNamePrefix.length());
1304 final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
1305 if (findTypes.length > 1) {
1306 final String resourceType = findTypes[0];
1307 return nameWithouNamespacePrefix.substring(resourceType.length());
1309 return nameWithouNamespacePrefix;
1312 private ImmutablePair<Resource, ActionStatus> createNodeTypeResourceFromYaml(final String yamlName, final Entry<String, Object> nodeNameValue,
1313 User user, final Map<String, Object> mapToConvert,
1314 final Resource resourceVf, final boolean needLock,
1315 final Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
1316 final List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1317 final boolean forceCertificationAllowed, final CsarInfo csarInfo,
1318 final boolean isNested) {
1319 final UploadResourceInfo resourceMetaData = fillResourceMetadata(yamlName, resourceVf, nodeNameValue.getKey(), user);
1320 final String singleVfcYaml = buildNodeTypeYaml(nodeNameValue, mapToConvert, resourceMetaData.getResourceType(), csarInfo);
1321 user = validateUser(user, "CheckIn Resource", resourceVf, AuditingActionEnum.CHECKIN_RESOURCE, true);
1322 return createResourceFromNodeType(singleVfcYaml, resourceMetaData, user, true, needLock, nodeTypeArtifactsToHandle,
1323 nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeNameValue.getKey(), isNested);
1326 private String buildNodeTypeYaml(final Entry<String, Object> nodeNameValue, final Map<String, Object> mapToConvert, final String nodeResourceType,
1327 final CsarInfo csarInfo) {
1328 // We need to create a Yaml from each node_types in order to create
1330 // resource from each node type using import normative flow.
1331 final DumperOptions options = new DumperOptions();
1332 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
1333 final Yaml yaml = new Yaml(options);
1334 final Map<String, Object> node = new HashMap<>();
1335 node.put(buildNestedToscaResourceName(nodeResourceType, csarInfo.getVfResourceName(), nodeNameValue.getKey()).getLeft(),
1336 nodeNameValue.getValue());
1337 mapToConvert.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), node);
1338 return yaml.dumpAsMap(mapToConvert);
1341 public Boolean validateResourceCreationFromNodeType(Resource resource, User creator) {
1342 validateDerivedFromNotEmpty(creator, resource, AuditingActionEnum.CREATE_RESOURCE);
1346 public ImmutablePair<Resource, ActionStatus> createResourceFromNodeType(String nodeTypeYaml, UploadResourceInfo resourceMetaData, User creator,
1347 boolean isInTransaction, boolean needLock,
1348 Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
1349 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1350 boolean forceCertificationAllowed, CsarInfo csarInfo, String nodeName,
1352 LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT,
1353 LifecycleChanceActionEnum.CREATE_FROM_CSAR);
1354 Function<Resource, Boolean> validator = resource -> validateResourceCreationFromNodeType(resource, creator);
1355 return resourceImportManager
1356 .importCertifiedResource(nodeTypeYaml, resourceMetaData, creator, validator, lifecycleChangeInfo, isInTransaction, true, needLock,
1357 nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeName, isNested);
1361 * Validates if a given node type name has a valid prefix.
1363 * @param nodeName node name from definition file
1364 * @param definedResourceNamespaceList is a list of all node type name prefix allowed
1365 * @return a valid node type name prefix if it`s found
1367 public Optional<String> validateNodeTypeNamePrefix(final String nodeName, final List<String> definedResourceNamespaceList) {
1368 for (final String validNamespace : definedResourceNamespaceList) {
1369 if (nodeName.startsWith(validNamespace)) {
1370 return Optional.of(validNamespace);
1373 return Optional.empty();
1376 private List<String> getDefinedNodeTypeNamespaceList() {
1377 return ConfigurationManager.getConfigurationManager().getConfiguration().getDefinedResourceNamespace();
1380 private UploadResourceInfo fillResourceMetadata(final String yamlName, final Resource resourceVf, final String nodeName, final User user) {
1381 final UploadResourceInfo resourceMetaData = new UploadResourceInfo();
1382 final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeName);
1383 log.debug("Node type Name prefix {}", nodeTypeNamePrefix);
1384 if (!nodeName.startsWith(nodeTypeNamePrefix)) {
1385 log.debug("invalid nodeName:{} does not start with {}.", nodeName, getDefinedNodeTypeNamespaceList());
1386 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeName);
1388 final String actualName = this.getNodeTypeActualName(nodeName, nodeTypeNamePrefix);
1389 final String namePrefix = nodeName.replace(actualName, "");
1390 String resourceType = namePrefix.substring(nodeTypeNamePrefix.length());
1391 log.debug("initial namePrefix:{} resourceType {}. nodeName {} , actualName {} prefix {}", namePrefix, resourceType, nodeName, actualName,
1392 nodeTypeNamePrefix);
1393 // if we import from csar, the node_type name can be
1395 // org.openecomp.resource.abstract.node_name - in this case we always
1398 if (resourceType.equals(Constants.ABSTRACT)) {
1399 resourceType = ResourceTypeEnum.VFC.name().toLowerCase();
1401 if (!ResourceTypeEnum.containsIgnoreCase(resourceType)) {
1402 resourceType = ResourceTypeEnum.VFC.name().toLowerCase();
1405 if (!ResourceTypeEnum.containsName(resourceType.toUpperCase())) {
1406 log.debug("invalid resourceType:{} the type is not one of the valide types:{}.", resourceType.toUpperCase(), ResourceTypeEnum.values());
1407 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeName);
1410 resourceMetaData.setName(resourceVf.getSystemName() + actualName);
1411 // Setting type from name
1412 final String type = resourceType.toUpperCase();
1413 resourceMetaData.setResourceType(type);
1414 resourceMetaData.setDescription(ImportUtils.Constants.INNER_VFC_DESCRIPTION);
1415 resourceMetaData.setIcon(ImportUtils.Constants.DEFAULT_ICON);
1416 resourceMetaData.setContactId(user.getUserId());
1417 resourceMetaData.setVendorName(resourceVf.getVendorName());
1418 resourceMetaData.setVendorRelease(resourceVf.getVendorRelease());
1419 resourceMetaData.setModel(resourceVf.getModel());
1421 final List<String> tags = new ArrayList<>();
1422 tags.add(resourceMetaData.getName());
1423 resourceMetaData.setTags(tags);
1425 final CategoryDefinition category = new CategoryDefinition();
1426 category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME);
1427 final SubCategoryDefinition subCategory = new SubCategoryDefinition();
1428 subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY);
1429 category.addSubCategory(subCategory);
1430 final List<CategoryDefinition> categories = new ArrayList<>();
1431 categories.add(category);
1432 resourceMetaData.setCategories(categories);
1433 return resourceMetaData;
1436 private Resource buildComplexVfcMetadata(final Resource resourceVf, final CsarInfo csarInfo, final String nodeName,
1437 final Map<String, NodeTypeInfo> nodesInfo) {
1438 final Resource cvfc = new Resource();
1439 final NodeTypeInfo nodeTypeInfo = nodesInfo.get(nodeName);
1440 cvfc.setName(buildCvfcName(csarInfo.getVfResourceName(), nodeName));
1441 cvfc.setNormalizedName(ValidationUtils.normaliseComponentName(cvfc.getName()));
1442 cvfc.setSystemName(ValidationUtils.convertToSystemName(cvfc.getName()));
1443 cvfc.setResourceType(ResourceTypeEnum.CVFC);
1444 cvfc.setAbstract(true);
1445 cvfc.setDerivedFrom(nodeTypeInfo.getDerivedFrom());
1446 cvfc.setDescription(ImportUtils.Constants.CVFC_DESCRIPTION);
1447 cvfc.setIcon(ImportUtils.Constants.DEFAULT_ICON);
1448 cvfc.setContactId(csarInfo.getModifier().getUserId());
1449 cvfc.setCreatorUserId(csarInfo.getModifier().getUserId());
1450 cvfc.setVendorName(resourceVf.getVendorName());
1451 cvfc.setVendorRelease(resourceVf.getVendorRelease());
1452 cvfc.setModel(resourceVf.getModel());
1453 cvfc.setResourceVendorModelNumber(resourceVf.getResourceVendorModelNumber());
1454 cvfc.setToscaResourceName(buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getLeft());
1455 cvfc.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
1456 final List<String> tags = new ArrayList<>();
1457 tags.add(cvfc.getName());
1459 final CategoryDefinition category = new CategoryDefinition();
1460 category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME);
1461 SubCategoryDefinition subCategory = new SubCategoryDefinition();
1462 subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY);
1463 category.addSubCategory(subCategory);
1464 final List<CategoryDefinition> categories = new ArrayList<>();
1465 categories.add(category);
1466 cvfc.setCategories(categories);
1467 cvfc.setVersion(ImportUtils.Constants.FIRST_NON_CERTIFIED_VERSION);
1468 cvfc.setLifecycleState(ImportUtils.Constants.NORMATIVE_TYPE_LIFE_CYCLE_NOT_CERTIFIED_CHECKOUT);
1469 cvfc.setHighestVersion(ImportUtils.Constants.NORMATIVE_TYPE_HIGHEST_VERSION);
1473 private String buildCvfcName(final String resourceVfName, final String nodeName) {
1474 String nameWithouNamespacePrefix = nodeName.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length());
1475 String[] findTypes = nameWithouNamespacePrefix.split("\\.");
1476 String resourceType = findTypes[0];
1477 String resourceName = resourceVfName + "-" + nameWithouNamespacePrefix.substring(resourceType.length() + 1);
1478 return addCvfcSuffixToResourceName(resourceName);
1481 private Resource createResourceAndRIsFromYaml(final String yamlName, Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo,
1482 final AuditingActionEnum actionEnum, final boolean isNormative,
1483 final List<ArtifactDefinition> createdArtifacts, final String topologyTemplateYaml,
1484 final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo,
1485 final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1486 final boolean shouldLock, final boolean inTransaction, final String nodeName) {
1487 final List<ArtifactDefinition> nodeTypesNewCreatedArtifacts = new ArrayList<>();
1489 final Either<Boolean, ResponseFormat> lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE);
1490 if (lockResult.isRight()) {
1491 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1492 throw new ByResponseFormatComponentException(lockResult.right().value());
1494 log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult);
1497 log.trace("************* createResourceFromYaml before full create resource {}", yamlName);
1498 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1499 "Starting to add inputs from yaml: {}", yamlName);
1500 if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
1501 final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
1502 (Map<String, Object>) new Yaml().load(topologyTemplateYaml), parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1503 resource.setToscaResourceName(parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1504 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
1505 (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
1506 resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
1507 generatePropertiesFromGenericType(resource, genericResource);
1508 generatePropertiesFromNodeType(resource, substitutableAsNodeType);
1509 final String resourceId = resource.getUniqueId();
1510 resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
1511 UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
1513 createResourcePropertiesOnGraph(resource);
1514 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo, resource.getModel());
1516 log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName);
1517 loggerSupportability
1518 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1519 "Start create nodes, RI and Relations from yaml: {}", yamlName);
1520 resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
1521 nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName,
1522 parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1524 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource, null);
1525 resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
1526 log.trace("************* createResourceFromYaml after full create resource {}", yamlName);
1527 log.trace("************* Going to add inputs from yaml {}", yamlName);
1528 if (resource.shouldGenerateInputs()) {
1529 generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
1531 final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs();
1532 resource = createInputsOnResource(resource, inputs);
1534 log.trace("************* Finish to add inputs from yaml {}", yamlName);
1535 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1536 "Finish to add inputs from yaml: {}", yamlName);
1537 if (resource.getResourceType() == ResourceTypeEnum.PNF) {
1538 log.trace("************* Adding generic properties to PNF");
1539 resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties());
1540 log.trace("************* Adding software information to PNF");
1541 softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo);
1542 log.trace("************* Removing non-mano software information file from PNF");
1543 if (csarInfo.getSoftwareInformationPath().isPresent() && !softwareInformationBusinessLogic.removeSoftwareInformationFile(
1545 log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), "catalog-be",
1546 "Could not remove the software information file.");
1549 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo);
1551 log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName);
1552 loggerSupportability
1553 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1554 "Start create nodes, RI and Relations from yaml: {}", yamlName);
1555 resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
1556 nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName, null);
1558 log.trace("************* Finished to create nodes, RI and Relation from yaml {}", yamlName);
1559 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1560 "Finished to create nodes, RI and Relation from yaml: {}", yamlName);
1561 // validate update vf module group names
1562 Optional<Map<String, GroupDefinition>> asdGroups = checkAndCreateAsdTypeVfModules(parsedToscaYamlInfo.getInstances());
1563 Map<String, GroupDefinition> parsedGroups = parsedToscaYamlInfo.getGroups();
1564 if (asdGroups.isPresent()) {
1565 parsedGroups.putAll(asdGroups.get());
1567 final Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic
1568 .validateUpdateVfGroupNames(parsedGroups, resource.getSystemName());
1569 if (validateUpdateVfGroupNamesRes.isRight()) {
1570 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1571 throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value());
1573 // add groups to resource
1574 final Map<String, GroupDefinition> groups;
1575 log.trace("************* Going to add groups from yaml {}", yamlName);
1576 loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1577 "Start to add groups from yaml: {}", yamlName);
1578 if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) {
1579 groups = validateUpdateVfGroupNamesRes.left().value();
1581 groups = parsedGroups;
1583 final Either<Resource, ResponseFormat> createGroupsOnResource = createGroupsOnResource(resource, groups);
1584 if (createGroupsOnResource.isRight()) {
1585 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1586 loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1587 "ERROR while adding groups from yaml: {}", yamlName);
1588 throw new ByResponseFormatComponentException(createGroupsOnResource.right().value());
1590 resource = createGroupsOnResource.left().value();
1591 log.trace("************* Finished to add groups from yaml {}", yamlName);
1592 loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1593 "Finished to add groups from yaml: {}", yamlName);
1594 log.trace("************* Going to add artifacts from yaml {}", yamlName);
1595 loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1596 "Started to add artifacts from yaml: {}", yamlName);
1597 log.trace("************* Starting to add policies from yaml {}", yamlName);
1598 Map<String, PolicyDefinition> policies = parsedToscaYamlInfo.getPolicies();
1599 if (MapUtils.isNotEmpty(policies)) {
1600 resource = createPoliciesOnResource(resource, policies);
1602 log.trace("************* Finished to add policies from yaml {}", yamlName);
1603 final NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName,
1604 nodeTypesArtifactsToCreate);
1605 final Either<Resource, ResponseFormat> createArtifactsEither = createOrUpdateArtifacts(ArtifactOperationEnum.CREATE, createdArtifacts,
1606 yamlName, csarInfo, resource, nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock);
1607 if (createArtifactsEither.isRight()) {
1608 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1609 loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1610 "error happened {}", createArtifactsEither.right().value());
1611 throw new ByResponseFormatComponentException(createArtifactsEither.right().value());
1613 loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1614 "Finished to add artifacts from yaml: " + resource.getToscaResourceName());
1615 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
1616 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, actionEnum);
1617 ASDCKpiApi.countCreatedResourcesKPI();
1619 } catch (final BusinessLogicException e) {
1620 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(),
1621 "An error has occurred during resource and resource instance creation", e);
1622 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1623 throw new ByResponseFormatComponentException(e.getResponseFormat());
1624 } catch (final ComponentException e) {
1625 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ResourceBusinessLogic.class.getName(),
1626 "An error has occurred during resource and resource instance creation", e);
1627 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1628 throw new ByResponseFormatComponentException(e.getResponseFormat());
1629 } catch (final Exception e) {
1630 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(),
1631 "An error has occurred during resource and resource instance creation", e);
1632 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1633 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1635 if (!inTransaction) {
1636 janusGraphDao.commit();
1639 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
1644 private Optional<Map<String, GroupDefinition>> checkAndCreateAsdTypeVfModules(Map<String, UploadComponentInstanceInfo> instances) {
1645 Map<String, GroupDefinition> addAsdGroups = new HashMap<>();
1646 if (isNotEmpty(instances) || instances != null) {
1647 for (Map.Entry<String, UploadComponentInstanceInfo> instance : instances.entrySet()) {
1648 if (isNotEmpty(instance.getValue().getArtifacts()) || instance.getValue().getArtifacts() != null) {
1649 Map<String, UploadArtifactInfo> artifactsMap = instance.getValue().getArtifacts()
1650 .get(ToscaTagNamesEnum.ARTIFACTS.getElementName());
1651 if (isNotEmpty(artifactsMap) || artifactsMap != null) {
1652 for (Map.Entry<String , UploadArtifactInfo> artifact : artifactsMap.entrySet()) {
1653 if (artifact.getValue().getType().equals(Constants.ASD_DEPLOYMENT_ITEM)) {
1654 GroupDefinition groupDefinition = new GroupDefinition();
1655 groupDefinition.setName(artifact.getKey());
1656 groupDefinition.setType(Constants.DEFAULT_GROUP_VF_MODULE);
1657 addAsdTypeProperties(groupDefinition);
1658 addAsdGroups.put(groupDefinition.getName(), groupDefinition);
1665 return Optional.of(addAsdGroups);
1668 private void addAsdTypeProperties(GroupDefinition groupDefinition) {
1669 List<GroupProperty> properties = new ArrayList<>();
1670 GroupProperty propIsBase = new GroupProperty();
1671 propIsBase.setName(Constants.IS_BASE);
1672 propIsBase.setValue("true");
1673 properties.add(propIsBase);
1674 GroupProperty propVfModuleLabel = new GroupProperty();
1675 propVfModuleLabel.setName(Constants.VF_MODULE_LABEL);
1676 propVfModuleLabel.setValue(groupDefinition.getName());
1677 properties.add(propVfModuleLabel);
1678 GroupProperty propVfModuleDescription = new GroupProperty();
1679 propVfModuleDescription.setName(Constants.VF_MODULE_DESCRIPTION);
1680 propVfModuleDescription.setValue("VF Module representing deployment item " + groupDefinition.getName());
1681 properties.add(propVfModuleDescription);
1682 GroupProperty propMinVfModuleInstances = new GroupProperty();
1683 propMinVfModuleInstances.setName(Constants.MIN_VF_MODULE_INSTANCES);
1684 propMinVfModuleInstances.setValue("1");
1685 properties.add(propMinVfModuleInstances);
1686 GroupProperty propMaxVfModuleInstances = new GroupProperty();
1687 propMaxVfModuleInstances.setName(Constants.MAX_VF_MODULE_INSTANCES);
1688 propMaxVfModuleInstances.setValue("1");
1689 properties.add(propMaxVfModuleInstances);
1690 GroupProperty propInitialCount = new GroupProperty();
1691 propInitialCount.setName(Constants.INITIAL_COUNT);
1692 propInitialCount.setValue("1");
1693 properties.add(propInitialCount);
1694 GroupProperty propVfModuleType = new GroupProperty();
1695 propVfModuleType.setName(Constants.VF_MODULE_TYPE);
1696 propVfModuleType.setValue("Base");
1697 properties.add(propVfModuleType);
1698 GroupProperty propVolumeGroup = new GroupProperty();
1699 propVolumeGroup.setName(Constants.VOLUME_GROUP);
1700 propVolumeGroup.setValue("false");
1701 properties.add(propVolumeGroup);
1702 groupDefinition.convertFromGroupProperties(properties);
1705 private boolean processSubstitutableAsNodeType(final Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo) {
1706 return !resource.getResourceType().isAtomicType() && StringUtils.isNotEmpty(resource.getModel())
1707 && parsedToscaYamlInfo.getSubstitutionMappingNodeType() != null;
1710 private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo) {
1711 return getInstancesToCreate(parsedToscaYamlInfo, null);
1714 private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo, final String model) {
1715 if (StringUtils.isEmpty(model) || StringUtils.isEmpty(parsedToscaYamlInfo.getSubstitutionMappingNodeType())) {
1716 return parsedToscaYamlInfo.getInstances();
1718 return parsedToscaYamlInfo.getInstances().entrySet().stream()
1719 .filter(entry -> !parsedToscaYamlInfo.getSubstitutionMappingNodeType().equals(entry.getValue().getType()))
1720 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
1723 private void rollback(boolean inTransaction, Resource resource, List<ArtifactDefinition> createdArtifacts,
1724 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts) {
1725 if (!inTransaction) {
1726 janusGraphDao.rollback();
1728 if (isNotEmpty(createdArtifacts) && isNotEmpty(nodeTypesNewCreatedArtifacts)) {
1729 createdArtifacts.addAll(nodeTypesNewCreatedArtifacts);
1730 log.debug("Found {} newly created artifacts to deleted, the component name: {}", createdArtifacts.size(), resource.getName());
1734 private Resource getResourceWithGroups(String resourceId) {
1735 ComponentParametersView filter = new ComponentParametersView();
1736 filter.setIgnoreGroups(false);
1737 Either<Resource, StorageOperationStatus> updatedResource = toscaOperationFacade.getToscaElement(resourceId, filter);
1738 if (updatedResource.isRight()) {
1739 rollbackWithException(componentsUtils.convertFromStorageResponse(updatedResource.right().value()), resourceId);
1741 return updatedResource.left().value();
1744 private Either<Resource, ResponseFormat> createGroupsOnResource(Resource resource, Map<String, GroupDefinition> groups) {
1745 if (groups != null && !groups.isEmpty()) {
1746 List<GroupDefinition> groupsAsList = updateGroupsMembersUsingResource(groups, resource);
1747 handleGroupsProperties(resource, groups);
1748 fillGroupsFinalFields(groupsAsList);
1749 Either<List<GroupDefinition>, ResponseFormat> createGroups = groupBusinessLogic.createGroups(resource, groupsAsList, true);
1750 if (createGroups.isRight()) {
1751 return Either.right(createGroups.right().value());
1754 return Either.left(resource);
1757 private void handleGroupsProperties(Resource resource, Map<String, GroupDefinition> groups) {
1758 List<InputDefinition> inputs = resource.getInputs();
1759 if (MapUtils.isNotEmpty(groups)) {
1760 groups.values().stream().filter(g -> isNotEmpty(g.getProperties())).flatMap(g -> g.getProperties().stream())
1761 .forEach(p -> handleGetInputs(p, inputs));
1765 private Resource createPoliciesOnResource(Resource resource, Map<String, PolicyDefinition> policies) {
1766 policyBusinessLogic.createPoliciesFromParsedCsar(resource, policies);
1770 private void handleGetInputs(PropertyDataDefinition property, List<InputDefinition> inputs) {
1771 if (isNotEmpty(property.getGetInputValues())) {
1772 if (inputs == null || inputs.isEmpty()) {
1773 log.debug("Failed to add property {} to group. Inputs list is empty ", property);
1774 rollbackWithException(ActionStatus.INPUTS_NOT_FOUND,
1775 property.getGetInputValues().stream().map(GetInputValueDataDefinition::getInputName).collect(toList()).toString());
1777 ListIterator<GetInputValueDataDefinition> getInputValuesIter = property.getGetInputValues().listIterator();
1778 while (getInputValuesIter.hasNext()) {
1779 GetInputValueDataDefinition getInput = getInputValuesIter.next();
1780 Either<InputDefinition, RuntimeException> inputEither = findInputByName(inputs, getInput);
1781 if (inputEither.isRight()) {
1782 throw inputEither.right().value();
1784 InputDefinition input = inputEither.left().value();
1785 getInput.setInputId(input.getUniqueId());
1786 if (getInput.getGetInputIndex() != null) {
1787 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
1788 Either<InputDefinition, RuntimeException> newInputEither = findInputByName(inputs, getInputIndex);
1789 if (newInputEither.isRight()) {
1790 throw newInputEither.right().value();
1792 InputDefinition newInput = newInputEither.left().value();
1793 getInputIndex.setInputId(newInput.getUniqueId());
1795 getInputValuesIter.add(getInputIndex);
1802 <T> Either<T, RuntimeException> rollbackWithEither(final ActionStatus actionStatus, final String... params) {
1803 return rollbackWithEither(janusGraphDao, actionStatus, params);
1806 private Either<InputDefinition, RuntimeException> findInputByName(List<InputDefinition> inputs, GetInputValueDataDefinition getInput) {
1807 final String inputName = getInput != null ? getInput.getInputName() : "";
1808 if (inputs == null || inputs.isEmpty()) {
1809 log.debug("#findInputByName - Inputs list is empty");
1810 return rollbackWithEither(ActionStatus.INPUTS_NOT_FOUND, inputName);
1812 Optional<InputDefinition> inputOpt = inputs.stream().filter(p -> p.getName().equals(inputName)).findFirst();
1813 if (inputOpt.isEmpty()) {
1814 log.debug("#findInputByName - Failed to find the input {} ", inputName);
1815 return rollbackWithEither(ActionStatus.INPUTS_NOT_FOUND, inputName);
1817 return Either.left(inputOpt.get());
1822 private void fillGroupsFinalFields(List<GroupDefinition> groupsAsList) {
1823 groupsAsList.forEach(groupDefinition -> {
1824 groupDefinition.setInvariantName(groupDefinition.getName());
1825 groupDefinition.setCreatedFrom(CreatedFrom.CSAR);
1829 private Resource updateGroupsOnResource(Resource resource, Map<String, GroupDefinition> groups) {
1830 if (isEmpty(groups)) {
1833 return updateOrCreateGroups(resource, groups);
1836 private Resource updateOrCreateGroups(Resource resource, Map<String, GroupDefinition> groups) {
1837 List<GroupDefinition> groupsFromResource = resource.getGroups();
1838 List<GroupDefinition> groupsAsList = updateGroupsMembersUsingResource(groups, resource);
1839 List<GroupDefinition> groupsToUpdate = new ArrayList<>();
1840 List<GroupDefinition> groupsToDelete = new ArrayList<>();
1841 List<GroupDefinition> groupsToCreate = new ArrayList<>();
1842 if (isNotEmpty(groupsFromResource)) {
1843 addGroupsToCreateOrUpdate(groupsFromResource, groupsAsList, groupsToUpdate, groupsToCreate);
1844 addGroupsToDelete(groupsFromResource, groupsAsList, groupsToDelete);
1846 groupsToCreate.addAll(groupsAsList);
1848 if (isNotEmpty(groupsToCreate)) {
1849 fillGroupsFinalFields(groupsToCreate);
1850 if (isNotEmpty(groupsFromResource)) {
1851 groupBusinessLogic.addGroups(resource, groupsToCreate, true).left().on(this::throwComponentException);
1853 groupBusinessLogic.createGroups(resource, groupsToCreate, true).left().on(this::throwComponentException);
1856 if (isNotEmpty(groupsToDelete)) {
1857 groupBusinessLogic.deleteGroups(resource, groupsToDelete).left().on(this::throwComponentException);
1859 if (isNotEmpty(groupsToUpdate)) {
1860 groupBusinessLogic.updateGroups(resource, groupsToUpdate, true).left().on(this::throwComponentException);
1865 private void addGroupsToDelete(List<GroupDefinition> groupsFromResource, List<GroupDefinition> groupsAsList,
1866 List<GroupDefinition> groupsToDelete) {
1867 for (GroupDefinition group : groupsFromResource) {
1868 Optional<GroupDefinition> op = groupsAsList.stream().filter(p -> p.getInvariantName().equalsIgnoreCase(group.getInvariantName()))
1870 if (op.isEmpty() && (group.getArtifacts() == null || group.getArtifacts().isEmpty())) {
1871 groupsToDelete.add(group);
1876 private void addGroupsToCreateOrUpdate(List<GroupDefinition> groupsFromResource, List<GroupDefinition> groupsAsList,
1877 List<GroupDefinition> groupsToUpdate, List<GroupDefinition> groupsToCreate) {
1878 for (GroupDefinition group : groupsAsList) {
1879 Optional<GroupDefinition> op = groupsFromResource.stream().filter(p -> p.getInvariantName().equalsIgnoreCase(group.getInvariantName()))
1881 if (op.isPresent()) {
1882 GroupDefinition groupToUpdate = op.get();
1883 groupToUpdate.setMembers(group.getMembers());
1884 groupToUpdate.setCapabilities(group.getCapabilities());
1885 groupToUpdate.setProperties(group.getProperties());
1886 groupsToUpdate.add(groupToUpdate);
1888 groupsToCreate.add(group);
1893 private Resource createInputsOnResource(Resource resource, Map<String, InputDefinition> inputs) {
1894 List<InputDefinition> resourceProperties = resource.getInputs();
1895 if (MapUtils.isNotEmpty(inputs) || isNotEmpty(resourceProperties)) {
1896 Either<List<InputDefinition>, ResponseFormat> createInputs = inputsBusinessLogic.createInputsInGraph(inputs, resource);
1897 if (createInputs.isRight()) {
1898 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1899 "failed to add inputs from yaml: {}", createInputs.right().value());
1900 throw new ByResponseFormatComponentException(createInputs.right().value());
1902 resource.setInputs(createInputs.left().value());
1907 private Resource generatePropertiesFromNodeType(final Resource resource, final Map<String, Object> nodeType) {
1908 final Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils.getProperties(nodeType);
1909 if (properties.isLeft()) {
1910 final List<PropertyDefinition> propertiesList = new ArrayList<>();
1911 final Map<String, PropertyDefinition> value = properties.left().value();
1912 if (value != null) {
1913 for (Entry<String, PropertyDefinition> entry : value.entrySet()) {
1914 final String name = entry.getKey();
1915 final PropertyDefinition propertyDefinition = entry.getValue();
1916 propertyDefinition.setName(name);
1917 propertiesList.add(propertyDefinition);
1918 resource.getProperties().removeIf(p -> p.getName().equals(name));
1921 resource.getProperties().addAll(propertiesList);
1926 private Resource createResourcePropertiesOnGraph(final Resource resource) {
1927 final List<PropertyDefinition> resourceProperties = resource.getProperties();
1928 for (PropertyDefinition propertyDefinition : resourceProperties) {
1929 final Either<PropertyDefinition, StorageOperationStatus> addPropertyEither = toscaOperationFacade
1930 .addPropertyToComponent(propertyDefinition.getName(), propertyDefinition, resource);
1932 if (addPropertyEither.isRight()) {
1933 final String error = String.format("failed to add properties from yaml: {}", addPropertyEither.right().value());
1934 loggerSupportability.log(LoggerSupportabilityActions.CREATE_PROPERTIES, resource.getComponentMetadataForSupportLog(),
1937 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addPropertyEither.right().value()), error);
1943 private List<GroupDefinition> updateGroupsMembersUsingResource(Map<String, GroupDefinition> groups, Resource component) {
1944 List<GroupDefinition> result = new ArrayList<>();
1945 List<ComponentInstance> componentInstances = component.getComponentInstances();
1946 if (groups != null) {
1947 Either<Boolean, ResponseFormat> validateCyclicGroupsDependencies = validateCyclicGroupsDependencies(groups);
1948 if (validateCyclicGroupsDependencies.isRight()) {
1949 throw new ByResponseFormatComponentException(validateCyclicGroupsDependencies.right().value());
1951 for (Entry<String, GroupDefinition> entry : groups.entrySet()) {
1952 String groupName = entry.getKey();
1953 GroupDefinition groupDefinition = entry.getValue();
1954 GroupDefinition updatedGroupDefinition = new GroupDefinition(groupDefinition);
1955 updatedGroupDefinition.setMembers(null);
1956 Map<String, String> members = groupDefinition.getMembers();
1957 if (members != null) {
1958 updateGroupMembers(groups, updatedGroupDefinition, component, componentInstances, groupName, members);
1960 result.add(updatedGroupDefinition);
1966 private void updateGroupMembers(Map<String, GroupDefinition> groups, GroupDefinition updatedGroupDefinition, Resource component,
1967 List<ComponentInstance> componentInstances, String groupName, Map<String, String> members) {
1968 Set<String> compInstancesNames = members.keySet();
1969 if (CollectionUtils.isEmpty(componentInstances)) {
1970 String membersAstString = String.join(",", compInstancesNames);
1971 log.debug("The members: {}, in group: {}, cannot be found in component {}. There are no component instances.", membersAstString,
1972 groupName, component.getNormalizedName());
1973 throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1974 component.getNormalizedName(), getComponentTypeForResponse(component));
1976 // Find all component instances with the member names
1977 Map<String, String> memberNames = componentInstances.stream().collect(toMap(ComponentInstance::getName, ComponentInstance::getUniqueId));
1978 memberNames.putAll(groups.keySet().stream().collect(toMap(g -> g, g -> "")));
1979 Map<String, String> relevantInstances = memberNames.entrySet().stream().filter(n -> compInstancesNames.contains(n.getKey()))
1980 .collect(toMap(Entry::getKey, Entry::getValue));
1981 if (relevantInstances.size() != compInstancesNames.size()) {
1982 List<String> foundMembers = new ArrayList<>(relevantInstances.keySet());
1983 foundMembers.forEach(compInstancesNames::remove);
1984 String membersAstString = String.join(",", compInstancesNames);
1985 log.debug("The members: {}, in group: {}, cannot be found in component: {}", membersAstString, groupName, component.getNormalizedName());
1986 throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1987 component.getNormalizedName(), getComponentTypeForResponse(component));
1989 updatedGroupDefinition.setMembers(relevantInstances);
1993 * This Method validates that there is no cyclic group dependencies. meaning group A as member in group B which is member in group A
1998 private Either<Boolean, ResponseFormat> validateCyclicGroupsDependencies(Map<String, GroupDefinition> allGroups) {
1999 Either<Boolean, ResponseFormat> result = Either.left(true);
2001 Iterator<Entry<String, GroupDefinition>> allGroupsItr = allGroups.entrySet().iterator();
2002 while (allGroupsItr.hasNext() && result.isLeft()) {
2003 Entry<String, GroupDefinition> groupAEntry = allGroupsItr.next();
2004 // Fetches a group member A
2005 String groupAName = groupAEntry.getKey();
2006 // Finds all group members in group A
2007 Set<String> allGroupAMembersNames = new HashSet<>();
2008 fillAllGroupMemebersRecursivly(groupAEntry.getKey(), allGroups, allGroupAMembersNames);
2009 // If A is a group member of itself found cyclic dependency
2010 if (allGroupAMembersNames.contains(groupAName)) {
2011 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GROUP_HAS_CYCLIC_DEPENDENCY, groupAName);
2012 result = Either.right(responseFormat);
2015 } catch (Exception e) {
2016 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2017 result = Either.right(responseFormat);
2018 log.debug("Exception occurred when validateCyclicGroupsDependencies, error is:{}", e.getMessage(), e);
2024 * This Method fills recursively the set groupMembers with all the members of the given group which are also of type group.
2028 * @param allGroupMembers
2031 private void fillAllGroupMemebersRecursivly(String groupName, Map<String, GroupDefinition> allGroups, Set<String> allGroupMembers) {
2032 // Found Cyclic dependency
2033 if (isfillGroupMemebersRecursivlyStopCondition(groupName, allGroups, allGroupMembers)) {
2036 GroupDefinition groupDefinition = allGroups.get(groupName);
2037 // All Members Of Current Group Resource Instances & Other Groups
2038 Set<String> currGroupMembers = groupDefinition.getMembers().keySet();
2039 // Filtered Members Of Current Group containing only members which
2042 List<String> currGroupFilteredMembers = currGroupMembers.stream().
2043 // Keep Only Elements of type group and not Resource Instances
2044 filter(allGroups::containsKey).
2045 // Add Filtered Elements to main Set
2046 peek(allGroupMembers::add).
2049 // Recursively call the method for all the filtered group members
2050 for (String innerGroupName : currGroupFilteredMembers) {
2051 fillAllGroupMemebersRecursivly(innerGroupName, allGroups, allGroupMembers);
2055 private boolean isfillGroupMemebersRecursivlyStopCondition(String groupName, Map<String, GroupDefinition> allGroups,
2056 Set<String> allGroupMembers) {
2057 boolean stop = !allGroups.containsKey(groupName);
2058 // In Case Not Group Stop
2059 // In Case Group Has no members stop
2061 GroupDefinition groupDefinition = allGroups.get(groupName);
2062 stop = isEmpty(groupDefinition.getMembers());
2064 // In Case all group members already contained stop
2066 final Set<String> allMembers = allGroups.get(groupName).getMembers().keySet();
2067 Set<String> membersOfTypeGroup = allMembers.stream().
2068 // Filter In Only Group members
2069 filter(allGroups::containsKey).
2072 stop = allGroupMembers.containsAll(membersOfTypeGroup);
2077 private Resource createRIAndRelationsFromYaml(String yamlName, Resource resource,
2078 Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap,
2079 String topologyTemplateYaml, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
2080 Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
2081 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
2082 String nodeName, final String substitutableAsNodeType) {
2083 log.debug("************* Going to create all nodes {}", yamlName);
2084 handleNodeTypes(yamlName, resource, topologyTemplateYaml, false, nodeTypesArtifactsToCreate, nodeTypesNewCreatedArtifacts, nodeTypesInfo,
2085 csarInfo, nodeName, substitutableAsNodeType);
2086 log.debug("************* Finished to create all nodes {}", yamlName);
2087 log.debug("************* Going to create all resource instances {}", yamlName);
2088 Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
2089 resource = createResourceInstances(yamlName, resource, null, uploadComponentInstanceInfoMap, csarInfo.getCreatedNodes(),
2090 existingNodeTypesByResourceNames);
2091 log.debug("************* Finished to create all resource instances {}", yamlName);
2092 log.debug("************* Going to create all relations {}", yamlName);
2093 resource = createResourceInstancesRelations(csarInfo.getModifier(), yamlName, resource, null, uploadComponentInstanceInfoMap,
2094 existingNodeTypesByResourceNames);
2095 log.debug("************* Finished to create all relations {}", yamlName);
2096 log.debug("************* Going to create positions {}", yamlName);
2097 compositionBusinessLogic.setPositionsForComponentInstances(resource, csarInfo.getModifier().getUserId());
2098 log.debug("************* Finished to set positions {}", yamlName);
2102 private void handleAndAddExtractedVfcsArtifacts(List<ArtifactDefinition> vfcArtifacts, List<ArtifactDefinition> artifactsToAdd) {
2103 List<String> vfcArtifactNames = vfcArtifacts.stream().map(ArtifactDataDefinition::getArtifactName).collect(toList());
2104 artifactsToAdd.forEach(a -> {
2105 if (!vfcArtifactNames.contains(a.getArtifactName())) {
2106 vfcArtifacts.add(a);
2108 log.debug("Can't upload two artifact with the same name {}. ", a.getArtifactName());
2113 @SuppressWarnings("unchecked")
2114 private void handleNodeTypes(String yamlName, Resource resource, String topologyTemplateYaml, boolean needLock,
2115 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
2116 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
2117 String nodeName, String substitutableAsNodeType) {
2119 for (Entry<String, NodeTypeInfo> nodeTypeEntry : nodeTypesInfo.entrySet()) {
2120 if (nodeTypeEntry.getValue().isNested() && !nodeTypeAlreadyExists(nodeTypeEntry.getKey(), resource.getModel())) {
2121 handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
2122 nodeTypeEntry.getKey());
2123 log.trace("************* finished to create node {}", nodeTypeEntry.getKey());
2126 Map<String, Object> mappedToscaTemplate = null;
2127 if (StringUtils.isNotEmpty(nodeName) && isNotEmpty(nodeTypesInfo) && nodeTypesInfo.containsKey(nodeName)) {
2128 mappedToscaTemplate = nodeTypesInfo.get(nodeName).getMappedToscaTemplate();
2130 if (isEmpty(mappedToscaTemplate)) {
2131 mappedToscaTemplate = (Map<String, Object>) new Yaml().load(topologyTemplateYaml);
2133 createResourcesFromYamlNodeTypesList(yamlName, resource, mappedToscaTemplate, needLock, nodeTypesArtifactsToHandle,
2134 nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, substitutableAsNodeType);
2135 } catch (ComponentException e) {
2136 ResponseFormat responseFormat =
2137 e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2138 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2140 } catch (StorageException e) {
2141 ResponseFormat responseFormat = componentsUtils
2142 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
2143 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2148 private boolean nodeTypeAlreadyExists(final String toscaResourceName, String modelName) {
2149 return toscaOperationFacade.getLatestByToscaResourceName(toscaResourceName, modelName).isLeft();
2152 private Either<Resource, ResponseFormat> handleVfCsarArtifacts(Resource resource, CsarInfo csarInfo, List<ArtifactDefinition> createdArtifacts,
2153 ArtifactOperationInfo artifactOperation, boolean shouldLock,
2154 boolean inTransaction) {
2155 if (csarInfo.getCsar() != null) {
2156 String vendorLicenseModelId = null;
2157 String vfLicenseModelId = null;
2158 if (artifactOperation.isUpdate()) {
2159 Map<String, ArtifactDefinition> deploymentArtifactsMap = resource.getDeploymentArtifacts();
2160 if (deploymentArtifactsMap != null && !deploymentArtifactsMap.isEmpty()) {
2161 for (Entry<String, ArtifactDefinition> artifactEntry : deploymentArtifactsMap.entrySet()) {
2162 if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VENDOR_LICENSE_MODEL)) {
2163 vendorLicenseModelId = artifactEntry.getValue().getUniqueId();
2165 if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VF_LICENSE_MODEL)) {
2166 vfLicenseModelId = artifactEntry.getValue().getUniqueId();
2171 // Specific Behavior for license artifacts
2172 createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VENDOR_LICENSE_MODEL,
2173 Constants.VENDOR_LICENSE_MODEL, ArtifactTypeEnum.VENDOR_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT,
2174 Constants.VENDOR_LICENSE_LABEL, Constants.VENDOR_LICENSE_DISPLAY_NAME, Constants.VENDOR_LICENSE_DESCRIPTION, vendorLicenseModelId,
2175 artifactOperation, null, true, shouldLock, inTransaction);
2176 createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VF_LICENSE_MODEL, Constants.VF_LICENSE_MODEL,
2177 ArtifactTypeEnum.VF_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT, Constants.VF_LICENSE_LABEL,
2178 Constants.VF_LICENSE_DISPLAY_NAME, Constants.VF_LICENSE_DESCRIPTION, vfLicenseModelId, artifactOperation, null, true, shouldLock,
2180 Either<Resource, ResponseFormat> eitherCreateResult = createOrUpdateNonMetaArtifacts(csarInfo, resource, createdArtifacts, shouldLock,
2181 inTransaction, artifactOperation);
2182 if (eitherCreateResult.isRight()) {
2183 return Either.right(eitherCreateResult.right().value());
2185 Either<ImmutablePair<String, String>, ResponseFormat> artifacsMetaCsarStatus = CsarValidationUtils
2186 .getArtifactsMeta(csarInfo.getCsar(), csarInfo.getCsarUUID(), componentsUtils);
2187 if (artifacsMetaCsarStatus.isLeft()) {
2188 String artifactsFileName = artifacsMetaCsarStatus.left().value().getKey();
2189 String artifactsContents = artifacsMetaCsarStatus.left().value().getValue();
2190 Either<Resource, ResponseFormat> createArtifactsFromCsar;
2191 if (artifactOperation.isCreateOrLink()) {
2192 createArtifactsFromCsar = csarArtifactsAndGroupsBusinessLogic
2193 .createResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts);
2195 Either<Component, ResponseFormat> result = csarArtifactsAndGroupsBusinessLogic
2196 .updateResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts, shouldLock,
2198 if ((result.left().value() instanceof Resource) && result.isLeft()) {
2199 Resource service1 = (Resource) result.left().value();
2200 createArtifactsFromCsar = Either.left(service1);
2202 createArtifactsFromCsar = Either.right(result.right().value());
2205 if (createArtifactsFromCsar.isRight()) {
2206 log.debug("Couldn't create artifacts from artifacts.meta");
2207 return Either.right(createArtifactsFromCsar.right().value());
2209 return Either.left(createArtifactsFromCsar.left().value());
2212 return Either.left(resource);
2215 private Either<Boolean, ResponseFormat> createOrUpdateSingleNonMetaArtifact(Resource resource, CsarInfo csarInfo, String artifactPath,
2216 String artifactFileName, String artifactType,
2217 ArtifactGroupTypeEnum artifactGroupType, String artifactLabel,
2218 String artifactDisplayName, String artifactDescription,
2219 String artifactId, ArtifactOperationInfo operation,
2220 List<ArtifactDefinition> createdArtifacts, boolean isFromCsar,
2221 boolean shouldLock, boolean inTransaction) {
2222 byte[] artifactFileBytes = null;
2223 if (csarInfo.getCsar().containsKey(artifactPath)) {
2224 artifactFileBytes = csarInfo.getCsar().get(artifactPath);
2226 Either<Boolean, ResponseFormat> result = Either.left(true);
2227 if (operation.isUpdate() || operation.isDelete()) {
2228 if (isArtifactDeletionRequired(artifactId, artifactFileBytes, isFromCsar)) {
2229 Either<ArtifactDefinition, ResponseFormat> handleDelete = artifactsBusinessLogic
2230 .handleDelete(resource.getUniqueId(), artifactId, csarInfo.getModifier(), resource, shouldLock, inTransaction);
2231 if (handleDelete.isRight()) {
2232 result = Either.right(handleDelete.right().value());
2234 ArtifactDefinition value = handleDelete.left().value();
2235 String updatedArtifactId = value.getUniqueId();
2236 if (artifactGroupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
2237 resource.getDeploymentArtifacts().remove(updatedArtifactId);
2239 resource.getArtifacts().remove(updatedArtifactId);
2244 if (StringUtils.isEmpty(artifactId) && artifactFileBytes != null) {
2245 operation = new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE);
2248 if (artifactFileBytes != null) {
2249 Map<String, Object> vendorLicenseModelJson = ArtifactUtils
2250 .buildJsonForUpdateArtifact(artifactId, artifactFileName, artifactType, artifactGroupType, artifactLabel, artifactDisplayName,
2251 artifactDescription, artifactFileBytes, null, isFromCsar);
2252 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts = csarArtifactsAndGroupsBusinessLogic
2253 .createOrUpdateCsarArtifactFromJson(resource, csarInfo.getModifier(), vendorLicenseModelJson, operation);
2254 addNonMetaCreatedArtifactsToSupportRollback(operation, createdArtifacts, eitherNonMetaArtifacts);
2255 if (eitherNonMetaArtifacts.isRight()) {
2256 BeEcompErrorManager.getInstance().logInternalFlowError("UploadLicenseArtifact",
2257 "Failed to upload license artifact: " + artifactFileName + "With csar uuid: " + csarInfo.getCsarUUID(), ErrorSeverity.WARNING);
2258 return Either.right(eitherNonMetaArtifacts.right().value());
2260 ArtifactDefinition artifactDefinition = eitherNonMetaArtifacts.left().value().left().value();
2261 createOrUpdateResourceWithUpdatedArtifact(artifactDefinition, resource, artifactGroupType);
2266 private void createOrUpdateResourceWithUpdatedArtifact(ArtifactDefinition artifact, Resource resource, ArtifactGroupTypeEnum groupTypeEnum) {
2267 if (groupTypeEnum == ArtifactGroupTypeEnum.DEPLOYMENT) {
2268 resource.getDeploymentArtifacts().put(artifact.getArtifactLabel(), artifact);
2270 resource.getArtifacts().put(artifact.getArtifactLabel(), artifact);
2274 private boolean isArtifactDeletionRequired(String artifactId, byte[] artifactFileBytes, boolean isFromCsar) {
2275 return !StringUtils.isEmpty(artifactId) && artifactFileBytes == null && isFromCsar;
2278 private void addNonMetaCreatedArtifactsToSupportRollback(ArtifactOperationInfo operation, List<ArtifactDefinition> createdArtifacts,
2279 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts) {
2280 if (operation.isCreateOrLink() && createdArtifacts != null && eitherNonMetaArtifacts.isLeft()) {
2281 Either<ArtifactDefinition, Operation> eitherResult = eitherNonMetaArtifacts.left().value();
2282 if (eitherResult.isLeft()) {
2283 createdArtifacts.add(eitherResult.left().value());
2288 private Either<Resource, ResponseFormat> createOrUpdateNonMetaArtifacts(CsarInfo csarInfo, Resource resource,
2289 List<ArtifactDefinition> createdArtifacts, boolean shouldLock,
2290 boolean inTransaction, ArtifactOperationInfo artifactOperation) {
2291 Either<Resource, ResponseFormat> resStatus = null;
2292 Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
2294 Either<List<NonMetaArtifactInfo>, String> artifactPathAndNameList = getValidArtifactNames(csarInfo, collectedWarningMessages);
2295 if (artifactPathAndNameList.isRight()) {
2296 return Either.right(
2297 getComponentsUtils().getResponseFormatByArtifactId(ActionStatus.ARTIFACT_NAME_INVALID, artifactPathAndNameList.right().value(),
2298 VALID_CHARACTERS_ARTIFACT_NAME));
2300 EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle = null;
2301 if (artifactOperation.isCreateOrLink()) {
2302 vfCsarArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
2303 vfCsarArtifactsToHandle.put(artifactOperation.getArtifactOperationEnum(), artifactPathAndNameList.left().value());
2305 Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandleRes = findVfCsarArtifactsToHandle(
2306 resource, artifactPathAndNameList.left().value(), csarInfo.getModifier());
2307 if (findVfCsarArtifactsToHandleRes.isRight()) {
2308 resStatus = Either.right(findVfCsarArtifactsToHandleRes.right().value());
2310 if (resStatus == null) {
2311 vfCsarArtifactsToHandle = findVfCsarArtifactsToHandleRes.left().value();
2314 if (resStatus == null && vfCsarArtifactsToHandle != null) {
2315 resStatus = processCsarArtifacts(csarInfo, resource, createdArtifacts, shouldLock, inTransaction, resStatus, vfCsarArtifactsToHandle);
2317 if (resStatus == null) {
2318 resStatus = Either.left(resource);
2320 } catch (Exception e) {
2321 resStatus = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2322 log.debug("Exception occurred in createNonMetaArtifacts, message:{}", e.getMessage(), e);
2324 CsarUtils.handleWarningMessages(collectedWarningMessages);
2329 private Either<Resource, ResponseFormat> processCsarArtifacts(CsarInfo csarInfo, Resource resource, List<ArtifactDefinition> createdArtifacts,
2330 boolean shouldLock, boolean inTransaction,
2331 Either<Resource, ResponseFormat> resStatus,
2332 EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle) {
2333 for (Entry<ArtifactOperationEnum, List<NonMetaArtifactInfo>> currArtifactOperationPair : vfCsarArtifactsToHandle.entrySet()) {
2334 Optional<ResponseFormat> optionalCreateInDBError =
2335 // Stream of artifacts to be created
2336 currArtifactOperationPair.getValue().stream()
2337 // create each artifact
2338 .map(e -> createOrUpdateSingleNonMetaArtifact(resource, csarInfo, e.getPath(), e.getArtifactName(), e.getArtifactType(),
2339 e.getArtifactGroupType(), e.getArtifactLabel(), e.getDisplayName(), CsarUtils.ARTIFACT_CREATED_FROM_CSAR,
2340 e.getArtifactUniqueId(), new ArtifactOperationInfo(false, false, currArtifactOperationPair.getKey()), createdArtifacts,
2341 e.isFromCsar(), shouldLock, inTransaction))
2342 // filter in only error
2343 .filter(Either::isRight).
2344 // Convert the error from either to
2347 map(e -> e.right().value()).
2348 // Check if an error occurred
2350 // Error found on artifact Creation
2351 if (optionalCreateInDBError.isPresent()) {
2352 resStatus = Either.right(optionalCreateInDBError.get());
2359 private Either<List<NonMetaArtifactInfo>, String> getValidArtifactNames(CsarInfo csarInfo,
2360 Map<String, Set<List<String>>> collectedWarningMessages) {
2361 List<NonMetaArtifactInfo> artifactPathAndNameList =
2362 // Stream of file paths contained in csar
2363 csarInfo.getCsar().entrySet().stream()
2364 // Filter in only VF artifact path location
2365 .filter(e -> Pattern.compile(VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
2366 // Validate and add warnings
2367 .map(e -> CsarUtils.validateNonMetaArtifact(e.getKey(), e.getValue(), collectedWarningMessages))
2368 // Filter in Non Warnings
2369 .filter(Either::isLeft)
2370 // Convert from Either to NonMetaArtifactInfo
2371 .map(e -> e.left().value())
2374 Pattern englishNumbersAndUnderScoresOnly = Pattern.compile(CsarUtils.VALID_ENGLISH_ARTIFACT_NAME);
2375 for (NonMetaArtifactInfo nonMetaArtifactInfo : artifactPathAndNameList) {
2376 if (!englishNumbersAndUnderScoresOnly.matcher(nonMetaArtifactInfo.getDisplayName()).matches()) {
2377 return Either.right(nonMetaArtifactInfo.getArtifactName());
2380 return Either.left(artifactPathAndNameList);
2383 private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandle(Resource resource,
2384 List<NonMetaArtifactInfo> artifactPathAndNameList,
2386 List<ArtifactDefinition> existingArtifacts = new ArrayList<>();
2387 // collect all Deployment and Informational artifacts of VF
2388 if (resource.getDeploymentArtifacts() != null && !resource.getDeploymentArtifacts().isEmpty()) {
2389 existingArtifacts.addAll(resource.getDeploymentArtifacts().values());
2391 if (resource.getArtifacts() != null && !resource.getArtifacts().isEmpty()) {
2392 existingArtifacts.addAll(resource.getArtifacts().values());
2394 existingArtifacts = existingArtifacts.stream()
2395 // filter MANDATORY artifacts, LICENSE artifacts and artifacts
2397 // was created from HEAT.meta
2398 .filter(this::isNonMetaArtifact).collect(toList());
2399 List<String> artifactsToIgnore = new ArrayList<>();
2400 // collect IDs of Artifacts of VF which belongs to any group
2401 if (resource.getGroups() != null) {
2402 resource.getGroups().forEach(g -> {
2403 if (g.getArtifacts() != null && !g.getArtifacts().isEmpty()) {
2404 artifactsToIgnore.addAll(g.getArtifacts());
2408 existingArtifacts = existingArtifacts.stream()
2409 // filter artifacts which belongs to any group
2410 .filter(a -> !artifactsToIgnore.contains(a.getUniqueId())).collect(toList());
2411 return organizeVfCsarArtifactsByArtifactOperation(artifactPathAndNameList, existingArtifacts, resource, user);
2414 private boolean isNonMetaArtifact(ArtifactDefinition artifact) {
2415 return !artifact.getMandatory() && artifact.getArtifactName() != null && isValidArtifactType(artifact);
2418 private boolean isValidArtifactType(ArtifactDefinition artifact) {
2419 return artifact.getArtifactType() != null && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VENDOR_LICENSE
2420 && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VF_LICENSE;
2423 private Resource createResourceInstancesRelations(User user, String yamlName, Resource resource, Resource oldResource,
2424 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2425 Map<String, Resource> existingNodeTypesByResourceNames) {
2426 log.debug("#createResourceInstancesRelations - Going to create relations ");
2427 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2428 "Start to create relations");
2429 List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2430 if (isEmpty(uploadResInstancesMap) || CollectionUtils.isEmpty(componentInstancesList) &&
2431 resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances {
2432 log.debug("#createResourceInstancesRelations - No instances found in the resource {} is empty, yaml template file name {}, ",
2433 resource.getUniqueId(), yamlName);
2434 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2435 "No instances found in the resource: {}, is empty, yaml template file name: {}", resource.getName(), yamlName);
2436 BeEcompErrorManager.getInstance()
2437 .logInternalDataError("createResourceInstancesRelations", "No instances found in a resource or nn yaml template. ",
2438 ErrorSeverity.ERROR);
2439 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2441 Map<String, List<ComponentInstanceProperty>> instProperties = new HashMap<>();
2442 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities = new HashMap<>();
2443 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements = new HashMap<>();
2444 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts = new HashMap<>();
2445 Map<String, Map<String, ArtifactDefinition>> instArtifacts = new HashMap<>();
2446 Map<String, List<AttributeDefinition>> instAttributes = new HashMap<>();
2447 List<RequirementCapabilityRelDef> relations = new ArrayList<>();
2448 Map<String, List<ComponentInstanceInput>> instInputs = new HashMap<>();
2449 Resource finalResource = resource;
2450 uploadResInstancesMap.values().forEach(
2451 i -> processComponentInstance(yamlName, finalResource, componentInstancesList,
2452 componentsUtils.getAllDataTypes(applicationDataTypeCache, resource.getModel()), instProperties, instCapabilities,
2453 instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, existingNodeTypesByResourceNames, instInputs, i));
2454 resource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar()).forEach(
2455 i -> processUiComponentInstance(oldResource, i, instCapabilities, instRequirements, instDeploymentArtifacts, instArtifacts,
2456 instProperties, instInputs, instAttributes));
2457 associateComponentInstancePropertiesToComponent(yamlName, resource, instProperties);
2458 associateComponentInstanceInputsToComponent(yamlName, resource, instInputs);
2459 associateDeploymentArtifactsToInstances(user, yamlName, resource, instDeploymentArtifacts);
2460 associateArtifactsToInstances(yamlName, resource, instArtifacts);
2461 associateOrAddCalculatedCapReq(yamlName, resource, instCapabilities, instRequirements);
2462 associateInstAttributeToComponentToInstances(yamlName, resource, instAttributes);
2463 addRelationsToRI(yamlName, resource, uploadResInstancesMap, componentInstancesList, relations);
2464 associateResourceInstances(yamlName, resource, relations);
2465 handleSubstitutionMappings(resource, uploadResInstancesMap);
2466 log.debug("************* in create relations, getResource start");
2467 loggerSupportability
2468 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, "create relations");
2469 Either<Resource, StorageOperationStatus> eitherGetResource = toscaOperationFacade.getToscaFullElement(resource.getUniqueId());
2470 log.debug("************* in create relations, getResource end");
2471 if (eitherGetResource.isRight()) {
2472 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2473 "ERROR while create relations");
2474 throw new ByResponseFormatComponentException(
2475 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGetResource.right().value()), resource));
2477 return eitherGetResource.left().value();
2480 private void processUiComponentInstance(Resource oldResource, ComponentInstance instance,
2481 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2482 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2483 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2484 Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2485 Map<String, List<ComponentInstanceProperty>> instProperties,
2486 Map<String, List<ComponentInstanceInput>> instInputs,
2487 Map<String, List<AttributeDefinition>> instAttributes) {
2488 Optional<ComponentInstance> foundInstance = findInstance(oldResource, instance);
2489 if (foundInstance.isPresent()) {
2490 if (MapUtils.isNotEmpty(foundInstance.get().getCapabilities())) {
2491 instCapabilities.put(instance, foundInstance.get().getCapabilities());
2493 if (MapUtils.isNotEmpty(foundInstance.get().getRequirements())) {
2494 instRequirements.put(instance, foundInstance.get().getRequirements());
2496 if (MapUtils.isNotEmpty(foundInstance.get().getDeploymentArtifacts())) {
2497 instDeploymentArtifacts.put(instance.getUniqueId(), foundInstance.get().getDeploymentArtifacts());
2499 if (MapUtils.isNotEmpty(foundInstance.get().getArtifacts())) {
2500 instArtifacts.put(instance.getUniqueId(), foundInstance.get().getArtifacts());
2502 if (MapUtils.isNotEmpty(oldResource.getComponentInstancesProperties()) && CollectionUtils
2503 .isNotEmpty(oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()))) {
2504 instProperties.put(instance.getUniqueId(), oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()));
2506 if (MapUtils.isNotEmpty(oldResource.getComponentInstancesInputs()) && CollectionUtils
2507 .isNotEmpty(oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()))) {
2508 instInputs.put(instance.getUniqueId(), oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()));
2510 if (MapUtils.isNotEmpty(oldResource.getComponentInstancesAttributes()) && CollectionUtils
2511 .isNotEmpty(oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()))) {
2512 instAttributes.put(instance.getUniqueId(),
2513 oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()).stream().map(AttributeDefinition::new)
2514 .collect(toList()));
2519 private Optional<ComponentInstance> findInstance(Resource oldResource, ComponentInstance instance) {
2520 if (oldResource != null && CollectionUtils.isNotEmpty(oldResource.getComponentInstances())) {
2521 return oldResource.getComponentInstances().stream().filter(i -> i.getName().equals(instance.getName())).findFirst();
2523 return Optional.empty();
2526 private void associateResourceInstances(String yamlName, Resource resource, List<RequirementCapabilityRelDef> relations) {
2527 Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> relationsEither = toscaOperationFacade
2528 .associateResourceInstances(resource, resource.getUniqueId(), relations);
2529 if (relationsEither.isRight() && relationsEither.right().value() != StorageOperationStatus.NOT_FOUND) {
2530 StorageOperationStatus status = relationsEither.right().value();
2531 log.debug("failed to associate instances of resource {} status is {}", resource.getUniqueId(), status);
2532 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), yamlName);
2534 setResourceInstanceRelationsOnComponent(resource, relationsEither.left().value());
2538 private void associateInstAttributeToComponentToInstances(String yamlName, Resource resource,
2539 Map<String, List<AttributeDefinition>> instAttributes) {
2540 StorageOperationStatus addArtToInst;
2541 addArtToInst = toscaOperationFacade.associateInstAttributeToComponentToInstances(instAttributes, resource);
2542 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2543 log.debug("failed to associate attributes of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2544 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2548 private void associateOrAddCalculatedCapReq(String yamlName, Resource resource,
2549 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2550 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements) {
2551 StorageOperationStatus addArtToInst;
2552 addArtToInst = toscaOperationFacade.associateOrAddCalculatedCapReq(instCapabilities, instRequirements, resource);
2553 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2554 log.debug("failed to associate cap and req of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2555 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2559 private void associateArtifactsToInstances(String yamlName, Resource resource, Map<String, Map<String, ArtifactDefinition>> instArtifacts) {
2560 StorageOperationStatus addArtToInst;
2561 addArtToInst = toscaOperationFacade.associateArtifactsToInstances(instArtifacts, resource);
2562 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2563 log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2564 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2568 private void associateDeploymentArtifactsToInstances(User user, String yamlName, Resource resource,
2569 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts) {
2570 StorageOperationStatus addArtToInst = toscaOperationFacade.associateDeploymentArtifactsToInstances(instDeploymentArtifacts, resource, user);
2571 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2572 log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2573 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2577 private void associateComponentInstanceInputsToComponent(String yamlName, Resource resource,
2578 Map<String, List<ComponentInstanceInput>> instInputs) {
2579 if (MapUtils.isNotEmpty(instInputs)) {
2580 Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addInputToInst = toscaOperationFacade
2581 .associateComponentInstanceInputsToComponent(instInputs, resource.getUniqueId());
2582 if (addInputToInst.isRight()) {
2583 StorageOperationStatus addInputToInstError = addInputToInst.right().value();
2584 log.debug("failed to associate inputs value of resource {} status is {}", resource.getUniqueId(), addInputToInstError);
2585 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addInputToInstError), yamlName);
2587 setComponentInstanceInputsOnComponent(resource, instInputs);
2591 private void setComponentInstanceInputsOnComponent(Resource resource, Map<String, List<ComponentInstanceInput>> instInputs) {
2592 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = resource.getComponentInstancesInputs();
2593 if (componentInstancesInputs == null) {
2594 componentInstancesInputs = new HashMap<>();
2596 componentInstancesInputs.putAll(instInputs);
2597 resource.setComponentInstancesInputs(componentInstancesInputs);
2600 private void associateComponentInstancePropertiesToComponent(String yamlName, Resource resource,
2601 Map<String, List<ComponentInstanceProperty>> instProperties) {
2602 Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addPropToInst = toscaOperationFacade
2603 .associateComponentInstancePropertiesToComponent(instProperties, resource.getUniqueId());
2604 if (addPropToInst.isRight()) {
2605 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2606 "ERROR while associate compnent insatnce properties of resource: {} status is: {}", resource.getName(),
2607 addPropToInst.right().value());
2608 StorageOperationStatus storageOperationStatus = addPropToInst.right().value();
2609 log.debug("failed to associate properties of resource {} status is {}", resource.getUniqueId(), storageOperationStatus);
2610 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageOperationStatus), yamlName);
2612 setComponentInstancePropertiesOnComponent(resource, instProperties);
2615 private void setComponentInstancePropertiesOnComponent(Resource resource, Map<String, List<ComponentInstanceProperty>> instProperties) {
2616 Map<String, List<ComponentInstanceProperty>> componentInstanceProps = resource.getComponentInstancesProperties();
2617 if (componentInstanceProps == null) {
2618 componentInstanceProps = new HashMap<>();
2620 componentInstanceProps.putAll(instProperties);
2621 resource.setComponentInstancesProperties(componentInstanceProps);
2624 private void handleSubstitutionMappings(Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2625 Either<Resource, StorageOperationStatus> getResourceRes = null;
2626 if (resource.getResourceType() == ResourceTypeEnum.CVFC) {
2627 getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap);
2628 } else if (StringUtils.isNotEmpty(resource.getModel()) && resource.getResourceType() == ResourceTypeEnum.VF) {
2629 getResourceRes = updateCalculatedCapReqWithSubstitutionMappingsForVf(resource, uploadResInstancesMap);
2631 if (getResourceRes != null && getResourceRes.isRight()) {
2632 ResponseFormat responseFormat = componentsUtils
2633 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource);
2634 throw new ByResponseFormatComponentException(responseFormat);
2639 private void addRelationsToRI(String yamlName, Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2640 List<ComponentInstance> componentInstancesList, List<RequirementCapabilityRelDef> relations) {
2641 for (Entry<String, UploadComponentInstanceInfo> entry : uploadResInstancesMap.entrySet()) {
2642 UploadComponentInstanceInfo uploadComponentInstanceInfo = entry.getValue();
2643 ComponentInstance currentCompInstance = null;
2644 for (ComponentInstance compInstance : componentInstancesList) {
2645 if (compInstance.getName().equals(uploadComponentInstanceInfo.getName())) {
2646 currentCompInstance = compInstance;
2650 if (currentCompInstance == null) {
2651 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2652 BeEcompErrorManager.getInstance()
2653 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2654 ErrorSeverity.ERROR);
2655 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2657 ResponseFormat addRelationToRiRes = addRelationToRI(yamlName, resource, entry.getValue(), relations);
2658 if (addRelationToRiRes.getStatus() != 200) {
2659 throw new ByResponseFormatComponentException(addRelationToRiRes);
2664 private void setResourceInstanceRelationsOnComponent(Resource resource, List<RequirementCapabilityRelDef> relations) {
2665 if (resource.getComponentInstancesRelations() != null) {
2666 resource.getComponentInstancesRelations().addAll(relations);
2668 resource.setComponentInstancesRelations(relations);
2672 private void processComponentInstance(String yamlName, Resource resource, List<ComponentInstance> componentInstancesList,
2673 Map<String, DataTypeDefinition> allDataTypes,
2674 Map<String, List<ComponentInstanceProperty>> instProperties,
2675 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2676 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2677 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2678 Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2679 Map<String, List<AttributeDefinition>> instAttributes, Map<String, Resource> originCompMap,
2680 Map<String, List<ComponentInstanceInput>> instInputs,
2681 UploadComponentInstanceInfo uploadComponentInstanceInfo) {
2682 Optional<ComponentInstance> currentCompInstanceOpt = componentInstancesList.stream()
2683 .filter(i -> i.getName().equals(uploadComponentInstanceInfo.getName())).findFirst();
2684 if (currentCompInstanceOpt.isEmpty()) {
2685 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2686 BeEcompErrorManager.getInstance()
2687 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2688 ErrorSeverity.ERROR);
2689 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2691 ComponentInstance currentCompInstance = currentCompInstanceOpt.get();
2692 String resourceInstanceId = currentCompInstance.getUniqueId();
2693 Resource originResource = getOriginResource(originCompMap, currentCompInstance);
2694 if (isNotEmpty(originResource.getRequirements())) {
2695 instRequirements.put(currentCompInstance, originResource.getRequirements());
2697 if (isNotEmpty(originResource.getCapabilities())) {
2698 processComponentInstanceCapabilities(allDataTypes, instCapabilties, uploadComponentInstanceInfo, currentCompInstance, originResource);
2700 if (originResource.getDeploymentArtifacts() != null && !originResource.getDeploymentArtifacts().isEmpty()) {
2701 instDeploymentArtifacts.put(resourceInstanceId, originResource.getDeploymentArtifacts());
2703 if (originResource.getArtifacts() != null && !originResource.getArtifacts().isEmpty()) {
2704 instArtifacts.put(resourceInstanceId, originResource.getArtifacts());
2706 if (originResource.getAttributes() != null && !originResource.getAttributes().isEmpty()) {
2707 instAttributes.put(resourceInstanceId, originResource.getAttributes());
2709 if (originResource.getResourceType() != ResourceTypeEnum.CVFC) {
2710 ResponseFormat addPropertiesValueToRiRes = addPropertyValuesToRi(uploadComponentInstanceInfo, resource, originResource,
2711 currentCompInstance, instProperties, allDataTypes);
2712 if (addPropertiesValueToRiRes.getStatus() != 200) {
2713 throw new ByResponseFormatComponentException(addPropertiesValueToRiRes);
2716 addInputsValuesToRi(uploadComponentInstanceInfo, resource, originResource, currentCompInstance, instInputs, allDataTypes);
2720 private Resource getOriginResource(Map<String, Resource> originCompMap, ComponentInstance currentCompInstance) {
2721 Resource originResource;
2722 if (!originCompMap.containsKey(currentCompInstance.getComponentUid())) {
2723 Either<Resource, StorageOperationStatus> getOriginResourceRes = toscaOperationFacade
2724 .getToscaFullElement(currentCompInstance.getComponentUid());
2725 if (getOriginResourceRes.isRight()) {
2726 log.debug("failed to fetch resource with uniqueId {} and tosca component name {} status is {}", currentCompInstance.getComponentUid(),
2727 currentCompInstance.getToscaComponentName(), getOriginResourceRes);
2728 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getOriginResourceRes.right().value()),
2729 currentCompInstance.getComponentUid());
2731 originResource = getOriginResourceRes.left().value();
2732 originCompMap.put(originResource.getUniqueId(), originResource);
2734 originResource = originCompMap.get(currentCompInstance.getComponentUid());
2736 return originResource;
2739 private void processComponentInstanceCapabilities(Map<String, DataTypeDefinition> allDataTypes,
2740 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2741 UploadComponentInstanceInfo uploadComponentInstanceInfo, ComponentInstance currentCompInstance,
2742 Resource originResource) {
2743 Map<String, List<CapabilityDefinition>> originCapabilities;
2744 if (isNotEmpty(uploadComponentInstanceInfo.getCapabilities())) {
2745 originCapabilities = new HashMap<>();
2746 Map<String, Map<String, UploadPropInfo>> newPropertiesMap = new HashMap<>();
2747 originResource.getCapabilities().forEach((k, v) -> addCapabilities(originCapabilities, k, v));
2748 uploadComponentInstanceInfo.getCapabilities().values().forEach(l -> addCapabilitiesProperties(newPropertiesMap, l));
2749 updateCapabilityPropertiesValues(originCapabilities, newPropertiesMap, allDataTypes);
2751 originCapabilities = originResource.getCapabilities();
2753 instCapabilties.put(currentCompInstance, originCapabilities);
2756 private void updateCapabilityPropertiesValues(Map<String, List<CapabilityDefinition>> originCapabilities,
2757 Map<String, Map<String, UploadPropInfo>> newPropertiesMap,
2758 Map<String, DataTypeDefinition> allDataTypes) {
2759 originCapabilities.values().stream().flatMap(Collection::stream).filter(c -> newPropertiesMap.containsKey(c.getName()))
2760 .forEach(c -> updatePropertyValues(c.getProperties(), newPropertiesMap.get(c.getName()), allDataTypes));
2763 private void addCapabilitiesProperties(Map<String, Map<String, UploadPropInfo>> newPropertiesMap, List<UploadCapInfo> capabilities) {
2764 for (UploadCapInfo capability : capabilities) {
2765 if (isNotEmpty(capability.getProperties())) {
2766 newPropertiesMap.put(capability.getName(), capability.getProperties().stream().collect(toMap(UploadInfo::getName, p -> p)));
2771 private void addCapabilities(Map<String, List<CapabilityDefinition>> originCapabilities, String type, List<CapabilityDefinition> capabilities) {
2772 List<CapabilityDefinition> list = capabilities.stream().map(CapabilityDefinition::new).collect(toList());
2773 originCapabilities.put(type, list);
2776 private void updatePropertyValues(List<ComponentInstanceProperty> properties, Map<String, UploadPropInfo> newProperties,
2777 Map<String, DataTypeDefinition> allDataTypes) {
2778 properties.forEach(p -> updatePropertyValue(p, newProperties.get(p.getName()), allDataTypes));
2781 private String updatePropertyValue(ComponentInstanceProperty property, UploadPropInfo propertyInfo,
2782 Map<String, DataTypeDefinition> allDataTypes) {
2783 String value = null;
2784 List<GetInputValueDataDefinition> getInputs = null;
2785 boolean isValidate = true;
2786 if (null != propertyInfo && propertyInfo.getValue() != null) {
2787 getInputs = propertyInfo.getGet_input();
2788 isValidate = getInputs == null || getInputs.isEmpty();
2790 value = getPropertyJsonStringValue(propertyInfo.getValue(), property.getType());
2792 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
2795 property.setValue(value);
2796 return validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
2799 private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappings(Resource resource,
2800 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2801 Either<Resource, StorageOperationStatus> updateRes = null;
2802 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2803 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2805 StorageOperationStatus status = toscaOperationFacade.deleteAllCalculatedCapabilitiesRequirements(resource.getUniqueId());
2806 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2807 log.debug("Failed to delete all calculated capabilities and requirements of resource {} upon update. Status is {}",
2808 resource.getUniqueId(), status);
2809 updateRes = Either.right(status);
2811 if (updateRes == null) {
2812 fillUpdatedInstCapabilitiesRequirements(resource.getComponentInstances(), uploadResInstancesMap, updatedInstCapabilities,
2813 updatedInstRequirements);
2814 status = toscaOperationFacade.associateOrAddCalculatedCapReq(updatedInstCapabilities, updatedInstRequirements, resource);
2815 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2817 "Failed to associate capabilities and requirementss of resource {}, updated according to a substitution mapping. Status is {}",
2818 resource.getUniqueId(), status);
2819 updateRes = Either.right(status);
2822 if (updateRes == null) {
2823 updateRes = Either.left(resource);
2828 private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappingsForVf(final Resource resource,
2829 final Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2830 Either<Resource, StorageOperationStatus> updateRes = null;
2831 final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2832 final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2834 resource.getComponentInstances().forEach(i -> {
2835 setExternalCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2836 setExternalRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2839 final StorageOperationStatus status = toscaOperationFacade.updateCalculatedCapabilitiesRequirements(updatedInstCapabilities,
2840 updatedInstRequirements, resource);
2841 if (status != StorageOperationStatus.OK) {
2843 "Failed to update capabilities and requirements of resource {}. Status is {}",
2844 resource.getUniqueId(), status);
2845 updateRes = Either.right(status);
2848 if (updateRes == null) {
2849 updateRes = Either.left(resource);
2854 private void fillUpdatedInstCapabilitiesRequirements(List<ComponentInstance> componentInstances,
2855 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2856 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities,
2857 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements) {
2858 componentInstances.forEach(i -> {
2859 fillUpdatedInstCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2860 fillUpdatedInstRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2864 private void fillUpdatedInstRequirements(Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2865 ComponentInstance instance, Map<String, String> requirementsNamesToUpdate) {
2866 Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2867 Set<String> updatedReqNames = new HashSet<>();
2868 if (isNotEmpty(requirementsNamesToUpdate)) {
2869 for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2870 updatedRequirements.put(requirements.getKey(), requirements.getValue().stream().filter(
2871 r -> requirementsNamesToUpdate.containsKey(r.getName()) && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2873 r.setParentName(r.getName());
2874 r.setName(requirementsNamesToUpdate.get(r.getName()));
2875 updatedReqNames.add(r.getName());
2877 }).collect(toList()));
2880 if (isNotEmpty(updatedRequirements)) {
2881 updatedInstRequirements.put(instance, updatedRequirements);
2885 private void setExternalRequirements(
2886 final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2887 final ComponentInstance instance, final Map<String, String> requirementsNamesToUpdate) {
2888 final Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2889 final Set<String> updatedReqNames = new HashSet<>();
2890 if (isNotEmpty(requirementsNamesToUpdate)) {
2891 for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2892 updatedRequirements.put(requirements.getKey(),
2893 requirements.getValue().stream()
2894 .filter(r -> requirementsNamesToUpdate.containsKey(r.getName())
2895 && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2897 r.setExternal(true);
2898 r.setExternalName(requirementsNamesToUpdate.get(r.getName()));
2899 updatedReqNames.add(r.getName());
2901 }).collect(toList()));
2904 if (isNotEmpty(updatedRequirements)) {
2905 updatedInstRequirements.put(instance, updatedRequirements);
2909 private void setExternalCapabilities(
2910 final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2911 final ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2912 final Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2913 final Set<String> updatedCapNames = new HashSet<>();
2914 if (isNotEmpty(capabilitiesNamesToUpdate)) {
2915 for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2916 updatedCapabilities.put(requirements.getKey(),
2917 requirements.getValue().stream()
2918 .filter(c -> capabilitiesNamesToUpdate.containsKey(c.getName())
2919 && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2921 c.setExternal(true);
2922 c.setExternalName(capabilitiesNamesToUpdate.get(c.getName()));
2923 updatedCapNames.add(c.getName());
2925 }).collect(toList()));
2928 if (isNotEmpty(updatedCapabilities)) {
2929 updatedInstCapabilties.put(instance, updatedCapabilities);
2933 private void fillUpdatedInstCapabilities(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2934 ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2935 Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2936 Set<String> updatedCapNames = new HashSet<>();
2937 if (isNotEmpty(capabilitiesNamesToUpdate)) {
2938 for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2939 updatedCapabilities.put(requirements.getKey(), requirements.getValue().stream().filter(
2940 c -> capabilitiesNamesToUpdate.containsKey(c.getName()) && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2942 c.setParentName(c.getName());
2943 c.setName(capabilitiesNamesToUpdate.get(c.getName()));
2944 updatedCapNames.add(c.getName());
2946 }).collect(toList()));
2949 if (isNotEmpty(updatedCapabilities)) {
2950 updatedInstCapabilties.put(instance, updatedCapabilities);
2954 private ResponseFormat addRelationToRI(String yamlName, Resource resource, UploadComponentInstanceInfo nodesInfoValue,
2955 List<RequirementCapabilityRelDef> relations) {
2956 List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2957 ComponentInstance currentCompInstance = null;
2958 for (ComponentInstance compInstance : componentInstancesList) {
2959 if (compInstance.getName().equals(nodesInfoValue.getName())) {
2960 currentCompInstance = compInstance;
2964 if (currentCompInstance == null) {
2965 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, nodesInfoValue.getName(), resource.getUniqueId());
2966 BeEcompErrorManager.getInstance()
2967 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + nodesInfoValue.getName() + IN_RESOURCE, resource.getUniqueId(),
2968 ErrorSeverity.ERROR);
2969 return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2971 String resourceInstanceId = currentCompInstance.getUniqueId();
2972 Map<String, List<UploadReqInfo>> regMap = nodesInfoValue.getRequirements();
2973 if (regMap != null) {
2974 for (Entry<String, List<UploadReqInfo>> nodesRegInfoEntry : regMap.entrySet()) {
2975 List<UploadReqInfo> uploadRegInfoList = nodesRegInfoEntry.getValue();
2976 for (UploadReqInfo uploadRegInfo : uploadRegInfoList) {
2977 log.debug("Going to create relation {}", uploadRegInfo.getName());
2978 loggerSupportability
2979 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2980 "Started to create relations on instance: {}", uploadRegInfo.getName());
2981 String regName = uploadRegInfo.getName();
2982 RequirementCapabilityRelDef regCapRelDef = new RequirementCapabilityRelDef();
2983 regCapRelDef.setFromNode(resourceInstanceId);
2984 log.debug("try to find available requirement {} ", regName);
2985 Either<RequirementDefinition, ResponseFormat> eitherReqStatus = findAviableRequiremen(regName, yamlName, nodesInfoValue,
2986 currentCompInstance, uploadRegInfo.getCapabilityName());
2987 if (eitherReqStatus.isRight()) {
2988 log.debug("failed to find available requirement {} status is {}", regName, eitherReqStatus.right().value());
2989 loggerSupportability
2990 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2991 "ERROR while search available requirement {} status is: {}", regName, eitherReqStatus.right().value());
2992 return eitherReqStatus.right().value();
2994 RequirementDefinition validReq = eitherReqStatus.left().value();
2995 List<CapabilityRequirementRelationship> reqAndRelationshipPairList = regCapRelDef.getRelationships();
2996 if (reqAndRelationshipPairList == null) {
2997 reqAndRelationshipPairList = new ArrayList<>();
2999 RelationshipInfo reqAndRelationshipPair = new RelationshipInfo();
3000 reqAndRelationshipPair.setRequirement(regName);
3001 reqAndRelationshipPair.setRequirementOwnerId(validReq.getOwnerId());
3002 reqAndRelationshipPair.setRequirementUid(validReq.getUniqueId());
3003 RelationshipImpl relationship = new RelationshipImpl();
3004 relationship.setType(validReq.getCapability());
3005 reqAndRelationshipPair.setRelationships(relationship);
3006 ComponentInstance currentCapCompInstance = null;
3007 for (ComponentInstance compInstance : componentInstancesList) {
3008 if (compInstance.getName().equals(uploadRegInfo.getNode())) {
3009 currentCapCompInstance = compInstance;
3013 if (currentCapCompInstance == null) {
3014 log.debug("The component instance with name {} not found on resource {} ", uploadRegInfo.getNode(), resource.getUniqueId());
3015 loggerSupportability
3016 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3017 "ERROR component instance with name: {} not found on resource: {}", uploadRegInfo.getNode(), resource.getUniqueId());
3018 BeEcompErrorManager.getInstance()
3019 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadRegInfo.getNode() + IN_RESOURCE, resource.getUniqueId(),
3020 ErrorSeverity.ERROR);
3021 return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
3023 regCapRelDef.setToNode(currentCapCompInstance.getUniqueId());
3024 log.debug("try to find aviable Capability req name is {} ", validReq.getName());
3025 CapabilityDefinition aviableCapForRel = findAvailableCapabilityByTypeOrName(validReq, currentCapCompInstance, uploadRegInfo);
3026 if (aviableCapForRel == null) {
3027 log.debug("aviable capability was not found. req name is {} component instance is {}", validReq.getName(),
3028 currentCapCompInstance.getUniqueId());
3029 loggerSupportability
3030 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3031 "ERROR available capability was not found. req name is: {} component instance is: {}", validReq.getName(),
3032 currentCapCompInstance.getUniqueId());
3033 BeEcompErrorManager.getInstance().logInternalDataError(
3034 "aviable capability was not found. req name is " + validReq.getName() + " component instance is " + currentCapCompInstance
3035 .getUniqueId(), resource.getUniqueId(), ErrorSeverity.ERROR);
3036 return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
3038 reqAndRelationshipPair.setCapability(aviableCapForRel.getName());
3039 reqAndRelationshipPair.setCapabilityUid(aviableCapForRel.getUniqueId());
3040 reqAndRelationshipPair.setCapabilityOwnerId(aviableCapForRel.getOwnerId());
3041 CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
3042 capReqRel.setRelation(reqAndRelationshipPair);
3043 reqAndRelationshipPairList.add(capReqRel);
3044 regCapRelDef.setRelationships(reqAndRelationshipPairList);
3045 relations.add(regCapRelDef);
3048 } else if (resource.getResourceType() != ResourceTypeEnum.CVFC) {
3049 return componentsUtils.getResponseFormat(ActionStatus.OK, yamlName);
3051 return componentsUtils.getResponseFormat(ActionStatus.OK);
3054 private void addInputsValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
3055 ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceInput>> instInputs,
3056 Map<String, DataTypeDefinition> allDataTypes) {
3057 Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
3058 if (MapUtils.isNotEmpty(propMap)) {
3059 Map<String, InputDefinition> currPropertiesMap = new HashMap<>();
3060 List<ComponentInstanceInput> instPropList = new ArrayList<>();
3061 if (CollectionUtils.isEmpty(originResource.getInputs())) {
3062 log.debug("failed to find properties ");
3063 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3064 "ERROR while try to find properties");
3065 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND);
3067 originResource.getInputs().forEach(p -> addInput(currPropertiesMap, p));
3068 for (List<UploadPropInfo> propertyList : propMap.values()) {
3069 processProperty(resource, currentCompInstance, allDataTypes, currPropertiesMap, instPropList, propertyList);
3071 currPropertiesMap.values().forEach(p -> instPropList.add(new ComponentInstanceInput(p)));
3072 instInputs.put(currentCompInstance.getUniqueId(), instPropList);
3076 private void processProperty(Resource resource, ComponentInstance currentCompInstance, Map<String, DataTypeDefinition> allDataTypes,
3077 Map<String, InputDefinition> currPropertiesMap, List<ComponentInstanceInput> instPropList,
3078 List<UploadPropInfo> propertyList) {
3079 UploadPropInfo propertyInfo = propertyList.get(0);
3080 String propName = propertyInfo.getName();
3081 if (!currPropertiesMap.containsKey(propName)) {
3082 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3083 "ERROR failed to find property: {}", propName);
3084 log.debug("failed to find property {} ", propName);
3085 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, propName);
3087 InputDefinition curPropertyDef = currPropertiesMap.get(propName);
3088 ComponentInstanceInput property = null;
3089 String value = null;
3090 List<GetInputValueDataDefinition> getInputs = null;
3091 boolean isValidate = true;
3092 if (propertyInfo.getValue() != null) {
3093 getInputs = propertyInfo.getGet_input();
3094 isValidate = getInputs == null || getInputs.isEmpty();
3096 value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3098 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3101 property = new ComponentInstanceInput(curPropertyDef, value, null);
3102 String validPropertyVAlue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3103 property.setValue(validPropertyVAlue);
3104 if (isNotEmpty(getInputs)) {
3105 List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3106 for (GetInputValueDataDefinition getInput : getInputs) {
3107 List<InputDefinition> inputs = resource.getInputs();
3108 if (CollectionUtils.isEmpty(inputs)) {
3109 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3110 "ERROR Failed to add property: " + propName + " to resource instance: {}. Inputs list is empty ",
3111 currentCompInstance.getUniqueId());
3112 log.debug("Failed to add property {} to resource instance {}. Inputs list is empty ", property,
3113 currentCompInstance.getUniqueId());
3114 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3116 Optional<InputDefinition> optional = inputs.stream().filter(p -> p.getName().equals(getInput.getInputName())).findAny();
3117 if (optional.isEmpty()) {
3118 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3119 "ERROR Failed to find input: " + getInput.getInputName());
3120 log.debug("Failed to find input {} ", getInput.getInputName());
3121 // @@TODO error message
3122 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3124 InputDefinition input = optional.get();
3125 getInput.setInputId(input.getUniqueId());
3126 getInputValues.add(getInput);
3127 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3128 processGetInput(getInputValues, inputs, getInputIndex);
3130 property.setGetInputValues(getInputValues);
3132 instPropList.add(property);
3133 // delete overriden property
3134 currPropertiesMap.remove(property.getName());
3137 private void processGetInput(List<GetInputValueDataDefinition> getInputValues, List<InputDefinition> inputs,
3138 GetInputValueDataDefinition getInputIndex) {
3139 Optional<InputDefinition> optional;
3140 if (getInputIndex != null) {
3141 optional = inputs.stream().filter(p -> p.getName().equals(getInputIndex.getInputName())).findAny();
3142 if (optional.isEmpty()) {
3143 log.debug("Failed to find input {} ", getInputIndex.getInputName());
3144 // @@TODO error message
3145 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3147 InputDefinition inputIndex = optional.get();
3148 getInputIndex.setInputId(inputIndex.getUniqueId());
3149 getInputValues.add(getInputIndex);
3153 private void addInput(Map<String, InputDefinition> currPropertiesMap, InputDefinition prop) {
3154 String propName = prop.getName();
3155 if (!currPropertiesMap.containsKey(propName)) {
3156 currPropertiesMap.put(propName, prop);
3160 private ResponseFormat addPropertyValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
3161 ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceProperty>> instProperties,
3162 Map<String, DataTypeDefinition> allDataTypes) {
3163 Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
3164 Map<String, PropertyDefinition> currPropertiesMap = new HashMap<>();
3165 List<PropertyDefinition> listFromMap = originResource.getProperties();
3166 if ((propMap != null && !propMap.isEmpty()) && (listFromMap == null || listFromMap.isEmpty())) {
3167 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3168 "ERROR Failed to find properties");
3169 log.debug("failed to find properties");
3170 return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND);
3172 if (listFromMap == null || listFromMap.isEmpty()) {
3173 return componentsUtils.getResponseFormat(ActionStatus.OK);
3175 for (PropertyDefinition prop : listFromMap) {
3176 String propName = prop.getName();
3177 if (!currPropertiesMap.containsKey(propName)) {
3178 currPropertiesMap.put(propName, prop);
3181 List<ComponentInstanceProperty> instPropList = new ArrayList<>();
3182 if (propMap != null && propMap.size() > 0) {
3183 for (List<UploadPropInfo> propertyList : propMap.values()) {
3184 UploadPropInfo propertyInfo = propertyList.get(0);
3185 String propName = propertyInfo.getName();
3186 if (!currPropertiesMap.containsKey(propName)) {
3187 log.debug("failed to find property {} ", propName);
3188 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3189 "ERROR Failed to find property: {}", propName);
3190 return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, propName);
3192 PropertyDefinition curPropertyDef = currPropertiesMap.get(propName);
3193 ComponentInstanceProperty property = null;
3194 String value = null;
3195 List<GetInputValueDataDefinition> getInputs = null;
3196 boolean isValidate = true;
3197 if (propertyInfo.getValue() != null) {
3198 getInputs = propertyInfo.getGet_input();
3199 isValidate = getInputs == null || getInputs.isEmpty();
3201 value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3203 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3206 property = new ComponentInstanceProperty(curPropertyDef, value, null);
3207 String validatePropValue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3208 property.setValue(validatePropValue);
3209 if (getInputs != null && !getInputs.isEmpty()) {
3210 List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3211 for (GetInputValueDataDefinition getInput : getInputs) {
3212 List<InputDefinition> inputs = resource.getInputs();
3213 if (inputs == null || inputs.isEmpty()) {
3214 log.debug("Failed to add property {} to instance. Inputs list is empty ", property);
3215 loggerSupportability
3216 .log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3217 "Failed to add property: {} to instance. Inputs list is empty", propName);
3218 rollbackWithException(ActionStatus.INPUTS_NOT_FOUND,
3219 property.getGetInputValues().stream().map(GetInputValueDataDefinition::getInputName).collect(toList()).toString());
3221 Either<InputDefinition, RuntimeException> inputEither = findInputByName(inputs, getInput);
3222 if (inputEither.isRight()) {
3223 throw inputEither.right().value();
3225 InputDefinition input = inputEither.left().value();
3226 getInput.setInputId(input.getUniqueId());
3227 getInputValues.add(getInput);
3228 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3229 if (getInputIndex != null) {
3230 Either<InputDefinition, RuntimeException> newInputEither = findInputByName(inputs, getInputIndex);
3231 if (inputEither.isRight()) {
3232 throw newInputEither.right().value();
3234 InputDefinition newInput = newInputEither.left().value();
3235 getInputIndex.setInputId(newInput.getUniqueId());
3237 getInputValues.add(getInputIndex);
3241 property.setGetInputValues(getInputValues);
3243 instPropList.add(property);
3244 // delete overriden property
3245 currPropertiesMap.remove(property.getName());
3248 // add rest of properties
3249 if (!currPropertiesMap.isEmpty()) {
3250 for (PropertyDefinition value : currPropertiesMap.values()) {
3251 instPropList.add(new ComponentInstanceProperty(value));
3254 instProperties.put(currentCompInstance.getUniqueId(), instPropList);
3255 return componentsUtils.getResponseFormat(ActionStatus.OK);
3258 // US740820 Relate RIs according to capability name
3259 private CapabilityDefinition findAvailableCapabilityByTypeOrName(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3260 UploadReqInfo uploadReqInfo) {
3261 if (null == uploadReqInfo.getCapabilityName() || validReq.getCapability()
3262 .equals(uploadReqInfo.getCapabilityName())) {// get
3269 return findAvailableCapability(validReq, currentCapCompInstance);
3271 return findAvailableCapability(validReq, currentCapCompInstance, uploadReqInfo);
3274 private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3275 UploadReqInfo uploadReqInfo) {
3276 CapabilityDefinition cap = null;
3277 Map<String, List<CapabilityDefinition>> capMap = currentCapCompInstance.getCapabilities();
3278 if (!capMap.containsKey(validReq.getCapability())) {
3281 Optional<CapabilityDefinition> capByName = capMap.get(validReq.getCapability()).stream()
3282 .filter(p -> p.getName().equals(uploadReqInfo.getCapabilityName())).findAny();
3283 if (capByName.isEmpty()) {
3286 cap = capByName.get();
3287 if (isBoundedByOccurrences(cap)) {
3288 String leftOccurrences = cap.getLeftOccurrences();
3289 int left = Integer.parseInt(leftOccurrences);
3292 cap.setLeftOccurrences(String.valueOf(left));
3298 private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance instance) {
3299 Map<String, List<CapabilityDefinition>> capMap = instance.getCapabilities();
3300 if (capMap.containsKey(validReq.getCapability())) {
3301 List<CapabilityDefinition> capList = capMap.get(validReq.getCapability());
3302 for (CapabilityDefinition cap : capList) {
3303 if (isBoundedByOccurrences(cap)) {
3304 String leftOccurrences = cap.getLeftOccurrences() != null ? cap.getLeftOccurrences() : cap.getMaxOccurrences();
3305 int left = Integer.parseInt(leftOccurrences);
3308 cap.setLeftOccurrences(String.valueOf(left));
3319 private boolean isBoundedByOccurrences(CapabilityDefinition cap) {
3320 return cap.getMaxOccurrences() != null && !cap.getMaxOccurrences().equals(CapabilityDataDefinition.MAX_OCCURRENCES);
3323 private Either<RequirementDefinition, ResponseFormat> findAviableRequiremen(String regName, String yamlName,
3324 UploadComponentInstanceInfo uploadComponentInstanceInfo,
3325 ComponentInstance currentCompInstance, String capName) {
3326 Map<String, List<RequirementDefinition>> comInstRegDefMap = currentCompInstance.getRequirements();
3327 List<RequirementDefinition> list = comInstRegDefMap.get(capName);
3328 RequirementDefinition validRegDef = null;
3330 for (Entry<String, List<RequirementDefinition>> entry : comInstRegDefMap.entrySet()) {
3331 for (RequirementDefinition reqDef : entry.getValue()) {
3332 if (reqDef.getName().equals(regName)) {
3333 if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3334 String leftOccurrences = reqDef.getLeftOccurrences();
3335 if (leftOccurrences == null) {
3336 leftOccurrences = reqDef.getMaxOccurrences();
3338 int left = Integer.parseInt(leftOccurrences);
3341 reqDef.setLeftOccurrences(String.valueOf(left));
3342 validRegDef = reqDef;
3348 validRegDef = reqDef;
3353 if (validRegDef != null) {
3358 for (RequirementDefinition reqDef : list) {
3359 if (reqDef.getName().equals(regName)) {
3360 if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3361 String leftOccurrences = reqDef.getLeftOccurrences();
3362 if (leftOccurrences == null) {
3363 leftOccurrences = reqDef.getMaxOccurrences();
3365 int left = Integer.parseInt(leftOccurrences);
3368 reqDef.setLeftOccurrences(String.valueOf(left));
3369 validRegDef = reqDef;
3375 validRegDef = reqDef;
3381 if (validRegDef == null) {
3382 ResponseFormat responseFormat = componentsUtils
3383 .getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3384 uploadComponentInstanceInfo.getType());
3385 return Either.right(responseFormat);
3387 return Either.left(validRegDef);
3390 private Resource createResourceInstances(String yamlName, Resource resource, Resource oldResource,
3391 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap, Map<String, Resource> nodeNamespaceMap,
3392 Map<String, Resource> existingNodeTypesByResourceNames) {
3393 Either<Resource, ResponseFormat> eitherResource;
3394 log.debug("createResourceInstances is {} - going to create resource instanse from CSAR", yamlName);
3395 if (isEmpty(uploadResInstancesMap) && resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3396 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
3397 throw new ByResponseFormatComponentException(responseFormat);
3399 if (MapUtils.isNotEmpty(nodeNamespaceMap)) {
3400 nodeNamespaceMap.forEach((k, v) -> existingNodeTypesByResourceNames.put(v.getToscaResourceName(), v));
3402 Map<ComponentInstance, Resource> resourcesInstancesMap = new HashMap<>();
3403 uploadResInstancesMap.values().forEach(
3404 i -> createAndAddResourceInstance(i, yamlName, resource, nodeNamespaceMap, existingNodeTypesByResourceNames, resourcesInstancesMap));
3405 if (oldResource != null && oldResource.getResourceType() != ResourceTypeEnum.CVFC && oldResource.getComponentInstances() != null) {
3406 Map<String, Resource> existingNodeTypesByUids = existingNodeTypesByResourceNames.values().stream()
3407 .collect(toMap(Resource::getUniqueId, r -> r));
3408 oldResource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar())
3409 .forEach(uiInst -> resourcesInstancesMap.put(uiInst, getOriginResource(existingNodeTypesByUids, uiInst)));
3411 if (isNotEmpty(resourcesInstancesMap)) {
3413 toscaOperationFacade.associateComponentInstancesToComponent(resource, resourcesInstancesMap, false, oldResource != null);
3414 } catch (StorageException exp) {
3415 if (exp.getStorageOperationStatus() != null && exp.getStorageOperationStatus() != StorageOperationStatus.OK) {
3416 log.debug("Failed to add component instances to container component {}", resource.getName());
3417 ResponseFormat responseFormat = componentsUtils
3418 .getResponseFormat(componentsUtils.convertFromStorageResponse(exp.getStorageOperationStatus()));
3419 eitherResource = Either.right(responseFormat);
3420 throw new ByResponseFormatComponentException(eitherResource.right().value());
3424 if (CollectionUtils.isEmpty(resource.getComponentInstances()) &&
3425 resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3426 log.debug("Error when create resource instance from csar. ComponentInstances list empty");
3427 BeEcompErrorManager.getInstance().logBeDaoSystemError("Error when create resource instance from csar. ComponentInstances list empty");
3428 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE));
3433 private void createAndAddResourceInstance(UploadComponentInstanceInfo uploadComponentInstanceInfo, String yamlName, Resource resource,
3434 Map<String, Resource> nodeNamespaceMap, Map<String, Resource> existingnodeTypeMap,
3435 Map<ComponentInstance, Resource> resourcesInstancesMap) {
3436 Either<Resource, ResponseFormat> eitherResource;
3437 log.debug("*************Going to create resource instances {}", yamlName);
3438 // updating type if the type is node type name - we need to take the
3441 log.debug("*************Going to create resource instances {}", uploadComponentInstanceInfo.getName());
3442 if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3443 uploadComponentInstanceInfo.setType(nodeNamespaceMap.get(uploadComponentInstanceInfo.getType()).getToscaResourceName());
3445 Resource refResource = validateResourceInstanceBeforeCreate(yamlName, uploadComponentInstanceInfo, existingnodeTypeMap, resource);
3446 ComponentInstance componentInstance = new ComponentInstance();
3447 componentInstance.setComponentUid(refResource.getUniqueId());
3448 Collection<String> directives = uploadComponentInstanceInfo.getDirectives();
3449 if (directives != null && !directives.isEmpty()) {
3450 componentInstance.setDirectives(new ArrayList<>(directives));
3452 UploadNodeFilterInfo uploadNodeFilterInfo = uploadComponentInstanceInfo.getUploadNodeFilterInfo();
3453 if (uploadNodeFilterInfo != null) {
3455 .setNodeFilter(new CINodeFilterUtils().getNodeFilterDataDefinition(uploadNodeFilterInfo, componentInstance.getUniqueId()));
3457 ComponentTypeEnum containerComponentType = resource.getComponentType();
3458 NodeTypeEnum containerNodeType = containerComponentType.getNodeType();
3459 if (containerNodeType == NodeTypeEnum.Resource && isNotEmpty(uploadComponentInstanceInfo.getCapabilities()) && isNotEmpty(
3460 refResource.getCapabilities())) {
3461 setCapabilityNamesTypes(refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3462 Map<String, List<CapabilityDefinition>> validComponentInstanceCapabilities = getValidComponentInstanceCapabilities(
3463 refResource.getUniqueId(), refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3464 componentInstance.setCapabilities(validComponentInstanceCapabilities);
3466 if (isNotEmpty(uploadComponentInstanceInfo.getArtifacts())) {
3467 Map<String, Map<String, UploadArtifactInfo>> artifacts = uploadComponentInstanceInfo.getArtifacts();
3468 Map<String, ToscaArtifactDataDefinition> toscaArtifacts = new HashMap<>();
3469 Map<String, Map<String, UploadArtifactInfo>> arts = artifacts.entrySet().stream()
3470 .filter(e -> e.getKey().contains(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName()))
3471 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
3472 Map<String, UploadArtifactInfo> artifact = arts.get(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName());
3473 for (Map.Entry<String, UploadArtifactInfo> entry : artifact.entrySet()) {
3474 ToscaArtifactDataDefinition to = new ToscaArtifactDataDefinition();
3475 to.setFile(entry.getValue().getFile());
3476 to.setType(entry.getValue().getType());
3477 if(isNotEmpty(entry.getValue().getProperties())) {
3478 Map<String, Object> newPropertiesMap = new HashMap<>();
3479 List<UploadPropInfo> artifactPropsInfo = entry.getValue().getProperties();
3480 for(UploadPropInfo propInfo: artifactPropsInfo) {
3481 newPropertiesMap.put(propInfo.getName(), propInfo.getValue());
3483 to.setProperties(newPropertiesMap);
3485 toscaArtifacts.put(entry.getKey(), to);
3487 componentInstance.setToscaArtifacts(toscaArtifacts);
3489 if (!existingnodeTypeMap.containsKey(uploadComponentInstanceInfo.getType())) {
3490 log.debug("createResourceInstances - not found lates version for resource instance with name {} and type {}",
3491 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3492 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3493 uploadComponentInstanceInfo.getType());
3495 Resource origResource = existingnodeTypeMap.get(uploadComponentInstanceInfo.getType());
3496 componentInstance.setName(uploadComponentInstanceInfo.getName());
3497 componentInstance.setIcon(origResource.getIcon());
3498 componentInstance.setCreatedFrom(CreatedFrom.CSAR);
3499 resourcesInstancesMap.put(componentInstance, origResource);
3502 private void setCapabilityNamesTypes(Map<String, List<CapabilityDefinition>> originCapabilities,
3503 Map<String, List<UploadCapInfo>> uploadedCapabilities) {
3504 for (Entry<String, List<UploadCapInfo>> currEntry : uploadedCapabilities.entrySet()) {
3505 if (originCapabilities.containsKey(currEntry.getKey())) {
3506 currEntry.getValue().forEach(cap -> cap.setType(currEntry.getKey()));
3509 for (Map.Entry<String, List<CapabilityDefinition>> capabilities : originCapabilities.entrySet()) {
3510 capabilities.getValue().forEach(cap -> {
3511 if (uploadedCapabilities.containsKey(cap.getName())) {
3512 uploadedCapabilities.get(cap.getName()).forEach(c -> {
3513 c.setName(cap.getName());
3514 c.setType(cap.getType());
3521 private Resource validateResourceInstanceBeforeCreate(String yamlName, UploadComponentInstanceInfo uploadComponentInstanceInfo,
3522 Map<String, Resource> nodeNamespaceMap, Resource resource) {
3523 log.debug("validateResourceInstanceBeforeCreate - going to validate resource instance with name {} and type {} before create",
3524 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3525 Resource refResource;
3526 if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3527 refResource = nodeNamespaceMap.get(uploadComponentInstanceInfo.getType());
3529 Either<Resource, StorageOperationStatus> findResourceEither = StringUtils.isEmpty(resource.getModel()) ?
3530 toscaOperationFacade.getByToscaResourceNameMatchingVendorRelease(uploadComponentInstanceInfo.getType(),
3531 ((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()).getVendorRelease()):
3532 toscaOperationFacade.getLatestByToscaResourceNameAndModel(uploadComponentInstanceInfo.getType(), resource.getModel());
3533 if (findResourceEither.isRight()) {
3534 log.debug("validateResourceInstanceBeforeCreate - not found latest version for resource instance with name {} and type {}",
3535 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3536 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(findResourceEither.right().value()));
3538 refResource = findResourceEither.left().value();
3539 nodeNamespaceMap.put(refResource.getToscaResourceName(), refResource);
3541 String componentState = refResource.getComponentMetadataDefinition().getMetadataDataDefinition().getState();
3542 if (componentState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3544 "validateResourceInstanceBeforeCreate - component instance of component {} can not be created because the component is in an illegal state {}.",
3545 refResource.getName(), componentState);
3546 throw new ByActionStatusComponentException(ActionStatus.ILLEGAL_COMPONENT_STATE, refResource.getComponentType().getValue(),
3547 refResource.getName(), componentState);
3549 if (!ModelConverter.isAtomicComponent(refResource) && refResource.getResourceType() != ResourceTypeEnum.CVFC) {
3550 log.debug("validateResourceInstanceBeforeCreate - ref resource type is {} ", refResource.getResourceType());
3551 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3552 uploadComponentInstanceInfo.getType());
3557 public Resource propagateStateToCertified(User user, Resource resource, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3558 boolean needLock, boolean forceCertificationAllowed) {
3559 boolean failed = false;
3561 if (resource.getLifecycleState() != LifecycleStateEnum.CERTIFIED && forceCertificationAllowed && lifecycleBusinessLogic
3562 .isFirstCertification(resource.getVersion())) {
3563 nodeForceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3565 if (resource.getLifecycleState() == LifecycleStateEnum.CERTIFIED) {
3566 Either<ArtifactDefinition, Operation> eitherPopulated = populateToscaArtifacts(resource, user, false, inTransaction, needLock, false);
3569 return nodeFullCertification(resource.getUniqueId(), user, lifecycleChangeInfo, inTransaction, needLock);
3570 } catch (ComponentException e) {
3572 log.debug("The exception has occurred upon certification of resource {}. ", resource.getName(), e);
3576 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3577 if (!inTransaction) {
3578 janusGraphDao.rollback();
3580 } else if (!inTransaction) {
3581 janusGraphDao.commit();
3586 private Resource nodeFullCertification(String uniqueId, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3588 Either<Resource, ResponseFormat> resourceResponse = lifecycleBusinessLogic
3589 .changeState(uniqueId, user, LifeCycleTransitionEnum.CERTIFY, lifecycleChangeInfo, inTransaction, needLock);
3590 if (resourceResponse.isRight()) {
3591 throw new ByResponseFormatComponentException(resourceResponse.right().value());
3593 return resourceResponse.left().value();
3596 private Resource nodeForceCertification(Resource resource, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3598 return lifecycleBusinessLogic.forceResourceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3601 public ImmutablePair<Resource, ActionStatus> createOrUpdateResourceByImport(final Resource resource, final User user, final boolean isNormative,
3602 final boolean isInTransaction, final boolean needLock,
3603 final CsarInfo csarInfo, final String nodeName,
3604 final boolean isNested) {
3605 ImmutablePair<Resource, ActionStatus> result = null;
3606 // check if resource already exists (search by tosca name = type)
3607 final boolean isNestedResource = isNestedResourceUpdate(csarInfo, nodeName);
3608 final String resourceName = resource.getToscaResourceName();
3609 final Either<Resource, StorageOperationStatus> latestByToscaName = toscaOperationFacade
3610 .getLatestByToscaResourceNameAndModel(resourceName, resource.getModel());
3611 if (latestByToscaName.isLeft() && Objects.nonNull(latestByToscaName.left().value())) {
3612 final Resource foundResource = latestByToscaName.left().value();
3613 // we don't allow updating names of top level types
3614 if (!isNestedResource && !StringUtils.equals(resource.getName(), foundResource.getName())) {
3615 BeEcompErrorManager.getInstance()
3616 .logBeComponentMissingError("Create / Update resource by import", ComponentTypeEnum.RESOURCE.getValue(), resource.getName());
3617 log.debug("resource already exist new name={} old name={} same type={}", resource.getName(), foundResource.getName(),
3618 resource.getToscaResourceName());
3619 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
3620 componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3621 throwComponentException(responseFormat);
3623 result = updateExistingResourceByImport(resource, foundResource, user, isNormative, needLock, isNested);
3624 } else if (isNotFound(latestByToscaName)) {
3625 if (isNestedResource) {
3626 result = createOrUpdateNestedResource(resource, user, isNormative, isInTransaction, needLock, csarInfo, isNested, nodeName);
3628 result = createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3631 StorageOperationStatus status = latestByToscaName.right().value();
3632 log.debug("failed to get latest version of resource {}. status={}", resource.getName(), status);
3633 ResponseFormat responseFormat = componentsUtils
3634 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(latestByToscaName.right().value()), resource);
3635 componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3636 throwComponentException(responseFormat);
3641 private boolean isNestedResourceUpdate(CsarInfo csarInfo, String nodeName) {
3642 return csarInfo != null && csarInfo.isUpdate() && nodeName != null;
3645 private ImmutablePair<Resource, ActionStatus> createOrUpdateNestedResource(final Resource resource, final User user, final boolean isNormative,
3646 final boolean isInTransaction, final boolean needLock,
3647 final CsarInfo csarInfo, final boolean isNested,
3648 final String nodeName) {
3649 final Either<Component, StorageOperationStatus> latestByToscaName = toscaOperationFacade.getLatestByToscaResourceName(
3650 buildNestedToscaResourceName(resource.getResourceType().name(), csarInfo.getVfResourceName(), nodeName).getRight(), resource.getModel());
3651 if (latestByToscaName.isLeft()) {
3652 final Resource nestedResource = (Resource) latestByToscaName.left().value();
3653 log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
3654 final Either<Boolean, ResponseFormat> eitherValidation = validateNestedDerivedFromDuringUpdate(nestedResource, resource,
3655 ValidationUtils.hasBeenCertified(nestedResource.getVersion()));
3656 if (eitherValidation.isRight()) {
3657 return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3659 return updateExistingResourceByImport(resource, nestedResource, user, isNormative, needLock, isNested);
3661 return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3665 private boolean isNotFound(Either<Resource, StorageOperationStatus> getResourceEither) {
3666 return getResourceEither.isRight() && getResourceEither.right().value() == StorageOperationStatus.NOT_FOUND;
3669 private ImmutablePair<Resource, ActionStatus> createResourceByImport(Resource resource, User user, boolean isNormative, boolean isInTransaction,
3670 CsarInfo csarInfo) {
3671 log.debug("resource with name {} does not exist. create new resource", resource.getName());
3672 validateResourceBeforeCreate(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isInTransaction, csarInfo);
3673 final Resource createResourceByDao = createResourceByDao(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isNormative, isInTransaction);
3674 Resource createdResource = updateCatalog(createResourceByDao, ChangeTypeEnum.LIFECYCLE).left().map(r -> (Resource) r).left().value();
3675 ImmutablePair<Resource, ActionStatus> resourcePair = new ImmutablePair<>(createdResource, ActionStatus.CREATED);
3676 ASDCKpiApi.countImportResourcesKPI();
3677 return resourcePair;
3680 public boolean isResourceExist(String resourceName) {
3681 Either<Resource, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByName(resourceName, null);
3682 return latestByName.isLeft();
3685 private ImmutablePair<Resource, ActionStatus> updateExistingResourceByImport(Resource newResource, Resource oldResource, User user,
3686 boolean inTransaction, boolean needLock, boolean isNested) {
3687 String lockedResourceId = oldResource.getUniqueId();
3688 log.debug("found resource: name={}, id={}, version={}, state={}", oldResource.getName(), lockedResourceId, oldResource.getVersion(),
3689 oldResource.getLifecycleState());
3690 ImmutablePair<Resource, ActionStatus> resourcePair = null;
3692 lockComponent(lockedResourceId, oldResource, needLock, "Update Resource by Import");
3693 oldResource = prepareResourceForUpdate(oldResource, newResource, user, inTransaction, false);
3694 mergeOldResourceMetadataWithNew(oldResource, newResource);
3695 validateResourceFieldsBeforeUpdate(oldResource, newResource, inTransaction, isNested);
3696 validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), newResource, AuditingActionEnum.IMPORT_RESOURCE, inTransaction);
3697 // contact info normalization
3698 newResource.setContactId(newResource.getContactId().toLowerCase());
3699 PropertyConstraintsUtils.validatePropertiesConstraints(newResource, oldResource);
3700 // non-updatable fields
3701 newResource.setCreatorUserId(user.getUserId());
3702 newResource.setCreatorFullName(user.getFullName());
3703 newResource.setLastUpdaterUserId(user.getUserId());
3704 newResource.setLastUpdaterFullName(user.getFullName());
3705 newResource.setUniqueId(oldResource.getUniqueId());
3706 newResource.setVersion(oldResource.getVersion());
3707 newResource.setInvariantUUID(oldResource.getInvariantUUID());
3708 newResource.setLifecycleState(oldResource.getLifecycleState());
3709 newResource.setUUID(oldResource.getUUID());
3710 newResource.setNormalizedName(oldResource.getNormalizedName());
3711 newResource.setSystemName(oldResource.getSystemName());
3712 newResource.setModel(oldResource.getModel());
3713 if (oldResource.getCsarUUID() != null) {
3714 newResource.setCsarUUID(oldResource.getCsarUUID());
3716 if (oldResource.getImportedToscaChecksum() != null) {
3717 newResource.setImportedToscaChecksum(oldResource.getImportedToscaChecksum());
3719 newResource.setAbstract(oldResource.isAbstract());
3720 if (CollectionUtils.isEmpty(newResource.getDerivedFrom())) {
3721 newResource.setDerivedFrom(oldResource.getDerivedFrom());
3723 if (CollectionUtils.isEmpty(newResource.getDataTypes())) {
3724 newResource.setDataTypes(oldResource.getDataTypes());
3726 if (StringUtils.isEmpty(newResource.getDerivedFromGenericType())) {
3727 newResource.setDerivedFromGenericType(oldResource.getDerivedFromGenericType());
3729 if (StringUtils.isEmpty(newResource.getDerivedFromGenericVersion())) {
3730 newResource.setDerivedFromGenericVersion(oldResource.getDerivedFromGenericVersion());
3734 // created without tosca artifacts - add the placeholders
3735 if (MapUtils.isEmpty(newResource.getToscaArtifacts())) {
3736 setToscaArtifactsPlaceHolders(newResource, user);
3738 if (MapUtils.isEmpty(newResource.getInterfaces())) {
3739 newResource.setInterfaces(oldResource.getInterfaces());
3741 if (CollectionUtils.isEmpty(newResource.getAttributes())) {
3742 newResource.setAttributes(oldResource.getAttributes());
3744 if (CollectionUtils.isEmpty(newResource.getProperties())) {
3745 newResource.setProperties(oldResource.getProperties());
3747 Either<Resource, StorageOperationStatus> overrideResource = toscaOperationFacade.overrideComponent(newResource, oldResource);
3748 if (overrideResource.isRight()) {
3749 ResponseFormat responseFormat = componentsUtils
3750 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(overrideResource.right().value()), newResource);
3751 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE);
3752 throwComponentException(responseFormat);
3754 updateCatalog(overrideResource.left().value(), ChangeTypeEnum.LIFECYCLE);
3755 log.debug("Resource updated successfully!!!");
3756 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3757 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3758 ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3759 resourcePair = new ImmutablePair<>(overrideResource.left().value(), ActionStatus.OK);
3760 return resourcePair;
3762 if (resourcePair == null) {
3763 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3764 janusGraphDao.rollback();
3765 } else if (!inTransaction) {
3766 janusGraphDao.commit();
3769 log.debug("unlock resource {}", lockedResourceId);
3770 graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource);
3776 * Merge old resource with new. Keep old category and vendor name without change
3778 * @param oldResource
3779 * @param newResource
3781 private void mergeOldResourceMetadataWithNew(Resource oldResource, Resource newResource) {
3782 // keep old category and vendor name without change
3784 // merge the rest of the resource metadata
3785 if (newResource.getTags() == null || newResource.getTags().isEmpty()) {
3786 newResource.setTags(oldResource.getTags());
3788 if (newResource.getDescription() == null) {
3789 newResource.setDescription(oldResource.getDescription());
3791 if (newResource.getVendorRelease() == null) {
3792 newResource.setVendorRelease(oldResource.getVendorRelease());
3794 if (newResource.getResourceVendorModelNumber() == null) {
3795 newResource.setResourceVendorModelNumber(oldResource.getResourceVendorModelNumber());
3797 if (newResource.getModel() == null) {
3798 newResource.setModel(oldResource.getModel());
3800 if (newResource.getContactId() == null) {
3801 newResource.setContactId(oldResource.getContactId());
3803 newResource.setCategories(oldResource.getCategories());
3804 if (newResource.getVendorName() == null) {
3805 newResource.setVendorName(oldResource.getVendorName());
3807 List<GroupDefinition> oldForUpdate = oldResource.getGroups();
3808 if (CollectionUtils.isNotEmpty(oldForUpdate)) {
3809 List<GroupDefinition> groupForUpdate = oldForUpdate.stream().map(GroupDefinition::new).collect(Collectors.toList());
3810 groupForUpdate.stream().filter(GroupDataDefinition::isVspOriginated).forEach(group -> group.setName(group.getInvariantName()));
3811 newResource.setGroups(groupForUpdate);
3813 if (newResource.getResourceType().isAtomicType() && !newResource.getName().equals("Root")
3814 && newResource.getResourceType() != ResourceTypeEnum.CVFC) {
3815 ResourceTypeEnum updatedResourceType = newResource.getResourceType();
3816 Optional<Component> derivedFromResourceOptional = getParentComponent(newResource);
3817 if (derivedFromResourceOptional.isPresent() && derivedFromResourceOptional.get().getComponentType() == ComponentTypeEnum.RESOURCE) {
3818 Resource parentResource = (Resource) derivedFromResourceOptional.get();
3819 if (!(parentResource.isAbstract() && (ResourceTypeEnum.VFC == parentResource.getResourceType()
3820 || ResourceTypeEnum.ABSTRACT == parentResource.getResourceType())) && parentResource.getResourceType() != updatedResourceType
3821 && oldResource.getResourceType() != updatedResourceType) {
3822 BeEcompErrorManager.getInstance().logInternalDataError("mergeOldResourceMetadataWithNew",
3823 "resource type of the resource does not match to derived from resource type", ErrorSeverity.ERROR);
3825 "#mergeOldResourceMetadataWithNew - resource type {} of the resource {} does not match to derived from resource type {}",
3826 newResource.getResourceType(), newResource.getToscaResourceName(), parentResource.getResourceType());
3827 throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_TYPE);
3833 private Optional<Component> getParentComponent(Resource newResource) {
3834 if (newResource.getDerivedFrom() == null) {
3835 return Optional.empty();
3837 String toscaResourceNameDerivedFrom = newResource.getDerivedFrom().get(0);
3838 Either<Component, StorageOperationStatus> latestByToscaResourceName = toscaOperationFacade
3839 .getLatestByToscaResourceName(toscaResourceNameDerivedFrom, newResource.getModel());
3840 if (latestByToscaResourceName.isRight()) {
3841 BeEcompErrorManager.getInstance()
3842 .logInternalDataError("mergeOldResourceMetadataWithNew", "derived from resource not found", ErrorSeverity.ERROR);
3843 log.debug("#mergeOldResourceMetadataWithNew - derived from resource {} not found", toscaResourceNameDerivedFrom);
3844 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, toscaResourceNameDerivedFrom);
3846 return Optional.of(latestByToscaResourceName.left().value());
3849 private Resource prepareResourceForUpdate(Resource oldResource, Resource newResource, User user, boolean inTransaction, boolean needLock) {
3850 if (!ComponentValidationUtils.canWorkOnResource(oldResource, user.getUserId())) {
3852 return lifecycleBusinessLogic
3853 .changeState(oldResource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, new LifecycleChangeInfoWithAction("update by import"),
3854 inTransaction, needLock).left().on(response -> failOnChangeState(response, user, oldResource, newResource));
3859 private Resource failOnChangeState(ResponseFormat response, User user, Resource oldResource, Resource newResource) {
3860 log.info("resource {} cannot be updated. reason={}", oldResource.getUniqueId(), response.getFormattedMessage());
3861 componentsUtils.auditResource(response, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3862 ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3863 throw new ByResponseFormatComponentException(response);
3866 public Resource validateResourceBeforeCreate(Resource resource, User user, AuditingActionEnum actionEnum, boolean inTransaction,
3867 CsarInfo csarInfo) {
3868 validateResourceFieldsBeforeCreate(user, resource, actionEnum, inTransaction);
3869 validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), resource, actionEnum, inTransaction);
3870 validateLifecycleTypesCreate(user, resource, actionEnum);
3871 validateResourceType(user, resource, actionEnum);
3872 resource.setCreatorUserId(user.getUserId());
3873 resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
3874 resource.setContactId(resource.getContactId().toLowerCase());
3875 if (StringUtils.isEmpty(resource.getToscaResourceName()) && !ModelConverter.isAtomicComponent(resource)) {
3876 String resourceSystemName;
3877 if (csarInfo != null && StringUtils.isNotEmpty(csarInfo.getVfResourceName())) {
3878 resourceSystemName = ValidationUtils.convertToSystemName(csarInfo.getVfResourceName());
3880 resourceSystemName = resource.getSystemName();
3883 .setToscaResourceName(CommonBeUtils.generateToscaResourceName(resource.getResourceType().name().toLowerCase(), resourceSystemName));
3885 // Generate invariant UUID - must be here and not in operation since it
3887 // should stay constant during clone
3890 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
3891 resource.setInvariantUUID(invariantUUID);
3895 private Either<Boolean, ResponseFormat> validateResourceType(User user, Resource resource, AuditingActionEnum actionEnum) {
3896 Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3897 if (resource.getResourceType() == null) {
3898 log.debug("Invalid resource type for resource");
3899 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
3900 eitherResult = Either.right(errorResponse);
3901 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3903 return eitherResult;
3906 private Either<Boolean, ResponseFormat> validateLifecycleTypesCreate(User user, Resource resource, AuditingActionEnum actionEnum) {
3907 Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3908 if (resource.getInterfaces() != null && resource.getInterfaces().size() > 0) {
3909 log.debug("validate interface lifecycle Types Exist");
3910 Iterator<InterfaceDefinition> intItr = resource.getInterfaces().values().iterator();
3911 while (intItr.hasNext() && eitherResult.isLeft()) {
3912 InterfaceDefinition interfaceDefinition = intItr.next();
3913 String intType = interfaceDefinition.getUniqueId();
3914 Either<InterfaceDefinition, StorageOperationStatus> eitherCapTypeFound = interfaceTypeOperation.getInterface(intType);
3915 if (eitherCapTypeFound.isRight()) {
3916 if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3917 BeEcompErrorManager.getInstance()
3918 .logBeGraphObjectMissingError("Create Resource - validateLifecycleTypesCreate", "Interface", intType);
3919 log.debug("Lifecycle Type: {} is required by resource: {} but does not exist in the DB", intType, resource.getName());
3920 BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateLifecycleTypesCreate");
3921 log.debug("request to data model failed with error: {}", eitherCapTypeFound.right().value().name());
3923 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_LIFECYCLE_TYPE, intType);
3924 eitherResult = Either.right(errorResponse);
3925 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3929 return eitherResult;
3932 private Either<Boolean, ResponseFormat> validateCapabilityTypesCreate(User user, ICapabilityTypeOperation capabilityTypeOperation,
3933 Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
3934 Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3935 if (resource.getCapabilities() != null && resource.getCapabilities().size() > 0) {
3936 log.debug("validate capability Types Exist - capabilities section");
3937 for (Entry<String, List<CapabilityDefinition>> typeEntry : resource.getCapabilities().entrySet()) {
3938 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, actionEnum, eitherResult, typeEntry,
3940 if (eitherResult.isRight()) {
3941 return Either.right(eitherResult.right().value());
3945 if (resource.getRequirements() != null && resource.getRequirements().size() > 0) {
3946 log.debug("validate capability Types Exist - requirements section");
3947 for (String type : resource.getRequirements().keySet()) {
3948 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, resource.getRequirements().get(type), actionEnum,
3949 eitherResult, type, inTransaction);
3950 if (eitherResult.isRight()) {
3951 return Either.right(eitherResult.right().value());
3955 return eitherResult;
3958 // @param typeObject- the object to which the validation is done
3959 private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3960 Resource resource, List<?> validationObjects, AuditingActionEnum actionEnum,
3961 Either<Boolean, ResponseFormat> eitherResult, String type,
3962 boolean inTransaction) {
3963 Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation.getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), type), inTransaction);
3964 if (eitherCapTypeFound.isRight()) {
3965 if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3966 BeEcompErrorManager.getInstance().logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", type);
3967 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", type, resource.getName());
3968 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3970 log.debug("Trying to get capability type {} failed with error: {}", type, eitherCapTypeFound.right().value().name());
3971 ResponseFormat errorResponse = null;
3973 errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, type);
3975 errorResponse = componentsUtils.getResponseFormatByElement(ActionStatus.MISSING_CAPABILITY_TYPE, validationObjects);
3977 eitherResult = Either.right(errorResponse);
3978 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3980 return eitherResult;
3983 private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3984 Resource resource, AuditingActionEnum actionEnum,
3985 Either<Boolean, ResponseFormat> eitherResult,
3986 Entry<String, List<CapabilityDefinition>> typeEntry, boolean inTransaction) {
3987 Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation
3988 .getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), typeEntry.getKey()), inTransaction);
3989 if (eitherCapTypeFound.isRight()) {
3990 if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3991 BeEcompErrorManager.getInstance()
3992 .logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", typeEntry.getKey());
3993 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", typeEntry.getKey(), resource.getName());
3994 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3996 log.debug("Trying to get capability type {} failed with error: {}", typeEntry.getKey(), eitherCapTypeFound.right().value().name());
3997 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, typeEntry.getKey());
3998 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3999 return Either.right(errorResponse);
4001 CapabilityTypeDefinition capabilityTypeDefinition = eitherCapTypeFound.left().value();
4002 if (capabilityTypeDefinition.getProperties() != null) {
4003 for (CapabilityDefinition capDef : typeEntry.getValue()) {
4004 List<ComponentInstanceProperty> properties = capDef.getProperties();
4005 List<ComponentInstanceProperty> changedProperties = new ArrayList<>();
4006 if (properties == null || properties.isEmpty()) {
4007 for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
4008 ComponentInstanceProperty newProp = new ComponentInstanceProperty(prop.getValue());
4009 changedProperties.add(newProp);
4012 List<ComponentInstanceProperty> propsToAdd = new ArrayList<>();
4013 for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
4014 PropertyDefinition propFromDef = prop.getValue();
4015 boolean propFound = false;
4016 for (ComponentInstanceProperty cip : properties) {
4017 if (propFromDef.getName().equals(cip.getName())) {
4018 //merge property value and property description only, ignore other fields
4019 if (cip.getDescription() != null && !cip.getDescription().equals(propFromDef.getDescription())) {
4020 propFromDef.setDescription(cip.getDescription());
4022 propertyDataValueMergeBusinessLogic.mergePropertyValue(propFromDef, cip, new ArrayList<>());
4023 if (cip.getValue() != null) {
4024 propFromDef.setValue(cip.getValue());
4026 propsToAdd.add(new ComponentInstanceProperty(propFromDef));
4028 properties.remove(cip);
4033 propsToAdd.add(new ComponentInstanceProperty(propFromDef));
4036 if (!propsToAdd.isEmpty()) {
4037 changedProperties.addAll(propsToAdd);
4040 capDef.setProperties(changedProperties);
4043 return eitherResult;
4046 public Resource createResourceByDao(Resource resource, User user, AuditingActionEnum actionEnum, boolean isNormative, boolean inTransaction) {
4049 // lock new resource name in order to avoid creation resource with same
4052 Resource createdResource = null;
4053 if (!inTransaction) {
4054 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE);
4055 if (lockResult.isRight()) {
4056 ResponseFormat responseFormat = lockResult.right().value();
4057 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4058 throw new ByResponseFormatComponentException(responseFormat);
4060 log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult);
4063 if (resource.deriveFromGeneric()) {
4064 handleResourceGenericType(resource);
4066 createdResource = createResourceTransaction(resource, user, isNormative);
4067 componentsUtils.auditResource(componentsUtils.getResponseFormat(ActionStatus.CREATED), user, createdResource, actionEnum);
4068 ASDCKpiApi.countCreatedResourcesKPI();
4069 } catch (ComponentException e) {
4070 ResponseFormat responseFormat =
4071 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
4072 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4074 } catch (StorageException e) {
4075 ResponseFormat responseFormat = componentsUtils
4076 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
4077 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4080 if (!inTransaction) {
4081 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
4084 return createdResource;
4087 private Resource createResourceTransaction(Resource resource, User user, boolean isNormative) {
4088 final String resourceName = resource.getName();
4089 final String modelName = resource.getModel();
4090 final ResourceTypeEnum resourceType = resource.getResourceType();
4091 final ComponentTypeEnum componentType = resource.getComponentType();
4092 final Either<Boolean, StorageOperationStatus> eitherValidation = toscaOperationFacade
4093 .validateComponentNameAndModelExists(resourceName, modelName, resourceType, componentType);
4094 if (eitherValidation.isRight()) {
4095 loggerSupportability.log(LoggerSupportabilityActions.VALIDATE_NAME, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4096 "ERROR while validate component name {} Status is: {}", resource.getName(), eitherValidation.right().value());
4097 log.debug("Failed to validate component name {}. Status is {}. ", resource.getName(), eitherValidation.right().value());
4098 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(eitherValidation.right().value()));
4100 if (eitherValidation.left().value()) {
4101 log.debug("resource with name: {}, already exists", resource.getName());
4102 loggerSupportability
4103 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4104 "resource with name: {} already exists", resource.getName());
4105 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4106 resource.getName());
4108 log.debug("send resource {} to dao for create", resource.getName());
4109 createArtifactsPlaceHolderData(resource, user);
4112 log.debug("enrich resource with creator, version and state");
4113 resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
4114 resource.setVersion(INITIAL_VERSION);
4115 resource.setHighestVersion(true);
4116 if (resource.getResourceType() != null && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4117 resource.setAbstract(false);
4120 return toscaOperationFacade.createToscaComponent(resource).left().on(r -> throwComponentExceptionByResource(r, resource));
4123 private Resource throwComponentExceptionByResource(StorageOperationStatus status, Resource resource) {
4124 ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(status), resource);
4125 throw new ByResponseFormatComponentException(responseFormat);
4128 private void createArtifactsPlaceHolderData(Resource resource, User user) {
4129 // create mandatory artifacts
4131 // TODO it must be removed after that artifact uniqueId creation will be
4133 // moved to ArtifactOperation
4134 setInformationalArtifactsPlaceHolder(resource, user);
4135 setDeploymentArtifactsPlaceHolder(resource, user);
4136 setToscaArtifactsPlaceHolders(resource, user);
4139 @SuppressWarnings("unchecked")
4141 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
4142 Resource resource = (Resource) component;
4143 Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
4144 if (artifactMap == null) {
4145 artifactMap = new HashMap<>();
4147 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4148 .getDeploymentResourceArtifacts();
4149 if (deploymentResourceArtifacts != null) {
4150 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
4151 deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
4153 resource.setDeploymentArtifacts(artifactMap);
4156 private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
4157 Map<String, Object> artifactDetails = (Map<String, Object>) v;
4158 Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
4159 if (object != null) {
4160 List<String> artifactTypes = (List<String>) object;
4161 if (!artifactTypes.contains(resource.getResourceType().name())) {
4165 log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
4167 if (artifactsBusinessLogic != null) {
4168 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4169 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
4170 if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
4171 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4176 @SuppressWarnings("unchecked")
4177 private void setInformationalArtifactsPlaceHolder(Resource resource, User user) {
4178 Map<String, ArtifactDefinition> artifactMap = resource.getArtifacts();
4179 if (artifactMap == null) {
4180 artifactMap = new HashMap<>();
4182 String resourceUniqueId = resource.getUniqueId();
4183 List<String> exludeResourceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceCategory();
4184 List<String> exludeResourceType = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceType();
4185 Map<String, Object> informationalResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4186 .getInformationalResourceArtifacts();
4187 List<CategoryDefinition> categories = resource.getCategories();
4188 boolean isCreateArtifact = true;
4189 if (exludeResourceCategory != null) {
4190 String category = categories.get(0).getName();
4191 isCreateArtifact = exludeResourceCategory.stream().noneMatch(e -> e.equalsIgnoreCase(category));
4193 if (isCreateArtifact && exludeResourceType != null) {
4194 String resourceType = resource.getResourceType().name();
4195 isCreateArtifact = exludeResourceType.stream().noneMatch(e -> e.equalsIgnoreCase(resourceType));
4197 if (informationalResourceArtifacts != null && isCreateArtifact) {
4198 Set<String> keys = informationalResourceArtifacts.keySet();
4199 for (String informationalResourceArtifactName : keys) {
4200 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalResourceArtifacts.get(informationalResourceArtifactName);
4201 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4202 .createArtifactPlaceHolderInfo(resourceUniqueId, informationalResourceArtifactName, artifactInfoMap, user,
4203 ArtifactGroupTypeEnum.INFORMATIONAL);
4204 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4207 resource.setArtifacts(artifactMap);
4217 public ResponseFormat deleteResource(String resourceId, User user) {
4218 ResponseFormat responseFormat;
4219 validateUserExists(user);
4220 Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4221 if (resourceStatus.isRight()) {
4222 log.debug("failed to get resource {}", resourceId);
4223 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), "");
4225 Resource resource = resourceStatus.left().value();
4226 StorageOperationStatus result = StorageOperationStatus.OK;
4227 lockComponent(resourceId, resource, "Mark resource to delete");
4229 result = markComponentToDelete(resource);
4230 if (result == StorageOperationStatus.OK) {
4231 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4233 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4234 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4236 return responseFormat;
4238 if (!StorageOperationStatus.OK.equals(result)) {
4239 janusGraphDao.rollback();
4241 janusGraphDao.commit();
4243 graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
4247 public ResponseFormat deleteResourceByNameAndVersion(String resourceName, String version, User user) {
4248 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4249 validateUserExists(user);
4250 Resource resource = null;
4251 StorageOperationStatus result = StorageOperationStatus.OK;
4252 boolean failed = false;
4254 Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade
4255 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, version);
4256 if (resourceStatus.isRight()) {
4257 log.debug("failed to get resource {} version {}", resourceName, version);
4258 return componentsUtils
4259 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), resourceName);
4261 resource = resourceStatus.left().value();
4263 janusGraphDao.commit();
4265 if (resource != null) {
4266 lockComponent(resource.getUniqueId(), resource, DELETE_RESOURCE);
4268 result = markComponentToDelete(resource);
4269 if (result != StorageOperationStatus.OK) {
4270 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4271 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4272 return responseFormat;
4274 } catch (ComponentException e) {
4278 if (failed || !StorageOperationStatus.OK.equals(result)) {
4279 janusGraphDao.rollback();
4281 janusGraphDao.commit();
4283 graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource);
4286 return responseFormat;
4289 public Either<Resource, ResponseFormat> getResource(String resourceId, User user) {
4291 validateUserExists(user);
4293 Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceId);
4294 if (storageStatus.isRight()) {
4295 log.debug("failed to get resource by id {}", resourceId);
4296 return Either.right(
4297 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), resourceId));
4299 if (storageStatus.left().value() == null) {
4300 return Either.right(componentsUtils
4301 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), resourceId));
4303 return Either.left(storageStatus.left().value());
4306 public Either<Resource, ResponseFormat> getResourceByNameAndVersion(String resourceName, String resourceVersion, String userId) {
4307 validateUserExists(userId);
4308 Either<Resource, StorageOperationStatus> getResource = toscaOperationFacade
4309 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion);
4310 if (getResource.isRight()) {
4311 log.debug("failed to get resource by name {} and version {}", resourceName, resourceVersion);
4312 return Either.right(
4313 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResource.right().value()), resourceName));
4315 return Either.left(getResource.left().value());
4319 * updateResourceMetadata
4321 * @param user - modifier data (userId)
4322 * @param inTransaction TODO
4323 * @param resourceIdToUpdate - the resource identifier
4324 * @param newResource
4325 * @return Either<Resource, responseFormat>
4327 public Resource updateResourceMetadata(String resourceIdToUpdate, Resource newResource, Resource currentResource, User user,
4328 boolean inTransaction) {
4329 validateUserExists(user.getUserId());
4330 log.debug("Get resource with id {}", resourceIdToUpdate);
4331 boolean needToUnlock = false;
4333 if (currentResource == null) {
4334 Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceIdToUpdate);
4335 if (storageStatus.isRight()) {
4336 throw new ByResponseFormatComponentException(
4337 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), ""));
4339 currentResource = storageStatus.left().value();
4341 // verify that resource is checked-out and the user is the last
4344 if (!ComponentValidationUtils.canWorkOnResource(currentResource, user.getUserId())) {
4345 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
4348 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4349 if (lockResult != StorageOperationStatus.OK) {
4350 BeEcompErrorManager.getInstance()
4351 .logBeFailedLockObjectError("Upload Artifact - lock ", NodeTypeEnum.Resource.getName(), resourceIdToUpdate);
4352 log.debug("Failed to lock resource: {}, error - {}", resourceIdToUpdate, lockResult);
4353 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult));
4354 throw new ByResponseFormatComponentException(responseFormat);
4356 needToUnlock = true;
4357 // critical section starts here
4359 // convert json to object
4361 // Update and updated resource must have a non-empty "derivedFrom"
4365 // This code is not called from import resources, because of root
4367 // VF "derivedFrom" should be null (or ignored)
4368 if (ModelConverter.isAtomicComponent(currentResource)) {
4369 validateDerivedFromNotEmpty(null, newResource, null);
4370 validateDerivedFromNotEmpty(null, currentResource, null);
4372 newResource.setDerivedFrom(null);
4374 Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource, false,
4376 if (dataModelResponse.isRight()) {
4377 log.debug("failed to update resource metadata!!!");
4378 throw new ByResponseFormatComponentException(dataModelResponse.right().value());
4380 log.debug("Resource metadata updated successfully!!!");
4381 return dataModelResponse.left().value();
4382 } catch (ComponentException | StorageException e) {
4383 rollback(inTransaction, newResource, null, null);
4386 if (!inTransaction) {
4387 janusGraphDao.commit();
4390 graphLockOperation.unlockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4395 private Either<Resource, ResponseFormat> updateResourceMetadata(String resourceIdToUpdate, Resource newResource, User user,
4396 Resource currentResource, boolean shouldLock, boolean inTransaction) {
4397 updateVfModuleGroupsNames(currentResource, newResource);
4398 validateResourceFieldsBeforeUpdate(currentResource, newResource, inTransaction, false);
4399 // Setting last updater and uniqueId
4400 newResource.setContactId(newResource.getContactId().toLowerCase());
4401 newResource.setLastUpdaterUserId(user.getUserId());
4402 newResource.setUniqueId(resourceIdToUpdate);
4403 // Cannot set highest version through UI
4404 newResource.setHighestVersion(currentResource.isHighestVersion());
4405 newResource.setCreationDate(currentResource.getCreationDate());
4406 Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom = processUpdateOfDerivedFrom(currentResource, newResource, user.getUserId(),
4408 if (processUpdateOfDerivedFrom.isRight()) {
4409 log.debug("Couldn't update derived from for resource {}", resourceIdToUpdate);
4410 return Either.right(processUpdateOfDerivedFrom.right().value());
4412 log.debug("send resource {} to dao for update", newResource.getUniqueId());
4413 if (isNotEmpty(newResource.getGroups())) {
4414 for (GroupDefinition group : newResource.getGroups()) {
4415 if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
4417 .validateAndUpdateGroupMetadata(newResource.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId(), user,
4418 newResource.getComponentType(), group, true, false);
4422 Either<Resource, StorageOperationStatus> dataModelResponse = toscaOperationFacade.updateToscaElement(newResource);
4423 if (dataModelResponse.isRight()) {
4424 ResponseFormat responseFormat = componentsUtils
4425 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), newResource);
4426 return Either.right(responseFormat);
4427 } else if (dataModelResponse.left().value() == null) {
4428 log.debug("No response from updateResource");
4429 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
4431 return Either.left(dataModelResponse.left().value());
4434 private void updateVfModuleGroupsNames(Resource currentResource, Resource newResource) {
4435 if (currentResource.getGroups() != null && !currentResource.getName().equals(newResource.getName())) {
4436 List<GroupDefinition> updatedGroups = currentResource.getGroups().stream()
4437 .map(group -> getUpdatedGroup(group, currentResource.getName(), newResource.getName())).collect(toList());
4438 newResource.setGroups(updatedGroups);
4442 private GroupDefinition getUpdatedGroup(GroupDefinition currGroup, String replacePattern, String with) {
4443 GroupDefinition updatedGroup = new GroupDefinition(currGroup);
4444 if (updatedGroup.isSamePrefix(replacePattern) && updatedGroup.getType().equals(DEFAULT_GROUP_VF_MODULE)) {
4445 String prefix = updatedGroup.getName().substring(0, replacePattern.length());
4446 String newGroupName = updatedGroup.getName().replaceFirst(prefix, with);
4447 updatedGroup.setName(newGroupName);
4449 return updatedGroup;
4453 * validateResourceFieldsBeforeCreate
4455 * @param user - modifier data (userId)
4457 private void validateResourceFieldsBeforeCreate(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4458 componentValidator.validate(user, resource, actionEnum);
4459 // validate category
4460 log.debug("validate category");
4461 validateCategory(user, resource, actionEnum, inTransaction);
4462 // validate vendor name & release & model number
4463 log.debug("validate vendor name");
4464 validateVendorName(user, resource, actionEnum);
4465 log.debug("validate vendor release");
4466 validateVendorReleaseName(user, resource, actionEnum);
4467 log.debug("validate resource vendor model number");
4468 validateResourceVendorModelNumber(user, resource, actionEnum);
4470 log.debug("validate cost");
4471 validateCost(resource);
4472 // validate licenseType
4473 log.debug("validate licenseType");
4474 validateLicenseType(user, resource, actionEnum);
4475 // validate template (derived from)
4476 log.debug("validate derived from");
4477 if (!ModelConverter.isAtomicComponent(resource) && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4478 resource.setDerivedFrom(null);
4480 validateDerivedFromExist(user, resource, actionEnum);
4481 // warn about non-updatable fields
4482 checkComponentFieldsForOverrideAttempt(resource);
4483 String currentCreatorFullName = resource.getCreatorFullName();
4484 if (currentCreatorFullName != null) {
4485 log.debug("Resource Creator fullname is automatically set and cannot be updated");
4487 String currentLastUpdaterFullName = resource.getLastUpdaterFullName();
4488 if (currentLastUpdaterFullName != null) {
4489 log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4491 Long currentLastUpdateDate = resource.getLastUpdateDate();
4492 if (currentLastUpdateDate != null) {
4493 log.debug("Resource last update date is automatically set and cannot be updated");
4495 Boolean currentAbstract = resource.isAbstract();
4496 if (currentAbstract != null) {
4497 log.debug("Resource abstract is automatically set and cannot be updated");
4502 * validateResourceFieldsBeforeUpdate
4504 * @param currentResource - Resource object to validate
4507 private void validateResourceFieldsBeforeUpdate(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4508 validateFields(currentResource, updateInfoResource, inTransaction, isNested);
4509 warnNonEditableFields(currentResource, updateInfoResource);
4512 private void warnNonEditableFields(Resource currentResource, Resource updateInfoResource) {
4513 String currentResourceVersion = currentResource.getVersion();
4514 String updatedResourceVersion = updateInfoResource.getVersion();
4515 if ((updatedResourceVersion != null) && (!updatedResourceVersion.equals(currentResourceVersion))) {
4516 log.debug("Resource version is automatically set and cannot be updated");
4518 String currentCreatorUserId = currentResource.getCreatorUserId();
4519 String updatedCreatorUserId = updateInfoResource.getCreatorUserId();
4520 if ((updatedCreatorUserId != null) && (!updatedCreatorUserId.equals(currentCreatorUserId))) {
4521 log.debug("Resource Creator UserId is automatically set and cannot be updated");
4523 String currentCreatorFullName = currentResource.getCreatorFullName();
4524 String updatedCreatorFullName = updateInfoResource.getCreatorFullName();
4525 if ((updatedCreatorFullName != null) && (!updatedCreatorFullName.equals(currentCreatorFullName))) {
4526 log.debug("Resource Creator fullname is automatically set and cannot be updated");
4528 String currentLastUpdaterUserId = currentResource.getLastUpdaterUserId();
4529 String updatedLastUpdaterUserId = updateInfoResource.getLastUpdaterUserId();
4530 if ((updatedLastUpdaterUserId != null) && (!updatedLastUpdaterUserId.equals(currentLastUpdaterUserId))) {
4531 log.debug("Resource LastUpdater userId is automatically set and cannot be updated");
4533 String currentLastUpdaterFullName = currentResource.getLastUpdaterFullName();
4534 String updatedLastUpdaterFullName = updateInfoResource.getLastUpdaterFullName();
4535 if ((updatedLastUpdaterFullName != null) && (!updatedLastUpdaterFullName.equals(currentLastUpdaterFullName))) {
4536 log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4538 Long currentCreationDate = currentResource.getCreationDate();
4539 Long updatedCreationDate = updateInfoResource.getCreationDate();
4540 if ((updatedCreationDate != null) && (!updatedCreationDate.equals(currentCreationDate))) {
4541 log.debug("Resource Creation date is automatically set and cannot be updated");
4543 Long currentLastUpdateDate = currentResource.getLastUpdateDate();
4544 Long updatedLastUpdateDate = updateInfoResource.getLastUpdateDate();
4545 if ((updatedLastUpdateDate != null) && (!updatedLastUpdateDate.equals(currentLastUpdateDate))) {
4546 log.debug("Resource last update date is automatically set and cannot be updated");
4548 LifecycleStateEnum currentLifecycleState = currentResource.getLifecycleState();
4549 LifecycleStateEnum updatedLifecycleState = updateInfoResource.getLifecycleState();
4550 if ((updatedLifecycleState != null) && (!updatedLifecycleState.equals(currentLifecycleState))) {
4551 log.debug("Resource lifecycle state date is automatically set and cannot be updated");
4553 Boolean currentAbstract = currentResource.isAbstract();
4554 Boolean updatedAbstract = updateInfoResource.isAbstract();
4555 if ((updatedAbstract != null) && (!updatedAbstract.equals(currentAbstract))) {
4556 log.debug("Resource abstract is automatically set and cannot be updated");
4558 Boolean currentHighestVersion = currentResource.isHighestVersion();
4559 Boolean updatedHighestVersion = updateInfoResource.isHighestVersion();
4560 if ((updatedHighestVersion != null) && (!updatedHighestVersion.equals(currentHighestVersion))) {
4561 log.debug("Resource highest version is automatically set and cannot be updated");
4563 String currentUuid = currentResource.getUUID();
4564 String updatedUuid = updateInfoResource.getUUID();
4565 if ((updatedUuid != null) && (!updatedUuid.equals(currentUuid))) {
4566 log.debug("Resource UUID is automatically set and cannot be updated");
4568 log.debug("Resource Type cannot be updated");
4569 String currentInvariantUuid = currentResource.getInvariantUUID();
4570 String updatedInvariantUuid = updateInfoResource.getInvariantUUID();
4571 if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
4572 log.debug("Resource invariant UUID is automatically set and cannot be updated");
4573 updateInfoResource.setInvariantUUID(currentInvariantUuid);
4577 private void validateFields(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4578 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentResource.getVersion());
4579 log.debug("validate resource name before update");
4580 validateResourceName(currentResource, updateInfoResource, hasBeenCertified, isNested);
4581 log.debug("validate description before update");
4582 componentDescriptionValidator.validateAndCorrectField(null, updateInfoResource, null);
4583 log.debug("validate icon before update");
4584 validateIcon(currentResource, updateInfoResource, hasBeenCertified);
4585 log.debug("validate tags before update");
4586 componentTagsValidator.validateAndCorrectField(null, updateInfoResource, null);
4587 log.debug("validate vendor name before update");
4588 validateVendorName(null, updateInfoResource, null);
4589 log.debug("validate resource vendor model number before update");
4590 validateResourceVendorModelNumber(currentResource, updateInfoResource);
4591 log.debug("validate vendor release before update");
4592 validateVendorReleaseName(null, updateInfoResource, null);
4593 log.debug("validate contact info before update");
4594 componentContactIdValidator.validateAndCorrectField(null, updateInfoResource, null);
4595 log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
4596 validateDerivedFromDuringUpdate(currentResource, updateInfoResource, hasBeenCertified);
4597 log.debug("validate category before update");
4598 validateCategory(currentResource, updateInfoResource, hasBeenCertified, inTransaction);
4601 private boolean isResourceNameEquals(Resource currentResource, Resource updateInfoResource) {
4602 String resourceNameUpdated = updateInfoResource.getName();
4603 String resourceNameCurrent = currentResource.getName();
4604 if (resourceNameCurrent.equals(resourceNameUpdated)) {
4607 // In case of CVFC type we should support the case of old VF with CVFC
4609 // instances that were created without the "Cvfc" suffix
4610 return currentResource.getResourceType() == ResourceTypeEnum.CVFC && resourceNameUpdated
4611 .equals(addCvfcSuffixToResourceName(resourceNameCurrent));
4614 private String addCvfcSuffixToResourceName(String resourceName) {
4615 return resourceName + "Cvfc";
4618 private void validateResourceName(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified, boolean isNested) {
4619 String resourceNameUpdated = updateInfoResource.getName();
4620 if (!isResourceNameEquals(currentResource, updateInfoResource)) {
4621 if (isNested || !hasBeenCertified) {
4622 componentNameValidator.validateAndCorrectField(null, updateInfoResource, null);
4623 validateResourceNameUniqueness(updateInfoResource);
4624 currentResource.setName(resourceNameUpdated);
4625 currentResource.setNormalizedName(ValidationUtils.normaliseComponentName(resourceNameUpdated));
4626 currentResource.setSystemName(ValidationUtils.convertToSystemName(resourceNameUpdated));
4628 log.info("Resource name: {}, cannot be updated once the resource has been certified once.", resourceNameUpdated);
4629 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NAME_CANNOT_BE_CHANGED);
4634 private void validateIcon(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) {
4635 String iconUpdated = updateInfoResource.getIcon();
4636 String iconCurrent = currentResource.getIcon();
4637 if (!iconCurrent.equals(iconUpdated)) {
4638 if (!hasBeenCertified) {
4639 componentIconValidator.validateAndCorrectField(null, updateInfoResource, null);
4641 log.info("Icon {} cannot be updated once the resource has been certified once.", iconUpdated);
4642 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_ICON_CANNOT_BE_CHANGED);
4647 private void validateResourceVendorModelNumber(Resource currentResource, Resource updateInfoResource) {
4648 String updatedResourceVendorModelNumber = updateInfoResource.getResourceVendorModelNumber();
4649 String currentResourceVendorModelNumber = currentResource.getResourceVendorModelNumber();
4650 if (!currentResourceVendorModelNumber.equals(updatedResourceVendorModelNumber)) {
4651 validateResourceVendorModelNumber(null, updateInfoResource, null);
4655 private Either<Boolean, ResponseFormat> validateCategory(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified,
4656 boolean inTransaction) {
4657 validateCategory(null, updateInfoResource, null, inTransaction);
4658 if (hasBeenCertified) {
4659 CategoryDefinition currentCategory = currentResource.getCategories().get(0);
4660 SubCategoryDefinition currentSubCategory = currentCategory.getSubcategories().get(0);
4661 CategoryDefinition updateCategory = updateInfoResource.getCategories().get(0);
4662 SubCategoryDefinition updtaeSubCategory = updateCategory.getSubcategories().get(0);
4663 if (!currentCategory.getName().equals(updateCategory.getName()) || !currentSubCategory.getName().equals(updtaeSubCategory.getName())) {
4664 log.info("Category {} cannot be updated once the resource has been certified once.", currentResource.getCategories());
4665 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CATEGORY_CANNOT_BE_CHANGED);
4666 return Either.right(errorResponse);
4669 return Either.left(true);
4672 private Either<Boolean, ResponseFormat> validateDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4673 boolean hasBeenCertified) {
4674 List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4675 List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4676 if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4677 log.trace("Update normative types");
4678 return Either.left(true);
4680 String derivedFromCurrent = currentDerivedFrom.get(0);
4681 String derivedFromUpdated = updatedDerivedFrom.get(0);
4682 if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4683 if (!hasBeenCertified) {
4684 validateDerivedFromExist(null, updateInfoResource, null);
4686 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4688 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4689 log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4690 return validateDerivedFromExtending;
4694 // For derived from, we must know whether it was actually changed,
4696 // otherwise we must do no action.
4698 // Due to changes it inflicts on data model (remove artifacts,
4700 // properties...), it's not like a flat field which can be
4702 // overwritten if not changed.
4704 // So we must indicate that derived from is not changed
4705 updateInfoResource.setDerivedFrom(null);
4707 return Either.left(true);
4710 private Either<Boolean, ResponseFormat> validateNestedDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4711 boolean hasBeenCertified) {
4712 List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4713 List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4714 if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4715 log.trace("Update normative types");
4716 return Either.left(true);
4718 String derivedFromCurrent = currentDerivedFrom.get(0);
4719 String derivedFromUpdated = updatedDerivedFrom.get(0);
4720 if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4721 if (!hasBeenCertified) {
4722 validateDerivedFromExist(null, updateInfoResource, null);
4724 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4726 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4727 log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4728 return validateDerivedFromExtending;
4732 return Either.left(true);
4735 private void validateDerivedFromExist(User user, Resource resource, AuditingActionEnum actionEnum) {
4736 if (resource.getDerivedFrom() == null || resource.getDerivedFrom().isEmpty()) {
4739 String templateName = resource.getDerivedFrom().get(0);
4740 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateToscaResourceNameExists(templateName);
4741 if (dataModelResponse.isRight()) {
4742 StorageOperationStatus storageStatus = dataModelResponse.right().value();
4743 BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateDerivedFromExist");
4744 log.debug("request to data model failed with error: {}", storageStatus);
4745 ResponseFormat responseFormat = componentsUtils
4746 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), resource);
4747 log.trace("audit before sending response");
4748 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4749 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageStatus));
4750 } else if (!dataModelResponse.left().value()) {
4751 log.info("resource template with name: {}, does not exists", templateName);
4752 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4753 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4754 throw new ByActionStatusComponentException(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4758 // Tal G for extending inheritance US815447
4759 private Either<Boolean, ResponseFormat> validateDerivedFromExtending(User user, Resource currentResource, Resource updateInfoResource,
4760 AuditingActionEnum actionEnum) {
4761 String currentTemplateName = currentResource.getDerivedFrom().get(0);
4762 String updatedTemplateName = updateInfoResource.getDerivedFrom().get(0);
4763 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
4764 .validateToscaResourceNameExtends(currentTemplateName, updatedTemplateName, currentResource.getModel());
4765 if (dataModelResponse.isRight()) {
4766 StorageOperationStatus storageStatus = dataModelResponse.right().value();
4767 BeEcompErrorManager.getInstance().logBeDaoSystemError("Create/Update Resource - validateDerivingFromExtendingType");
4768 ResponseFormat responseFormat = componentsUtils
4769 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), currentResource);
4770 log.trace("audit before sending response");
4771 componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4772 return Either.right(responseFormat);
4774 if (!dataModelResponse.left().value()) {
4775 log.info("resource template with name {} does not inherit as original {}", updatedTemplateName, currentTemplateName);
4776 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_DOES_NOT_EXTEND);
4777 componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4778 return Either.right(responseFormat);
4780 return Either.left(true);
4783 public void validateDerivedFromNotEmpty(User user, Resource resource, AuditingActionEnum actionEnum) {
4784 log.debug("validate resource derivedFrom field");
4785 if ((resource.getDerivedFrom() == null) || (resource.getDerivedFrom().isEmpty()) || (resource.getDerivedFrom().get(0)) == null || (resource
4786 .getDerivedFrom().get(0).trim().isEmpty())) {
4787 log.info("derived from (template) field is missing for the resource");
4788 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4789 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4790 throw new ByActionStatusComponentException(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4794 private void validateResourceNameUniqueness(Resource resource) {
4795 Either<Boolean, StorageOperationStatus> resourceOperationResponse = toscaOperationFacade
4796 .validateComponentNameExists(resource.getName(), resource.getResourceType(), resource.getComponentType());
4797 if (resourceOperationResponse.isLeft() && resourceOperationResponse.left().value()) {
4798 log.debug("resource with name: {}, already exists", resource.getName());
4799 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4800 resource.getName());
4801 } else if (resourceOperationResponse.isRight()) {
4802 log.debug("error while validateResourceNameExists for resource: {}", resource.getName());
4803 throw new StorageException(resourceOperationResponse.right().value());
4807 private void validateCategory(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4808 List<CategoryDefinition> categories = resource.getCategories();
4809 if (CollectionUtils.isEmpty(categories)) {
4810 log.debug(CATEGORY_IS_EMPTY);
4811 ResponseFormat responseFormat = componentsUtils
4812 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4813 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4814 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4816 if (categories.size() > 1) {
4817 log.debug("Must be only one category for resource");
4818 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.RESOURCE.getValue());
4820 CategoryDefinition category = categories.get(0);
4821 List<SubCategoryDefinition> subcategories = category.getSubcategories();
4822 if (CollectionUtils.isEmpty(subcategories)) {
4823 log.debug("Missinig subcategory for resource");
4824 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY);
4826 if (subcategories.size() > 1) {
4827 log.debug("Must be only one sub category for resource");
4828 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_TOO_MUCH_SUBCATEGORIES);
4830 SubCategoryDefinition subcategory = subcategories.get(0);
4831 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
4832 log.debug(CATEGORY_IS_EMPTY);
4833 ResponseFormat responseFormat = componentsUtils
4834 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4835 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4836 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4838 if (!ValidationUtils.validateStringNotEmpty(subcategory.getName())) {
4839 log.debug(CATEGORY_IS_EMPTY);
4840 ResponseFormat responseFormat = componentsUtils
4841 .getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4842 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4843 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4845 validateCategoryListed(category, subcategory, user, resource, actionEnum, inTransaction);
4848 private void validateCategoryListed(CategoryDefinition category, SubCategoryDefinition subcategory, User user, Resource resource,
4849 AuditingActionEnum actionEnum, boolean inTransaction) {
4850 ResponseFormat responseFormat;
4851 if (category != null && subcategory != null) {
4852 log.debug("validating resource category {} against valid categories list", category);
4853 Either<List<CategoryDefinition>, ActionStatus> categories = elementDao.getAllCategories(NodeTypeEnum.ResourceNewCategory, inTransaction);
4854 if (categories.isRight()) {
4855 log.debug("failed to retrieve resource categories from JanusGraph");
4856 responseFormat = componentsUtils.getResponseFormat(categories.right().value());
4857 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4858 throw new ByActionStatusComponentException(categories.right().value());
4860 List<CategoryDefinition> categoryList = categories.left().value();
4861 Optional<CategoryDefinition> foundCategory = categoryList.stream().filter(cat -> cat.getName().equals(category.getName())).findFirst();
4862 if (foundCategory.isEmpty()) {
4863 log.debug("Category {} is not part of resource category group. Resource category valid values are {}", category, categoryList);
4864 failOnInvalidCategory(user, resource, actionEnum);
4865 return; // explisite output even if failOnInvalidCategory throw an exception
4867 Optional<SubCategoryDefinition> foundSubcategory = foundCategory.get().getSubcategories().stream()
4868 .filter(subcat -> subcat.getName().equals(subcategory.getName())).findFirst();
4869 if (foundSubcategory.isEmpty()) {
4870 log.debug("SubCategory {} is not part of resource category group. Resource subcategory valid values are {}", subcategory,
4871 foundCategory.get().getSubcategories());
4872 failOnInvalidCategory(user, resource, actionEnum);
4877 private void failOnInvalidCategory(User user, Resource resource, AuditingActionEnum actionEnum) {
4878 ResponseFormat responseFormat;
4879 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4880 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4881 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4884 public void validateVendorReleaseName(User user, Resource resource, AuditingActionEnum actionEnum) {
4885 String vendorRelease = resource.getVendorRelease();
4886 log.debug("validate vendor relese name");
4887 if (!ValidationUtils.validateStringNotEmpty(vendorRelease)) {
4888 log.info("vendor relese name is missing.");
4889 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_RELEASE);
4890 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4891 throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_RELEASE);
4893 validateVendorReleaseName(vendorRelease, user, resource, actionEnum);
4896 public void validateVendorReleaseName(String vendorRelease, User user, Resource resource, AuditingActionEnum actionEnum) {
4897 if (vendorRelease != null) {
4898 if (!ValidationUtils.validateVendorReleaseLength(vendorRelease)) {
4899 log.info("vendor release exceds limit.");
4900 ResponseFormat errorResponse = componentsUtils
4901 .getResponseFormat(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4902 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4903 throw new ByActionStatusComponentException(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4905 if (!ValidationUtils.validateVendorRelease(vendorRelease)) {
4906 log.info("vendor release is not valid.");
4907 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_RELEASE);
4908 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4909 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_RELEASE, vendorRelease);
4914 private void validateVendorName(User user, Resource resource, AuditingActionEnum actionEnum) {
4915 String vendorName = resource.getVendorName();
4916 if (!ValidationUtils.validateStringNotEmpty(vendorName)) {
4917 log.info("vendor name is missing.");
4918 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_NAME);
4919 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4920 throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_NAME);
4922 validateVendorName(vendorName, user, resource, actionEnum);
4925 private void validateVendorName(String vendorName, User user, Resource resource, AuditingActionEnum actionEnum) {
4926 if (vendorName != null) {
4927 if (!ValidationUtils.validateVendorNameLength(vendorName)) {
4928 log.info("vendor name exceds limit.");
4929 ResponseFormat errorResponse = componentsUtils
4930 .getResponseFormat(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4931 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4932 throw new ByActionStatusComponentException(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4934 if (!ValidationUtils.validateVendorName(vendorName)) {
4935 log.info("vendor name is not valid.");
4936 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_NAME);
4937 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4938 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_NAME, vendorName);
4943 private void validateResourceVendorModelNumber(User user, Resource resource, AuditingActionEnum actionEnum) {
4944 String resourceVendorModelNumber = resource.getResourceVendorModelNumber();
4945 if (StringUtils.isNotEmpty(resourceVendorModelNumber)) {
4946 if (!ValidationUtils.validateResourceVendorModelNumberLength(resourceVendorModelNumber)) {
4947 log.info("resource vendor model number exceeds limit.");
4948 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4949 "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4950 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4951 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4952 "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4954 // resource vendor model number is currently validated as vendor
4957 if (!ValidationUtils.validateVendorName(resourceVendorModelNumber)) {
4958 log.info("resource vendor model number is not valid.");
4959 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4960 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4961 throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4966 private void validateCost(Resource resource) {
4967 String cost = resource.getCost();
4969 if (!ValidationUtils.validateCost(cost)) {
4970 log.debug("resource cost is invalid.");
4971 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4976 private void validateLicenseType(User user, Resource resource, AuditingActionEnum actionEnum) {
4977 log.debug("validate licenseType");
4978 String licenseType = resource.getLicenseType();
4979 if (licenseType != null) {
4980 List<String> licenseTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getLicenseTypes();
4981 if (!licenseTypes.contains(licenseType)) {
4982 log.debug("License type {} isn't configured", licenseType);
4983 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
4984 if (actionEnum != null) {
4985 // In update case, no audit is required
4986 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4988 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4993 private Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom(Resource currentResource, Resource updatedResource, String userId,
4994 boolean inTransaction) {
4995 if (updatedResource.getDerivedFrom() != null) {
4996 log.debug("Starting derived from update for resource {}", updatedResource.getUniqueId());
4997 log.debug("1. Removing interface artifacts from graph");
4998 // Remove all interface artifacts of resource
4999 String resourceId = updatedResource.getUniqueId();
5000 Map<String, InterfaceDefinition> interfaces = currentResource.getInterfaces();
5001 if (interfaces != null) {
5002 Collection<InterfaceDefinition> values = interfaces.values();
5003 for (InterfaceDefinition interfaceDefinition : values) {
5004 String interfaceType = interfaceTypeOperation.getShortInterfaceName(interfaceDefinition);
5005 log.trace("Starting interface artifacts removal for interface type {}", interfaceType);
5006 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
5007 if (operations != null) {
5008 for (Entry<String, Operation> operationEntry : operations.entrySet()) {
5009 Operation operation = operationEntry.getValue();
5010 ArtifactDefinition implementation = operation.getImplementationArtifact();
5011 if (implementation != null) {
5012 String uniqueId = implementation.getUniqueId();
5013 log.debug("Removing interface artifact definition {}, operation {}, interfaceType {}", uniqueId,
5014 operationEntry.getKey(), interfaceType);
5015 // only thing that transacts and locks here
5016 Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface = artifactsBusinessLogic
5017 .deleteArtifactByInterface(resourceId, userId, uniqueId, true);
5018 if (deleteArtifactByInterface.isRight()) {
5019 log.debug("Couldn't remove artifact definition with id {}", uniqueId);
5020 if (!inTransaction) {
5021 janusGraphDao.rollback();
5023 return Either.right(deleteArtifactByInterface.right().value());
5026 log.trace("No implementation found for operation {} - nothing to delete", operationEntry.getKey());
5030 log.trace("No operations found for interface type {}", interfaceType);
5034 log.debug("2. Removing properties");
5035 Either<Map<String, PropertyDefinition>, StorageOperationStatus> findPropertiesOfNode = propertyOperation
5036 .deleteAllPropertiesAssociatedToNode(NodeTypeEnum.Resource, resourceId);
5037 if (findPropertiesOfNode.isRight() && findPropertiesOfNode.right().value() != StorageOperationStatus.OK) {
5038 log.debug("Failed to remove all properties of resource");
5039 if (!inTransaction) {
5040 janusGraphDao.rollback();
5043 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findPropertiesOfNode.right().value())));
5046 log.debug("Derived from wasn't changed during update");
5048 if (inTransaction) {
5049 return Either.left(true);
5051 janusGraphDao.commit();
5052 return Either.left(true);
5055 public ICapabilityTypeOperation getCapabilityTypeOperation() {
5056 return capabilityTypeOperation;
5060 public void setCapabilityTypeOperation(ICapabilityTypeOperation capabilityTypeOperation) {
5061 this.capabilityTypeOperation = capabilityTypeOperation;
5064 public Boolean validatePropertiesDefaultValues(Resource resource) {
5065 log.debug("validate resource properties default values");
5066 List<PropertyDefinition> properties = resource.getProperties();
5067 if (properties != null) {
5068 iterateOverProperties(properties, resource.getModel());
5073 public void iterateOverProperties(List<PropertyDefinition> properties, String model) {
5075 String innerType = null;
5076 for (PropertyDefinition property : properties) {
5077 if (!propertyOperation.isPropertyTypeValid(property, model)) {
5078 log.info("Invalid type for property {}", property);
5079 throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
5081 Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
5082 type = property.getType();
5083 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5084 ResponseFormat responseFormat = validateMapOrListPropertyType(property, innerType, allDataTypes);
5085 if (responseFormat != null) {
5089 validateDefaultPropertyValue(property, allDataTypes, type, innerType);
5093 private void validateDefaultPropertyValue(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes, String type,
5095 if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes)) {
5096 log.info("Invalid default value for property {}", property);
5097 ResponseFormat responseFormat;
5098 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5099 throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
5100 property.getDefaultValue());
5102 throw new ByActionStatusComponentException(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
5106 private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property, String innerType,
5107 Map<String, DataTypeDefinition> allDataTypes) {
5108 ResponseFormat responseFormat = null;
5109 ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, allDataTypes);
5110 innerType = propertyInnerTypeValid.getLeft();
5111 if (!propertyInnerTypeValid.getRight()) {
5112 log.info("Invalid inner type for property {}", property);
5113 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
5115 return responseFormat;
5119 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
5120 return deleteMarkedComponents(ComponentTypeEnum.RESOURCE);
5124 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
5125 return componentInstanceBusinessLogic;
5128 private String getComponentTypeForResponse(Component component) {
5129 String componentTypeForResponse = "SERVICE";
5130 if (component instanceof Resource) {
5131 componentTypeForResponse = ((Resource) component).getResourceType().name();
5133 return componentTypeForResponse;
5136 public Either<Resource, ResponseFormat> getLatestResourceFromCsarUuid(String csarUuid, User user) {
5139 validateUserExists(user);
5141 // get resource from csar uuid
5142 Either<Resource, StorageOperationStatus> either = toscaOperationFacade
5143 .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUuid, "");
5144 if (either.isRight()) {
5145 ResponseFormat resp = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUuid);
5146 return Either.right(resp);
5148 return Either.left(either.left().value());
5152 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
5156 private Map<String, List<CapabilityDefinition>> getValidComponentInstanceCapabilities(String resourceId,
5157 Map<String, List<CapabilityDefinition>> defaultCapabilities,
5158 Map<String, List<UploadCapInfo>> uploadedCapabilities) {
5159 Map<String, List<CapabilityDefinition>> validCapabilitiesMap = new HashMap<>();
5160 uploadedCapabilities.forEach((k, v) -> addValidComponentInstanceCapabilities(k, v, resourceId, defaultCapabilities, validCapabilitiesMap));
5161 return validCapabilitiesMap;
5164 private void addValidComponentInstanceCapabilities(String key, List<UploadCapInfo> capabilities, String resourceId,
5165 Map<String, List<CapabilityDefinition>> defaultCapabilities,
5166 Map<String, List<CapabilityDefinition>> validCapabilitiesMap) {
5167 String capabilityType = capabilities.get(0).getType();
5168 if (defaultCapabilities.containsKey(capabilityType)) {
5169 CapabilityDefinition defaultCapability = getCapability(resourceId, defaultCapabilities, capabilityType);
5170 validateCapabilityProperties(capabilities, resourceId, defaultCapability);
5171 List<CapabilityDefinition> validCapabilityList = new ArrayList<>();
5172 validCapabilityList.add(defaultCapability);
5173 validCapabilitiesMap.put(key, validCapabilityList);
5175 throw new ByActionStatusComponentException(ActionStatus.MISSING_CAPABILITY_TYPE, capabilityType);
5179 private void validateCapabilityProperties(List<UploadCapInfo> capabilities, String resourceId, CapabilityDefinition defaultCapability) {
5180 if (CollectionUtils.isEmpty(defaultCapability.getProperties()) && isNotEmpty(capabilities.get(0).getProperties())) {
5181 log.debug("Failed to validate capability {} of component {}. Property list is empty. ", defaultCapability.getName(), resourceId);
5182 log.debug("Failed to update capability property values. Property list of fetched capability {} is empty. ", defaultCapability.getName());
5183 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, resourceId);
5184 } else if (isNotEmpty(capabilities.get(0).getProperties())) {
5185 validateUniquenessUpdateUploadedComponentInstanceCapability(defaultCapability, capabilities.get(0));
5189 private CapabilityDefinition getCapability(String resourceId, Map<String, List<CapabilityDefinition>> defaultCapabilities,
5190 String capabilityType) {
5191 CapabilityDefinition defaultCapability;
5192 if (isNotEmpty(defaultCapabilities.get(capabilityType).get(0).getProperties())) {
5193 defaultCapability = defaultCapabilities.get(capabilityType).get(0);
5195 Either<Component, StorageOperationStatus> getFullComponentRes = toscaOperationFacade.getToscaFullElement(resourceId);
5196 if (getFullComponentRes.isRight()) {
5197 log.debug("Failed to get full component {}. Status is {}. ", resourceId, getFullComponentRes.right().value());
5198 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, resourceId);
5200 defaultCapability = getFullComponentRes.left().value().getCapabilities().get(capabilityType).get(0);
5202 return defaultCapability;
5205 private void validateUniquenessUpdateUploadedComponentInstanceCapability(CapabilityDefinition defaultCapability,
5206 UploadCapInfo uploadedCapability) {
5207 List<ComponentInstanceProperty> validProperties = new ArrayList<>();
5208 Map<String, PropertyDefinition> defaultProperties = defaultCapability.getProperties().stream()
5209 .collect(toMap(PropertyDefinition::getName, Function.identity()));
5210 List<UploadPropInfo> uploadedProperties = uploadedCapability.getProperties();
5211 for (UploadPropInfo property : uploadedProperties) {
5212 String propertyName = property.getName().toLowerCase();
5213 String propertyType = property.getType();
5214 ComponentInstanceProperty validProperty;
5215 if (defaultProperties.containsKey(propertyName) && propertTypeEqualsTo(defaultProperties, propertyName, propertyType)) {
5216 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, propertyName);
5218 validProperty = new ComponentInstanceProperty();
5219 validProperty.setName(propertyName);
5220 if (property.getValue() != null) {
5221 validProperty.setValue(property.getValue().toString());
5223 validProperty.setDescription(property.getDescription());
5224 validProperty.setPassword(property.isPassword());
5225 validProperties.add(validProperty);
5227 defaultCapability.setProperties(validProperties);
5230 private boolean propertTypeEqualsTo(Map<String, PropertyDefinition> defaultProperties, String propertyName, String propertyType) {
5231 return propertyType != null && !defaultProperties.get(propertyName).getType().equals(propertyType);
5234 private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> organizeVfCsarArtifactsByArtifactOperation(
5235 List<NonMetaArtifactInfo> artifactPathAndNameList, List<ArtifactDefinition> existingArtifactsToHandle, Resource resource, User user) {
5236 EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
5237 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
5238 Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> nodeTypeArtifactsToHandleRes = Either
5239 .left(nodeTypeArtifactsToHandle);
5241 // add all found Csar artifacts to list to upload
5242 List<NonMetaArtifactInfo> artifactsToUpload = new ArrayList<>(artifactPathAndNameList);
5243 List<NonMetaArtifactInfo> artifactsToUpdate = new ArrayList<>();
5244 List<NonMetaArtifactInfo> artifactsToDelete = new ArrayList<>();
5245 for (NonMetaArtifactInfo currNewArtifact : artifactPathAndNameList) {
5246 ArtifactDefinition foundArtifact;
5247 if (!existingArtifactsToHandle.isEmpty()) {
5248 foundArtifact = existingArtifactsToHandle.stream().filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName()))
5249 .findFirst().orElse(null);
5250 if (foundArtifact != null) {
5251 if (foundArtifact.getArtifactType().equals(currNewArtifact.getArtifactType())) {
5252 if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
5253 currNewArtifact.setArtifactUniqueId(foundArtifact.getUniqueId());
5254 // if current artifact already exists, but has
5256 // different content, add him to the list to
5259 artifactsToUpdate.add(currNewArtifact);
5261 // remove found artifact from the list of existing
5263 // artifacts to handle, because it was already
5266 existingArtifactsToHandle.remove(foundArtifact);
5267 // and remove found artifact from the list to
5269 // upload, because it should either be updated or be
5272 artifactsToUpload.remove(currNewArtifact);
5274 log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
5275 ResponseFormat responseFormat = ResponseFormatManager.getInstance()
5276 .getResponseFormat(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, currNewArtifact.getArtifactName(),
5277 currNewArtifact.getArtifactType(), foundArtifact.getArtifactType());
5278 AuditingActionEnum auditingAction = artifactsBusinessLogic
5279 .detectAuditingType(new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE),
5280 foundArtifact.getArtifactChecksum());
5281 artifactsBusinessLogic
5282 .handleAuditing(auditingAction, resource, resource.getUniqueId(), user, null, null, foundArtifact.getUniqueId(),
5283 responseFormat, resource.getComponentType(), null);
5284 responseWrapper.setInnerElement(responseFormat);
5290 if (responseWrapper.isEmpty()) {
5291 for (ArtifactDefinition currArtifact : existingArtifactsToHandle) {
5292 if (currArtifact.getIsFromCsar()) {
5293 artifactsToDelete.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5294 currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5296 artifactsToUpdate.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5297 currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5301 if (responseWrapper.isEmpty()) {
5302 if (!artifactsToUpload.isEmpty()) {
5303 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
5305 if (!artifactsToUpdate.isEmpty()) {
5306 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
5308 if (!artifactsToDelete.isEmpty()) {
5309 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
5312 if (!responseWrapper.isEmpty()) {
5313 nodeTypeArtifactsToHandleRes = Either.right(responseWrapper.getInnerElement());
5315 } catch (Exception e) {
5316 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
5317 responseWrapper.setInnerElement(responseFormat);
5318 log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
5320 return nodeTypeArtifactsToHandleRes;
5323 ImmutablePair<String, String> buildNestedToscaResourceName(final String nodeResourceType, final String vfResourceName,
5324 final String nodeTypeFullName) {
5326 String actualVfName;
5327 if (ResourceTypeEnum.CVFC.name().equals(nodeResourceType)) {
5328 actualVfName = vfResourceName + ResourceTypeEnum.CVFC.name();
5329 actualType = ResourceTypeEnum.VFC.name();
5331 actualVfName = vfResourceName;
5332 actualType = nodeResourceType;
5334 String nameWithouNamespacePrefix;
5336 final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
5337 log.debug("####### buildNestedToscaResourceName nodeResourceType {}, vfResourceName {}, "
5338 + "nodeTypeFullName {}, actualType {}, vfResourceName {} ", nodeResourceType, vfResourceName, nodeTypeFullName, actualType,
5340 final StringBuilder toscaResourceName = new StringBuilder(nodeTypeNamePrefix);
5341 if (!nodeTypeFullName.contains(nodeTypeNamePrefix)) {
5342 nameWithouNamespacePrefix = nodeTypeFullName;
5344 nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.length());
5346 final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
5348 if (nodeResourceType.equalsIgnoreCase(findTypes[0])) {
5349 actualName = nameWithouNamespacePrefix.substring(nodeResourceType.length());
5351 actualName = "." + nameWithouNamespacePrefix;
5353 if (actualName.startsWith(Constants.ABSTRACT)) {
5354 toscaResourceName.append(nodeResourceType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName));
5356 toscaResourceName.append(actualType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName)).append('.')
5357 .append(Constants.ABSTRACT);
5359 final StringBuilder previousToscaResourceName = new StringBuilder(toscaResourceName);
5360 final String[] actualNames = actualName.split("\\.");
5361 if (actualNames.length < 3) {
5362 return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5363 previousToscaResourceName.append(actualName).toString());
5365 return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5366 previousToscaResourceName.append(actualName.substring(actualNames[1].length() + 1).toLowerCase()).toString());
5367 } catch (final Exception e) {
5368 log.debug("Exception occured when buildNestedToscaResourceName, error is:{}", e.getMessage(), e);
5369 throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE, vfResourceName);
5374 * Extracts a Node Type Name prefix from the given Node Type Name.
5376 * @param fullName Node Type Name
5377 * @return Node Type Name Prefix
5379 private String getNodeTypeNamePrefix(final String fullName) {
5380 String tempPrefix = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX;
5381 final List<String> definedNodeTypeNamespaceList = getDefinedNodeTypeNamespaceList();
5382 log.debug("************* getPrefiX fullName {} FROM {}", fullName, definedNodeTypeNamespaceList);
5383 final Optional<String> validNameSpace = validateNodeTypeNamePrefix(fullName, definedNodeTypeNamespaceList);
5384 if (validNameSpace.isPresent()) {
5385 tempPrefix = validNameSpace.get();
5387 log.debug("************* getNodeTypeNamePrefix return fullName {} ", tempPrefix);
5392 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId,
5393 List<String> dataParamsToReturn) {
5394 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
5395 Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, paramsToReturn);
5396 if (resourceResultEither.isRight()) {
5397 if (resourceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
5398 log.debug("Failed to found resource with id {} ", resourceId);
5399 Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
5401 log.debug("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn);
5402 return Either.right(
5403 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceResultEither.right().value()), ""));
5405 Resource resource = resourceResultEither.left().value();
5406 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
5407 ListUtils.emptyIfNull(resource.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
5409 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromResourceByParams(resource, dataParamsToReturn);
5410 return Either.left(dataTransfer);
5414 public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
5415 Resource resource = (Resource) clonedComponent;
5416 if (ModelConverter.isAtomicComponent(resource.getResourceType())) {
5417 Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived = toscaOperationFacade.shouldUpgradeToLatestDerived(resource);
5418 if (shouldUpgradeToLatestDerived.isRight()) {
5419 return Either.right(componentsUtils.convertFromStorageResponse(shouldUpgradeToLatestDerived.right().value()));
5421 return Either.left(shouldUpgradeToLatestDerived.left().value());
5423 return super.shouldUpgradeToLatestDerived(clonedComponent);