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 org.apache.commons.collections.CollectionUtils.isNotEmpty;
25 import static org.apache.commons.collections.MapUtils.isEmpty;
26 import static org.apache.commons.collections.MapUtils.isNotEmpty;
27 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement;
28 import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue;
29 import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN;
30 import static org.openecomp.sdc.common.api.Constants.DEFAULT_GROUP_VF_MODULE;
32 import com.google.common.annotations.VisibleForTesting;
33 import fj.data.Either;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.EnumMap;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.ListIterator;
44 import java.util.Map.Entry;
45 import java.util.Objects;
46 import java.util.Optional;
48 import java.util.function.Function;
49 import java.util.regex.Pattern;
50 import java.util.stream.Collectors;
51 import org.apache.commons.codec.binary.Base64;
52 import org.apache.commons.collections.CollectionUtils;
53 import org.apache.commons.collections.MapUtils;
54 import org.apache.commons.collections4.ListUtils;
55 import org.apache.commons.lang3.StringUtils;
56 import org.apache.commons.lang3.tuple.ImmutablePair;
57 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
58 import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic;
59 import org.openecomp.sdc.be.components.csar.CsarBusinessLogic;
60 import org.openecomp.sdc.be.components.csar.CsarInfo;
61 import org.openecomp.sdc.be.components.csar.OnboardedCsarInfo;
62 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
63 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
64 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
65 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
66 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
67 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
68 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
69 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
70 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
71 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
72 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
73 import org.openecomp.sdc.be.components.merge.TopologyComparator;
74 import org.openecomp.sdc.be.components.merge.property.PropertyDataValueMergeBusinessLogic;
75 import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic;
76 import org.openecomp.sdc.be.components.property.PropertyConstraintsUtils;
77 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
78 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
79 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
80 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
81 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
82 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
83 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
84 import org.openecomp.sdc.be.config.BeEcompErrorManager;
85 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
86 import org.openecomp.sdc.be.config.ConfigurationManager;
87 import org.openecomp.sdc.be.dao.api.ActionStatus;
88 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
89 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
90 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
91 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
92 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
93 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
94 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
95 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
96 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
97 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
98 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
99 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
100 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
101 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
102 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
103 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
104 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
105 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
106 import org.openecomp.sdc.be.impl.ComponentsUtils;
107 import org.openecomp.sdc.be.info.NodeTypeInfoToUpdateArtifacts;
108 import org.openecomp.sdc.be.model.ArtifactDefinition;
109 import org.openecomp.sdc.be.model.AttributeDefinition;
110 import org.openecomp.sdc.be.model.CapabilityDefinition;
111 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
112 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
113 import org.openecomp.sdc.be.model.Component;
114 import org.openecomp.sdc.be.model.ComponentInstance;
115 import org.openecomp.sdc.be.model.ComponentInstanceInput;
116 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
117 import org.openecomp.sdc.be.model.ComponentParametersView;
118 import org.openecomp.sdc.be.model.DataTypeDefinition;
119 import org.openecomp.sdc.be.model.GroupDefinition;
120 import org.openecomp.sdc.be.model.GroupProperty;
121 import org.openecomp.sdc.be.model.InputDefinition;
122 import org.openecomp.sdc.be.model.InterfaceDefinition;
123 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
124 import org.openecomp.sdc.be.model.LifecycleStateEnum;
125 import org.openecomp.sdc.be.model.Model;
126 import org.openecomp.sdc.be.model.NodeTypeInfo;
127 import org.openecomp.sdc.be.model.Operation;
128 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
129 import org.openecomp.sdc.be.model.PolicyDefinition;
130 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
131 import org.openecomp.sdc.be.model.PropertyDefinition;
132 import org.openecomp.sdc.be.model.RelationshipImpl;
133 import org.openecomp.sdc.be.model.RelationshipInfo;
134 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
135 import org.openecomp.sdc.be.model.RequirementDefinition;
136 import org.openecomp.sdc.be.model.Resource;
137 import org.openecomp.sdc.be.model.UploadArtifactInfo;
138 import org.openecomp.sdc.be.model.UploadCapInfo;
139 import org.openecomp.sdc.be.model.UploadComponentInstanceInfo;
140 import org.openecomp.sdc.be.model.UploadInfo;
141 import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
142 import org.openecomp.sdc.be.model.UploadPropInfo;
143 import org.openecomp.sdc.be.model.UploadReqInfo;
144 import org.openecomp.sdc.be.model.UploadResourceInfo;
145 import org.openecomp.sdc.be.model.User;
146 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
147 import org.openecomp.sdc.be.model.category.CategoryDefinition;
148 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
149 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
150 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
151 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
152 import org.openecomp.sdc.be.model.operations.StorageException;
153 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
154 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
155 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
156 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
157 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
158 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
159 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
160 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
161 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
162 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
163 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
164 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
165 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
166 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
167 import org.openecomp.sdc.be.tosca.CsarUtils;
168 import org.openecomp.sdc.be.tosca.CsarUtils.NonMetaArtifactInfo;
169 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
170 import org.openecomp.sdc.be.user.UserBusinessLogic;
171 import org.openecomp.sdc.be.utils.CommonBeUtils;
172 import org.openecomp.sdc.be.utils.TypeUtils;
173 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
174 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
175 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
176 import org.openecomp.sdc.common.api.Constants;
177 import org.openecomp.sdc.common.datastructure.Wrapper;
178 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
179 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
180 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
181 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
182 import org.openecomp.sdc.common.log.enums.StatusCode;
183 import org.openecomp.sdc.common.log.wrappers.Logger;
184 import org.openecomp.sdc.common.util.GeneralUtility;
185 import org.openecomp.sdc.common.util.ValidationUtils;
186 import org.openecomp.sdc.exception.ResponseFormat;
187 import org.springframework.beans.factory.annotation.Autowired;
188 import org.springframework.context.annotation.Lazy;
189 import org.yaml.snakeyaml.DumperOptions;
190 import org.yaml.snakeyaml.Yaml;
192 @org.springframework.stereotype.Component("resourceBusinessLogic")
193 public class ResourceBusinessLogic extends ComponentBusinessLogic {
195 private static final String DELETE_RESOURCE = "Delete Resource";
196 private static final String IN_RESOURCE = " in resource {} ";
197 private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
198 private static final String INITIAL_VERSION = "0.1";
199 private static final Logger log = Logger.getLogger(ResourceBusinessLogic.class);
200 private static final String CERTIFICATION_ON_IMPORT = "certification on import";
201 private static final String CREATE_RESOURCE = "Create Resource";
202 private static final String VALIDATE_DERIVED_BEFORE_UPDATE = "validate derived before update";
203 private static final String CATEGORY_IS_EMPTY = "Resource category is empty";
204 private static final String CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES = "Create Resource - validateCapabilityTypesCreate";
205 private static final String COMPONENT_INSTANCE_WITH_NAME = "component instance with name ";
206 private static final String COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE = "component instance with name {} in resource {} ";
207 private static final String VALID_CHARACTERS_ARTIFACT_NAME = "'A-Z', 'a-z', '0-9', '.', '_', '-', '@' and space";
208 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourceBusinessLogic.class.getName());
209 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
210 private final ResourceImportManager resourceImportManager;
211 private final InputsBusinessLogic inputsBusinessLogic;
212 private final OutputsBusinessLogic outputsBusinessLogic;
213 private final CompositionBusinessLogic compositionBusinessLogic;
214 private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic;
215 private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic;
216 private final UiComponentDataConverter uiComponentDataConverter;
217 private final CsarBusinessLogic csarBusinessLogic;
218 private final PropertyBusinessLogic propertyBusinessLogic;
219 private final PolicyBusinessLogic policyBusinessLogic;
220 private final ModelBusinessLogic modelBusinessLogic;
221 private final DataTypeBusinessLogic dataTypeBusinessLogic;
222 private final PolicyTypeBusinessLogic policyTypeBusinessLogic;
223 private final ModelOperation modelOperation;
224 private IInterfaceLifecycleOperation interfaceTypeOperation;
225 private LifecycleBusinessLogic lifecycleBusinessLogic;
227 private ICapabilityTypeOperation capabilityTypeOperation;
229 private TopologyComparator topologyComparator;
231 private ComponentValidator componentValidator;
233 private PropertyDataValueMergeBusinessLogic propertyDataValueMergeBusinessLogic;
235 private SoftwareInformationBusinessLogic softwareInformationBusinessLogic;
239 public ResourceBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
240 final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
241 final GroupBusinessLogic groupBusinessLogic, final InterfaceOperation interfaceOperation,
242 final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
243 final ArtifactsBusinessLogic artifactsBusinessLogic,
244 final ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
245 final @Lazy ResourceImportManager resourceImportManager, final InputsBusinessLogic inputsBusinessLogic,
246 final OutputsBusinessLogic outputsBusinessLogic, final CompositionBusinessLogic compositionBusinessLogic,
247 final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic,
248 final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic,
249 final UiComponentDataConverter uiComponentDataConverter, final CsarBusinessLogic csarBusinessLogic,
250 final ArtifactsOperations artifactToscaOperation, final PropertyBusinessLogic propertyBusinessLogic,
251 final ComponentContactIdValidator componentContactIdValidator, final ComponentNameValidator componentNameValidator,
252 final ComponentTagsValidator componentTagsValidator, final ComponentValidator componentValidator,
253 final ComponentIconValidator componentIconValidator,
254 final ComponentProjectCodeValidator componentProjectCodeValidator,
255 final ComponentDescriptionValidator componentDescriptionValidator, final PolicyBusinessLogic policyBusinessLogic,
256 final ModelBusinessLogic modelBusinessLogic, final DataTypeBusinessLogic dataTypeBusinessLogic,
257 final PolicyTypeBusinessLogic policyTypeBusinessLogic, final ModelOperation modelOperation) {
258 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
259 interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
260 componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
261 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
262 this.resourceImportManager = resourceImportManager;
263 this.inputsBusinessLogic = inputsBusinessLogic;
264 this.outputsBusinessLogic = outputsBusinessLogic;
265 this.compositionBusinessLogic = compositionBusinessLogic;
266 this.resourceDataMergeBusinessLogic = resourceDataMergeBusinessLogic;
267 this.csarArtifactsAndGroupsBusinessLogic = csarArtifactsAndGroupsBusinessLogic;
268 this.uiComponentDataConverter = uiComponentDataConverter;
269 this.csarBusinessLogic = csarBusinessLogic;
270 this.propertyBusinessLogic = propertyBusinessLogic;
271 this.policyBusinessLogic = policyBusinessLogic;
272 this.modelBusinessLogic = modelBusinessLogic;
273 this.dataTypeBusinessLogic = dataTypeBusinessLogic;
274 this.policyTypeBusinessLogic = policyTypeBusinessLogic;
275 this.modelOperation = modelOperation;
278 static <T> Either<T, RuntimeException> rollbackWithEither(final JanusGraphDao janusGraphDao, final ActionStatus actionStatus,
279 final String... params) {
280 if (janusGraphDao != null) {
281 janusGraphDao.rollback();
283 return Either.right(new ByActionStatusComponentException(actionStatus, params));
286 public LifecycleBusinessLogic getLifecycleBusinessLogic() {
287 return lifecycleBusinessLogic;
291 public void setLifecycleManager(LifecycleBusinessLogic lifecycleBusinessLogic) {
292 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
296 protected void setComponentValidator(ComponentValidator componentValidator) {
297 this.componentValidator = componentValidator;
300 public IElementOperation getElementDao() {
304 public void setElementDao(IElementOperation elementDao) {
305 this.elementDao = elementDao;
308 public UserBusinessLogic getUserAdmin() {
309 return this.userAdmin;
314 public void setUserAdmin(UserBusinessLogic userAdmin) {
315 this.userAdmin = userAdmin;
318 public ComponentsUtils getComponentsUtils() {
319 return this.componentsUtils;
324 public void setComponentsUtils(ComponentsUtils componentsUtils) {
325 this.componentsUtils = componentsUtils;
328 public ArtifactsBusinessLogic getArtifactsManager() {
329 return artifactsBusinessLogic;
332 public void setArtifactsManager(ArtifactsBusinessLogic artifactsManager) {
333 this.artifactsBusinessLogic = artifactsManager;
336 public ApplicationDataTypeCache getApplicationDataTypeCache() {
337 return applicationDataTypeCache;
342 public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) {
343 this.applicationDataTypeCache = applicationDataTypeCache;
347 public void setInterfaceTypeOperation(IInterfaceLifecycleOperation interfaceTypeOperation) {
348 this.interfaceTypeOperation = interfaceTypeOperation;
352 * the method returns a list of all the resources that are certified, the returned resources are only abstract or only none abstract according to
359 public List<Resource> getAllCertifiedResources(boolean getAbstract, HighestFilterEnum highestFilter, String userId) {
360 User user = validateUserExists(userId);
361 Boolean isHighest = null;
362 switch (highestFilter) {
368 case NON_HIGHEST_ONLY:
374 Either<List<Resource>, StorageOperationStatus> getResponse = toscaOperationFacade.getAllCertifiedResources(getAbstract, isHighest);
375 if (getResponse.isRight()) {
376 throw new StorageException(getResponse.right().value());
378 return getResponse.left().value();
381 public Either<Map<String, Boolean>, ResponseFormat> validateResourceNameExists(String resourceName, ResourceTypeEnum resourceTypeEnum,
383 validateUserExists(userId);
384 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
385 .validateComponentNameUniqueness(resourceName, resourceTypeEnum, ComponentTypeEnum.RESOURCE);
387 janusGraphDao.commit();
388 if (dataModelResponse.isLeft()) {
389 Map<String, Boolean> result = new HashMap<>();
390 result.put("isValid", dataModelResponse.left().value());
391 log.debug("validation was successfully performed.");
392 return Either.left(result);
394 ResponseFormat responseFormat = componentsUtils
395 .getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
396 return Either.right(responseFormat);
399 public Resource createResource(Resource resource, AuditingActionEnum auditingAction, User user, Map<String, byte[]> csarUIPayload,
400 String payloadName) {
401 validateResourceBeforeCreate(resource, user, false);
402 String csarUUID = payloadName == null ? resource.getCsarUUID() : payloadName;
403 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
404 "Starting to create resource from CSAR by user {} ", user.getUserId());
405 if (StringUtils.isNotEmpty(csarUUID)) {
406 csarBusinessLogic.validateCsarBeforeCreate(resource, auditingAction, user, csarUUID);
407 log.debug("CsarUUID is {} - going to create resource from CSAR", csarUUID);
408 Resource createResourceFromCsar = createResourceFromCsar(resource, user, csarUIPayload, csarUUID);
409 return updateCatalog(createResourceFromCsar, ChangeTypeEnum.LIFECYCLE).left().map(Resource.class::cast).left().value();
411 final Resource createResourceByDao = createResourceByDao(resource, user, auditingAction, false, false);
412 return updateCatalog(createResourceByDao, ChangeTypeEnum.LIFECYCLE).left().map(Resource.class::cast).left().value();
415 public Resource validateAndUpdateResourceFromCsar(Resource resource, User user, Map<String, byte[]> csarUIPayload, String payloadName,
416 String resourceUniqueId) {
417 String csarUUID = payloadName;
418 String csarVersion = null;
419 Resource updatedResource = null;
420 if (payloadName == null) {
421 csarUUID = resource.getCsarUUID();
422 csarVersion = resource.getCsarVersion();
424 if (csarUUID != null && !csarUUID.isEmpty()) {
425 Resource oldResource = getResourceByUniqueId(resourceUniqueId);
426 validateCsarUuidMatching(oldResource, resource, csarUUID, resourceUniqueId, user);
427 validateCsarIsNotAlreadyUsed(oldResource, resource, csarUUID, user);
428 if (oldResource != null && ValidationUtils.hasBeenCertified(oldResource.getVersion())) {
429 overrideImmutableMetadata(oldResource, resource);
431 validateResourceBeforeCreate(resource, user, false);
432 String oldCsarVersion = oldResource != null ? oldResource.getCsarVersion() : null;
433 log.debug("CsarUUID is {} - going to update resource with UniqueId {} from CSAR", csarUUID, resourceUniqueId);
434 // (on boarding flow): If the update includes same csarUUID and
436 // same csarVersion as already in the VF - no need to import the
438 // csar (do only metadata changes if there are).
439 if (csarVersion != null && oldCsarVersion != null && oldCsarVersion.equals(csarVersion)) {
440 updatedResource = updateResourceMetadata(resourceUniqueId, resource, oldResource, user, false);
442 updatedResource = updateResourceFromCsar(oldResource, resource, user, AuditingActionEnum.UPDATE_RESOURCE_METADATA, false,
443 csarUIPayload, csarUUID);
446 log.debug("Failed to update resource {}, csarUUID or payload name is missing", resource.getSystemName());
447 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CSAR_UUID, resource.getName());
448 componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.CREATE_RESOURCE);
449 throw new ByActionStatusComponentException(ActionStatus.MISSING_CSAR_UUID, resource.getName());
451 return updatedResource;
454 private void validateCsarIsNotAlreadyUsed(Resource oldResource, Resource resource, String csarUUID, User user) {
455 // (on boarding flow): If the update includes a csarUUID: verify this
457 // csarUUID is not in use by another VF, If it is - use same error as
461 // "Error: The VSP with UUID %1 was already imported for VF %2. Please
463 // select another or update the existing VF." %1 - csarUUID, %2 - VF
466 Either<Resource, StorageOperationStatus> resourceLinkedToCsarRes = toscaOperationFacade
467 .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUUID, resource.getSystemName());
468 if (resourceLinkedToCsarRes.isRight()) {
469 if (StorageOperationStatus.NOT_FOUND != resourceLinkedToCsarRes.right().value()) {
470 log.debug("Failed to find previous resource by CSAR {} and system name {}", csarUUID, resource.getSystemName());
471 throw new StorageException(resourceLinkedToCsarRes.right().value());
473 } else if (!resourceLinkedToCsarRes.left().value().getUniqueId().equals(oldResource.getUniqueId()) && !resourceLinkedToCsarRes.left().value()
474 .getName().equals(oldResource.getName())) {
475 ResponseFormat errorResponse = componentsUtils
476 .getResponseFormat(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, resourceLinkedToCsarRes.left().value().getName());
477 componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.UPDATE_RESOURCE_METADATA);
478 throw new ByActionStatusComponentException(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, resourceLinkedToCsarRes.left().value().getName());
482 private void validateCsarUuidMatching(Resource resource, Resource oldResource, String csarUUID, String resourceUniqueId, User user) {
483 // (on boarding flow): If the update includes csarUUID which is
485 // different from the csarUUID of the VF - fail with
487 // error: "Error: Resource %1 cannot be updated using since it is linked
489 // to a different VSP" %1 - VF name
490 String oldCsarUUID = oldResource.getCsarUUID();
491 if (oldCsarUUID != null && !oldCsarUUID.isEmpty() && !csarUUID.equals(oldCsarUUID)) {
492 log.debug("Failed to update resource with UniqueId {} using Csar {}, since the resource is linked to a different VSP {}",
493 resourceUniqueId, csarUUID, oldCsarUUID);
494 ResponseFormat errorResponse = componentsUtils
495 .getResponseFormat(ActionStatus.RESOURCE_LINKED_TO_DIFFERENT_VSP, resource.getName(), csarUUID, oldCsarUUID);
496 componentsUtils.auditResource(errorResponse, user, resource, AuditingActionEnum.UPDATE_RESOURCE_METADATA);
497 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_LINKED_TO_DIFFERENT_VSP, resource.getName(), csarUUID, oldCsarUUID);
501 private Resource getResourceByUniqueId(String resourceUniqueId) {
502 Either<Resource, StorageOperationStatus> oldResourceRes = toscaOperationFacade.getToscaFullElement(resourceUniqueId);
503 if (oldResourceRes.isRight()) {
504 log.debug("Failed to find previous resource by UniqueId {}, status: {}", resourceUniqueId, oldResourceRes.right().value());
505 throw new StorageException(oldResourceRes.right().value());
507 return oldResourceRes.left().value();
510 private void overrideImmutableMetadata(Resource oldResource, Resource resource) {
511 resource.setName(oldResource.getName());
512 resource.setIcon(oldResource.getIcon());
513 resource.setTags(oldResource.getTags());
514 resource.setCategories(oldResource.getCategories());
515 resource.setDerivedFrom(oldResource.getDerivedFrom());
518 private Resource updateResourceFromCsar(Resource oldResource, Resource newResource, User user, AuditingActionEnum updateResource,
519 boolean inTransaction, Map<String, byte[]> csarUIPayload, String csarUUID) {
520 Resource updatedResource = null;
521 validateLifecycleState(oldResource, user);
522 String lockedResourceId = oldResource.getUniqueId();
523 List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
524 CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(newResource, oldResource, user, csarUIPayload, csarUUID);
525 lockComponent(lockedResourceId, oldResource, "update Resource From Csar");
526 Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
527 Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
528 nodeTypesInfo, csarInfo, oldResource);
529 if (findNodeTypesArtifactsToHandleRes.isRight()) {
530 log.debug("failed to find node types for update with artifacts during import csar {}. ", csarInfo.getCsarUUID());
531 throw new ByResponseFormatComponentException(findNodeTypesArtifactsToHandleRes.right().value());
533 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = findNodeTypesArtifactsToHandleRes.left()
536 updatedResource = updateResourceFromYaml(oldResource, newResource, updateResource, createdArtifacts, csarInfo.getMainTemplateName(),
537 csarInfo.getMainTemplateContent(), csarInfo, nodeTypesInfo, nodeTypesArtifactsToHandle, null, false);
538 } catch (ComponentException | StorageException e) {
539 rollback(inTransaction, newResource, createdArtifacts, null);
542 janusGraphDao.commit();
543 log.debug("unlock resource {}", lockedResourceId);
544 graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource);
546 return updatedResource;
549 private void validateLifecycleState(Resource oldResource, User user) {
550 if (LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == oldResource.getLifecycleState() && !oldResource.getLastUpdaterUserId()
551 .equals(user.getUserId())) {
552 log.debug("#validateLifecycleState - Current user is not last updater, last updater userId: {}, current user userId: {}",
553 oldResource.getLastUpdaterUserId(), user.getUserId());
554 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
558 private Resource updateResourceFromYaml(Resource oldResource, Resource newResource, AuditingActionEnum actionEnum,
559 List<ArtifactDefinition> createdArtifacts, String yamlFileName, String yamlFileContent, CsarInfo csarInfo,
560 Map<String, NodeTypeInfo> nodeTypesInfo,
561 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
562 String nodeName, boolean isNested) {
563 boolean inTransaction = true;
564 boolean shouldLock = false;
565 Resource preparedResource = null;
566 ParsedToscaYamlInfo uploadComponentInstanceInfoMap;
568 uploadComponentInstanceInfoMap = csarBusinessLogic
569 .getParsedToscaYamlInfo(yamlFileContent, yamlFileName, nodeTypesInfo, csarInfo, nodeName, oldResource);
570 Map<String, UploadComponentInstanceInfo> instances = uploadComponentInstanceInfoMap.getInstances();
571 if (MapUtils.isEmpty(instances) && newResource.getResourceType() != ResourceTypeEnum.PNF) {
572 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlFileName);
574 preparedResource = updateExistingResourceByImport(newResource, oldResource, csarInfo.getModifier(), inTransaction, shouldLock,
576 log.trace("YAML topology file found in CSAR, file name: {}, contents: {}", yamlFileName, yamlFileContent);
577 handleResourceGenericType(preparedResource, yamlFileContent, uploadComponentInstanceInfoMap,
578 uploadComponentInstanceInfoMap.getSubstitutionMappingNodeType());
579 handleNodeTypes(yamlFileName, preparedResource, yamlFileContent, shouldLock, nodeTypesArtifactsToHandle, createdArtifacts, nodeTypesInfo,
580 csarInfo, nodeName, newResource.getModel());
581 preparedResource = createInputsOnResource(preparedResource, uploadComponentInstanceInfoMap.getInputs());
582 Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
583 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(uploadComponentInstanceInfoMap,
584 newResource.getModel());
585 preparedResource = createResourceInstances(yamlFileName, preparedResource, oldResource, instancesToCreate, csarInfo.getCreatedNodes(),
586 existingNodeTypesByResourceNames);
587 preparedResource = createResourceInstancesRelations(csarInfo.getModifier(), yamlFileName, preparedResource, oldResource,
589 existingNodeTypesByResourceNames);
590 } catch (ComponentException e) {
591 ResponseFormat responseFormat =
592 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
593 log.debug("#updateResourceFromYaml - failed to update newResource from yaml {} .The error is {}", yamlFileName, responseFormat);
595 .auditResource(responseFormat, csarInfo.getModifier(), preparedResource == null ? oldResource : preparedResource, actionEnum);
597 } catch (StorageException e) {
598 ResponseFormat responseFormat = componentsUtils
599 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
600 log.debug("#updateResourceFromYaml - failed to update newResource from yaml {} .The error is {}", yamlFileName, responseFormat);
602 .auditResource(responseFormat, csarInfo.getModifier(), preparedResource == null ? oldResource : preparedResource, actionEnum);
605 Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic
606 .validateUpdateVfGroupNames(uploadComponentInstanceInfoMap.getGroups(), preparedResource.getSystemName());
607 if (validateUpdateVfGroupNamesRes.isRight()) {
608 throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value());
610 // add groups to newResource
611 Map<String, GroupDefinition> groups;
612 if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) {
613 groups = validateUpdateVfGroupNamesRes.left().value();
615 groups = uploadComponentInstanceInfoMap.getGroups();
617 handleGroupsProperties(preparedResource, groups);
618 Either<Boolean, ActionStatus> isTopologyChanged = topologyComparator.isTopologyChanged(oldResource, preparedResource);
619 preparedResource = updateGroupsOnResource(preparedResource, groups);
620 NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName, nodeTypesArtifactsToHandle);
621 Either<Resource, ResponseFormat> updateArtifactsEither = createOrUpdateArtifacts(ArtifactOperationEnum.UPDATE, createdArtifacts, yamlFileName,
622 csarInfo, preparedResource, nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock);
623 if (updateArtifactsEither.isRight()) {
624 log.debug("failed to update artifacts {}", updateArtifactsEither.right().value());
625 throw new ByResponseFormatComponentException(updateArtifactsEither.right().value());
627 preparedResource = getResourceWithGroups(updateArtifactsEither.left().value().getUniqueId());
628 updateGroupsName(oldResource, preparedResource, isTopologyChanged.left().value());
629 updateResourceInstancesNames(oldResource, csarInfo, preparedResource, isTopologyChanged.left().value());
630 final String preparedResourceId = preparedResource != null ? preparedResource.getUniqueId() : "";
631 preparedResource = getResourceWithGroups(preparedResourceId);
632 updateVolumeGroup(preparedResource);
633 ActionStatus mergingPropsAndInputsStatus = resourceDataMergeBusinessLogic.mergeResourceEntities(oldResource, preparedResource);
634 if (mergingPropsAndInputsStatus != ActionStatus.OK) {
635 ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(mergingPropsAndInputsStatus, preparedResource);
636 throw new ByResponseFormatComponentException(responseFormat);
638 compositionBusinessLogic.setPositionsForComponentInstances(preparedResource, csarInfo.getModifier().getUserId());
639 return preparedResource;
642 protected void updateVolumeGroup(Resource preparedResource) {
643 List<GroupDefinition> groups = preparedResource.safeGetGroups();
644 for (GroupDefinition group : groups) {
645 Map<String, ArtifactDefinition> createdNewArtifacts = preparedResource.getDeploymentArtifacts();
646 if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
647 List<PropertyDataDefinition> volumePropList = group.getProperties().stream().filter(p -> "volume_group".equals(p.getName()))
648 .collect(Collectors.toList());
649 if (!volumePropList.isEmpty()) {
650 PropertyDataDefinition volumeProp = volumePropList.get(0);
651 if (volumeProp != null) {
652 boolean isVolumeGroup = isVolumeGroup(group.getArtifacts(), new ArrayList<>(createdNewArtifacts.values()));
653 if (!volumePropList.get(0).getValue().equals(String.valueOf(isVolumeGroup))) {
654 volumeProp.setValue(String.valueOf(isVolumeGroup));
655 volumeProp.setDefaultValue(String.valueOf(isVolumeGroup));
663 private void updateGroupsName(Resource oldResource, Resource preparedResource, boolean isTopologyChanged) {
664 if (oldResource == null || preparedResource == null) {
665 log.debug("Failed to update groups name : oldResource or preparedResource is null");
666 } else if (CollectionUtils.isNotEmpty(oldResource.getGroups()) && CollectionUtils.isNotEmpty(preparedResource.getGroups())) {
667 Map<String, String> oldGroups = oldResource.getGroups().stream()
668 .collect(toMap(GroupDataDefinition::getInvariantName, GroupDataDefinition::getName));
669 List<GroupDefinition> updatedGroups = preparedResource.getGroups().stream()
670 .filter(group -> oldGroups.containsKey(group.getInvariantName()) && !group.getName().equals(oldGroups.get(group.getInvariantName())))
672 if (CollectionUtils.isNotEmpty(updatedGroups)) {
673 if (isTopologyChanged) {
674 updatedGroups.stream().filter(group -> !group.isVspOriginated())
675 .forEach(group -> group.setName(oldGroups.get(group.getInvariantName())));
677 updatedGroups.forEach(group -> group.setName(oldGroups.get(group.getInvariantName())));
679 groupBusinessLogic.updateGroups(preparedResource, updatedGroups, false);
684 private void updateResourceInstancesNames(Resource oldResource, CsarInfo csarInfo, Resource preparedResource, boolean isTopologyChanged) {
685 if (oldResource == null || preparedResource == null) {
686 log.debug("Failed to update resource instances names : oldResource or preparedResource is null");
688 if (CollectionUtils.isNotEmpty(oldResource.getComponentInstances())) {
689 Map<String, String> oldInstances = oldResource.getComponentInstances().stream()
690 .collect(toMap(ComponentInstance::getInvariantName, ComponentInstance::getName));
691 List<ComponentInstance> updatedInstances = preparedResource.getComponentInstances().stream()
692 .filter(i -> oldInstances.containsKey(i.getInvariantName()) && !i.getName().equals(oldInstances.get(i.getInvariantName())))
694 if (CollectionUtils.isNotEmpty(updatedInstances)) {
695 if (isTopologyChanged) {
696 updatedInstances.stream().filter(i -> !i.isCreatedFromCsar()).forEach(i -> i.setName(oldInstances.get(i.getInvariantName())));
698 updatedInstances.forEach(i -> i.setName(oldInstances.get(i.getInvariantName())));
702 componentInstanceBusinessLogic.updateComponentInstance(ComponentTypeEnum.RESOURCE_PARAM_NAME, null, preparedResource.getUniqueId(),
703 csarInfo.getModifier().getUserId(), preparedResource.getComponentInstances(), false);
707 private Either<Resource, ResponseFormat> createOrUpdateArtifacts(ArtifactOperationEnum operation, List<ArtifactDefinition> createdArtifacts,
708 String yamlFileName, CsarInfo csarInfo, Resource preparedResource,
709 NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts,
710 boolean inTransaction, boolean shouldLock) {
711 String nodeName = nodeTypeInfoToUpdateArtifacts.getNodeName();
712 Resource resource = preparedResource;
713 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = nodeTypeInfoToUpdateArtifacts
714 .getNodeTypesArtifactsToHandle();
715 if (preparedResource.getResourceType() == ResourceTypeEnum.CVFC) {
716 if (nodeName != null && nodeTypesArtifactsToHandle.get(nodeName) != null && !nodeTypesArtifactsToHandle.get(nodeName).isEmpty()) {
717 Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes = handleNodeTypeArtifacts(preparedResource,
718 nodeTypesArtifactsToHandle.get(nodeName), createdArtifacts, csarInfo.getModifier(), inTransaction, true);
719 if (handleNodeTypeArtifactsRes.isRight()) {
720 return Either.right(handleNodeTypeArtifactsRes.right().value());
724 Either<Resource, ResponseFormat> createdCsarArtifactsEither = handleVfCsarArtifacts(preparedResource, csarInfo, createdArtifacts,
725 new ArtifactOperationInfo(false, false, operation), shouldLock, inTransaction);
726 log.trace("************* Finished to add artifacts from yaml {}", yamlFileName);
727 if (createdCsarArtifactsEither.isRight()) {
728 return createdCsarArtifactsEither;
730 resource = createdCsarArtifactsEither.left().value();
732 return Either.left(resource);
735 private Resource handleResourceGenericType(Resource resource) {
736 Resource genericResource = fetchAndSetDerivedFromGenericType(resource);
738 if (resource.shouldGenerateInputs()) {
739 generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
741 return genericResource;
744 private Resource handleResourceGenericType(final Resource resource, final String topologyTemplateYaml,
745 final ParsedToscaYamlInfo parsedToscaYamlInfo, final String substitutionMappingNodeType) {
746 if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
747 final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
748 (Map<String, Object>) new Yaml().load(topologyTemplateYaml), substitutionMappingNodeType);
749 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
750 (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
752 generatePropertiesFromGenericType(resource, genericResource);
753 generatePropertiesFromNodeType(resource, substitutableAsNodeType);
754 final String resourceId = resource.getUniqueId();
755 resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
756 UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
757 createResourcePropertiesOnGraph(resource);
758 return genericResource;
760 return handleResourceGenericType(resource);
763 private Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandle(
764 final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo, final Resource oldResource) {
765 final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = new HashMap<>();
766 Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> nodeTypesArtifactsToHandleRes = Either
767 .left(nodeTypesArtifactsToHandle);
769 final Map<String, List<ArtifactDefinition>> extractedVfcsArtifacts = CsarUtils.extractVfcsArtifactsFromCsar(csarInfo.getCsar());
770 final Map<String, ImmutablePair<String, String>> extractedVfcToscaNames = extractVfcToscaNames(nodeTypesInfo, oldResource.getName(),
772 log.debug("Going to fetch node types for resource with name {} during import csar with UUID {}. ", oldResource.getName(),
773 csarInfo.getCsarUUID());
774 extractedVfcToscaNames.forEach(
775 (namespace, vfcToscaNames) -> findAddNodeTypeArtifactsToHandle(csarInfo, nodeTypesArtifactsToHandle, oldResource,
776 extractedVfcsArtifacts, namespace, vfcToscaNames));
777 } catch (Exception e) {
778 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
779 nodeTypesArtifactsToHandleRes = Either.right(responseFormat);
780 log.debug("Exception occurred when findNodeTypesUpdatedArtifacts, error is:{}", e.getMessage(), e);
782 return nodeTypesArtifactsToHandleRes;
785 private void findAddNodeTypeArtifactsToHandle(CsarInfo csarInfo,
786 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
787 Resource resource, Map<String, List<ArtifactDefinition>> extractedVfcsArtifacts, String namespace,
788 ImmutablePair<String, String> vfcToscaNames) {
789 EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> curNodeTypeArtifactsToHandle = null;
790 log.debug("Going to fetch node type with tosca name {}. ", vfcToscaNames.getLeft());
791 Resource curNodeType = findVfcResource(csarInfo, resource, vfcToscaNames.getLeft(), vfcToscaNames.getRight(), null);
792 if (!isEmpty(extractedVfcsArtifacts)) {
793 List<ArtifactDefinition> currArtifacts = new ArrayList<>();
794 if (extractedVfcsArtifacts.containsKey(namespace)) {
795 handleAndAddExtractedVfcsArtifacts(currArtifacts, extractedVfcsArtifacts.get(namespace));
797 curNodeTypeArtifactsToHandle = findNodeTypeArtifactsToHandle(curNodeType, currArtifacts);
798 } else if (curNodeType != null) {
799 // delete all artifacts if have not received artifacts from
802 curNodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
803 List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
804 // delete all informational artifacts
805 artifactsToDelete.addAll(
806 curNodeType.getArtifacts().values().stream().filter(a -> a.getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL)
808 // delete all deployment artifacts
809 artifactsToDelete.addAll(curNodeType.getDeploymentArtifacts().values());
810 if (!artifactsToDelete.isEmpty()) {
811 curNodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
814 if (isNotEmpty(curNodeTypeArtifactsToHandle)) {
815 nodeTypesArtifactsToHandle.put(namespace, curNodeTypeArtifactsToHandle);
819 private Resource findVfcResource(CsarInfo csarInfo, Resource resource, String currVfcToscaName, String previousVfcToscaName,
820 StorageOperationStatus status) {
821 if (status != null && status != StorageOperationStatus.NOT_FOUND) {
822 log.debug("Error occurred during fetching node type with tosca name {}, error: {}", currVfcToscaName, status);
823 ResponseFormat responseFormat = componentsUtils
824 .getResponseFormat(componentsUtils.convertFromStorageResponse(status), csarInfo.getCsarUUID());
825 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.CREATE_RESOURCE);
826 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), csarInfo.getCsarUUID());
827 } else if (StringUtils.isNotEmpty(currVfcToscaName)) {
828 return (Resource) toscaOperationFacade.getLatestByToscaResourceName(currVfcToscaName, resource.getModel()).left()
829 .on(st -> findVfcResource(csarInfo, resource, previousVfcToscaName, null, st));
834 private EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> findNodeTypeArtifactsToHandle(Resource curNodeType,
835 List<ArtifactDefinition> extractedArtifacts) {
837 List<ArtifactDefinition> artifactsToUpload = new ArrayList<>(extractedArtifacts);
838 List<ArtifactDefinition> artifactsToUpdate = new ArrayList<>();
839 List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
840 processExistingNodeTypeArtifacts(extractedArtifacts, artifactsToUpload, artifactsToUpdate, artifactsToDelete,
841 collectExistingArtifacts(curNodeType));
842 return putFoundArtifacts(artifactsToUpload, artifactsToUpdate, artifactsToDelete);
843 } catch (Exception e) {
844 log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
845 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
849 private EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> putFoundArtifacts(List<ArtifactDefinition> artifactsToUpload,
850 List<ArtifactDefinition> artifactsToUpdate,
851 List<ArtifactDefinition> artifactsToDelete) {
852 EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle = null;
853 if (!artifactsToUpload.isEmpty() || !artifactsToUpdate.isEmpty() || !artifactsToDelete.isEmpty()) {
854 nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
855 if (!artifactsToUpload.isEmpty()) {
856 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
858 if (!artifactsToUpdate.isEmpty()) {
859 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
861 if (!artifactsToDelete.isEmpty()) {
862 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
865 return nodeTypeArtifactsToHandle;
868 private void processExistingNodeTypeArtifacts(List<ArtifactDefinition> extractedArtifacts, List<ArtifactDefinition> artifactsToUpload,
869 List<ArtifactDefinition> artifactsToUpdate, List<ArtifactDefinition> artifactsToDelete,
870 Map<String, ArtifactDefinition> existingArtifacts) {
871 if (!existingArtifacts.isEmpty()) {
872 extractedArtifacts.forEach(a -> processNodeTypeArtifact(artifactsToUpload, artifactsToUpdate, existingArtifacts, a));
873 artifactsToDelete.addAll(existingArtifacts.values());
877 private void processNodeTypeArtifact(List<ArtifactDefinition> artifactsToUpload, List<ArtifactDefinition> artifactsToUpdate,
878 Map<String, ArtifactDefinition> existingArtifacts, ArtifactDefinition currNewArtifact) {
879 Optional<ArtifactDefinition> foundArtifact = existingArtifacts.values().stream()
880 .filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName())).findFirst();
881 if (foundArtifact.isPresent()) {
882 if (foundArtifact.get().getArtifactType().equals(currNewArtifact.getArtifactType())) {
883 updateFoundArtifact(artifactsToUpdate, currNewArtifact, foundArtifact.get());
884 existingArtifacts.remove(foundArtifact.get().getArtifactLabel());
885 artifactsToUpload.remove(currNewArtifact);
887 log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
888 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR,
889 currNewArtifact.getArtifactName(), currNewArtifact.getArtifactType(), foundArtifact.get().getArtifactType());
894 private void updateFoundArtifact(List<ArtifactDefinition> artifactsToUpdate, ArtifactDefinition currNewArtifact,
895 ArtifactDefinition foundArtifact) {
896 if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
897 foundArtifact.setPayload(currNewArtifact.getPayloadData());
898 foundArtifact.setPayloadData(Base64.encodeBase64String(currNewArtifact.getPayloadData()));
899 foundArtifact.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(currNewArtifact.getPayloadData()));
900 artifactsToUpdate.add(foundArtifact);
904 private Map<String, ArtifactDefinition> collectExistingArtifacts(Resource curNodeType) {
905 Map<String, ArtifactDefinition> existingArtifacts = new HashMap<>();
906 if (curNodeType == null) {
907 return existingArtifacts;
909 if (MapUtils.isNotEmpty(curNodeType.getDeploymentArtifacts())) {
910 existingArtifacts.putAll(curNodeType.getDeploymentArtifacts());
912 if (MapUtils.isNotEmpty(curNodeType.getArtifacts())) {
913 existingArtifacts.putAll(
914 curNodeType.getArtifacts().entrySet().stream().filter(e -> e.getValue().getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL)
915 .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)));
917 return existingArtifacts;
921 * Changes resource life cycle state to checked out
925 * @param inTransaction
928 private Either<Resource, ResponseFormat> checkoutResource(Resource resource, User user, boolean inTransaction) {
929 Either<Resource, ResponseFormat> checkoutResourceRes;
931 if (!resource.getComponentMetadataDefinition().getMetadataDataDefinition().getState()
932 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
933 log.debug("************* Going to change life cycle state of resource {} to not certified checked out. ", resource.getName());
934 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
935 .changeComponentState(resource.getComponentType(), resource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT,
936 new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT, LifecycleChanceActionEnum.CREATE_FROM_CSAR), inTransaction, true);
937 if (checkoutRes.isRight()) {
938 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ",
939 resource.getComponentType().getNodeType(), resource.getUniqueId(), checkoutRes.right().value().getStatus());
940 checkoutResourceRes = Either.right(checkoutRes.right().value());
942 checkoutResourceRes = Either.left((Resource) checkoutRes.left().value());
945 checkoutResourceRes = Either.left(resource);
947 } catch (Exception e) {
948 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
949 checkoutResourceRes = Either.right(responseFormat);
950 log.debug("Exception occurred when checkoutResource {} , error is:{}", resource.getName(), e.getMessage(), e);
952 return checkoutResourceRes;
956 * Handles Artifacts of NodeType
958 * @param nodeTypeResource
959 * @param nodeTypeArtifactsToHandle
961 * @param inTransaction
964 public Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifacts(Resource nodeTypeResource,
965 Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
966 List<ArtifactDefinition> createdArtifacts, User user,
967 boolean inTransaction, boolean ignoreLifecycleState) {
968 List<ArtifactDefinition> handleNodeTypeArtifactsRequestRes;
969 Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes = null;
970 Either<Resource, ResponseFormat> changeStateResponse;
972 changeStateResponse = checkoutResource(nodeTypeResource, user, inTransaction);
973 if (changeStateResponse.isRight()) {
974 return Either.right(changeStateResponse.right().value());
976 nodeTypeResource = changeStateResponse.left().value();
977 List<ArtifactDefinition> handledNodeTypeArtifacts = new ArrayList<>();
978 log.debug("************* Going to handle artifacts of node type resource {}. ", nodeTypeResource.getName());
979 for (Entry<ArtifactOperationEnum, List<ArtifactDefinition>> curOperationEntry : nodeTypeArtifactsToHandle.entrySet()) {
980 ArtifactOperationEnum curOperation = curOperationEntry.getKey();
981 List<ArtifactDefinition> curArtifactsToHandle = curOperationEntry.getValue();
982 if (curArtifactsToHandle != null && !curArtifactsToHandle.isEmpty()) {
983 log.debug("************* Going to {} artifact to vfc {}", curOperation.name(), nodeTypeResource.getName());
984 handleNodeTypeArtifactsRequestRes = artifactsBusinessLogic
985 .handleArtifactsRequestForInnerVfcComponent(curArtifactsToHandle, nodeTypeResource, user, createdArtifacts,
986 new ArtifactOperationInfo(false, ignoreLifecycleState, curOperation), false, inTransaction);
987 if (ArtifactOperationEnum.isCreateOrLink(curOperation)) {
988 createdArtifacts.addAll(handleNodeTypeArtifactsRequestRes);
990 handledNodeTypeArtifacts.addAll(handleNodeTypeArtifactsRequestRes);
993 handleNodeTypeArtifactsRes = Either.left(handledNodeTypeArtifacts);
994 } catch (Exception e) {
995 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
996 handleNodeTypeArtifactsRes = Either.right(responseFormat);
997 log.debug("Exception occurred when handleVfcArtifacts, error is:{}", e.getMessage(), e);
999 return handleNodeTypeArtifactsRes;
1002 private Map<String, ImmutablePair<String, String>> extractVfcToscaNames(final Map<String, NodeTypeInfo> nodeTypesInfo,
1003 final String vfResourceName, final CsarInfo csarInfo) {
1004 final Map<String, ImmutablePair<String, String>> vfcToscaNames = new HashMap<>();
1005 final Map<String, Object> nodes = extractAllNodes(nodeTypesInfo, csarInfo);
1006 if (!nodes.isEmpty()) {
1007 for (Entry<String, Object> nodeType : nodes.entrySet()) {
1008 final ImmutablePair<String, String> toscaResourceName = buildNestedToscaResourceName(ResourceTypeEnum.VFC.name(), vfResourceName,
1010 vfcToscaNames.put(nodeType.getKey(), toscaResourceName);
1013 for (final NodeTypeInfo cvfc : nodeTypesInfo.values()) {
1014 vfcToscaNames.put(cvfc.getType(), buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), vfResourceName, cvfc.getType()));
1016 return vfcToscaNames;
1019 private Map<String, Object> extractAllNodes(Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo) {
1020 Map<String, Object> nodes = new HashMap<>();
1021 for (NodeTypeInfo nodeTypeInfo : nodeTypesInfo.values()) {
1022 extractNodeTypes(nodes, nodeTypeInfo.getMappedToscaTemplate());
1024 extractNodeTypes(nodes, csarInfo.getMappedToscaMainTemplate());
1028 private void extractNodeTypes(Map<String, Object> nodes, Map<String, Object> mappedToscaTemplate) {
1029 Either<Map<String, Object>, ResultStatusEnum> eitherNodeTypes = ImportUtils
1030 .findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
1031 if (eitherNodeTypes.isLeft()) {
1032 nodes.putAll(eitherNodeTypes.left().value());
1036 public Resource createResourceFromCsar(Resource resource, User user, Map<String, byte[]> csarUIPayload, String csarUUID) {
1037 log.trace("************* created successfully from YAML, resource TOSCA ");
1038 loggerSupportability
1039 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.STARTED, "Starting to create Resource From Csar by user {}",
1041 OnboardedCsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID);
1043 Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
1044 final String model = resource.getModel();
1045 if (StringUtils.isNotEmpty(model)) {
1046 final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(model, csarInfo.getDataTypes());
1047 final Map<String, Object> policyTypesToCreate = getPolicytypesToCreate(model, csarInfo.getPolicyTypes());
1048 if (MapUtils.isNotEmpty(dataTypesToCreate) || MapUtils.isNotEmpty(policyTypesToCreate)) {
1049 createModel(resource, csarInfo.getVfResourceName());
1051 if (MapUtils.isNotEmpty(dataTypesToCreate)) {
1052 dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), model, true);
1054 if (MapUtils.isNotEmpty(policyTypesToCreate)) {
1055 policyTypeBusinessLogic.createPolicyTypeFromYaml(new Yaml().dump(policyTypesToCreate), model, true);
1058 Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
1059 nodeTypesInfo, csarInfo, resource);
1060 if (findNodeTypesArtifactsToHandleRes.isRight()) {
1061 log.debug("failed to find node types for update with artifacts during import csar {}. ", csarInfo.getCsarUUID());
1062 loggerSupportability
1063 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1064 "error: {}", findNodeTypesArtifactsToHandleRes.right().value());
1065 throw new ByResponseFormatComponentException(findNodeTypesArtifactsToHandleRes.right().value());
1067 Resource vfResource = createResourceFromYaml(resource, csarInfo.getMainTemplateContent(), csarInfo.getMainTemplateName(), nodeTypesInfo,
1068 csarInfo, findNodeTypesArtifactsToHandleRes.left().value(), true, false, null);
1069 log.trace("*************VF Resource created successfully from YAML, resource TOSCA name: {}", vfResource.getToscaResourceName());
1070 loggerSupportability
1071 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.COMPLETE, "Ended create Resource From Csar by user {}",
1076 private Resource validateResourceBeforeCreate(Resource resource, User user, boolean inTransaction) {
1077 log.trace("validating resource before create");
1078 user.copyData(validateUser(user, CREATE_RESOURCE, resource, AuditingActionEnum.CREATE_RESOURCE, false));
1079 // validate user role
1080 validateUserRole(user, resource, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
1081 // VF / PNF "derivedFrom" should be null (or ignored)
1082 if (ModelConverter.isAtomicComponent(resource)) {
1083 validateDerivedFromNotEmpty(user, resource, AuditingActionEnum.CREATE_RESOURCE);
1085 return validateResourceBeforeCreate(resource, user, AuditingActionEnum.CREATE_RESOURCE, inTransaction, null);
1088 private Resource createResourceFromYaml(Resource resource, String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo,
1090 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1091 boolean shouldLock, boolean inTransaction, String nodeName) {
1092 List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
1093 Resource createdResource;
1095 ParsedToscaYamlInfo parsedToscaYamlInfo = csarBusinessLogic
1096 .getParsedToscaYamlInfo(topologyTemplateYaml, yamlName, nodeTypesInfo, csarInfo, nodeName, resource);
1097 if (MapUtils.isEmpty(parsedToscaYamlInfo.getInstances()) && resource.getResourceType() != ResourceTypeEnum.PNF) {
1098 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
1100 log.debug("#createResourceFromYaml - Going to create resource {} and RIs ", resource.getName());
1101 loggerSupportability
1102 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED, "");
1103 createdResource = createResourceAndRIsFromYaml(yamlName, resource, parsedToscaYamlInfo, AuditingActionEnum.IMPORT_RESOURCE, false,
1104 createdArtifacts, topologyTemplateYaml, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, shouldLock, inTransaction, nodeName);
1105 log.debug("#createResourceFromYaml - The resource {} has been created ", resource.getName());
1106 loggerSupportability
1107 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1108 "The resource has been created: {}", resource.getName());
1109 } catch (ComponentException e) {
1110 ResponseFormat responseFormat =
1111 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
1112 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
1114 } catch (StorageException e) {
1115 ResponseFormat responseFormat = componentsUtils
1116 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
1117 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
1120 return createdResource;
1123 public Map<String, Resource> createResourcesFromYamlNodeTypesList(String yamlName, Resource resource, Map<String, Object> mappedToscaTemplate,
1125 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
1126 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1127 Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1128 final String substitutableAsNodeType) {
1129 Either<String, ResultStatusEnum> toscaVersion = findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
1130 if (toscaVersion.isRight()) {
1131 throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE);
1133 Map<String, Object> mapToConvert = new HashMap<>();
1134 mapToConvert.put(TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION.getElementName(), toscaVersion.left().value());
1135 final Map<String, Object> nodeTypes = getNodeTypesFromTemplate(mappedToscaTemplate, substitutableAsNodeType);
1136 createNodeTypes(yamlName, resource, needLock, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, mapToConvert,
1138 return csarInfo.getCreatedNodes();
1141 private Map<String, Object> getNodeTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, final String substitutableAsNodeType) {
1142 final Map<String, Object> nodeTypes = getAllNodeTypesInTemplate(mappedToscaTemplate);
1143 if (StringUtils.isNotEmpty(substitutableAsNodeType)) {
1144 nodeTypes.remove(substitutableAsNodeType);
1149 @SuppressWarnings("unchecked")
1150 private Map<String, Object> getSubstitutableAsNodeTypeFromTemplate(final Map<String, Object> mappedToscaTemplate,
1151 final String substitutableAsNodeType) {
1152 return (Map<String, Object>) getAllNodeTypesInTemplate(mappedToscaTemplate).get(substitutableAsNodeType);
1155 private Map<String, Object> getAllNodeTypesInTemplate(final Map<String, Object> mappedToscaTemplate) {
1156 return ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES).left().orValue(HashMap::new);
1159 private void createModel(final Resource resource, final String vfResourcename) {
1160 final String nameForGeneratedModel = resource.getModel() + "_" + vfResourcename + resource.getCsarVersion();
1161 Model model = new Model(nameForGeneratedModel, resource.getModel(), ModelTypeEnum.NORMATIVE_EXTENSION);
1162 modelBusinessLogic.createModel(model);
1163 resource.setModel(nameForGeneratedModel);
1166 private Map<String, Object> getDatatypesToCreate(final String model, final Map<String, Object> dataTypes) {
1167 final Map<String, Object> dataTypesToCreate = new HashMap<>();
1168 for (final String dataType : dataTypes.keySet()) {
1169 final Either<DataTypeDefinition, StorageOperationStatus> result =
1170 propertyOperation.getDataTypeByName(dataType, model);
1171 if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
1172 dataTypesToCreate.put(dataType, dataTypes.get(dataType));
1175 return dataTypesToCreate;
1178 private Map<String, Object> getPolicytypesToCreate(final String model, final Map<String, Object> policyTypes) {
1179 final Map<String, Object> policyTypesToCreate = new HashMap<>();
1180 for (final String policyType : policyTypes.keySet()) {
1181 final Either<PolicyTypeDefinition, StorageOperationStatus> result =
1182 policyTypeOperation.getLatestPolicyTypeByType(policyType, model);
1183 if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
1184 policyTypesToCreate.put(policyType, policyTypes.get(policyType));
1187 return policyTypesToCreate;
1190 private void createNodeTypes(String yamlName, Resource resource, boolean needLock,
1191 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
1192 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1193 Map<String, Object> mapToConvert, Map<String, Object> nodeTypes) {
1194 Iterator<Entry<String, Object>> nodesNameValueIter = nodeTypes.entrySet().iterator();
1195 Resource vfcCreated = null;
1196 while (nodesNameValueIter.hasNext()) {
1197 Entry<String, Object> nodeType = nodesNameValueIter.next();
1198 Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle =
1199 nodeTypesArtifactsToHandle == null || nodeTypesArtifactsToHandle.isEmpty() ? null : nodeTypesArtifactsToHandle.get(nodeType.getKey());
1200 if (nodeTypesInfo.containsKey(nodeType.getKey())) {
1201 log.trace("************* Going to handle nested vfc {}", nodeType.getKey());
1202 vfcCreated = handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
1204 log.trace("************* Finished to handle nested vfc {}", nodeType.getKey());
1205 } else if (csarInfo.getCreatedNodesToscaResourceNames() != null && !csarInfo.getCreatedNodesToscaResourceNames()
1206 .containsKey(nodeType.getKey())) {
1207 log.trace("************* Going to create node {}", nodeType.getKey());
1208 ImmutablePair<Resource, ActionStatus> resourceCreated = createNodeTypeResourceFromYaml(yamlName, nodeType, csarInfo.getModifier(),
1209 mapToConvert, resource, needLock, nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, true, csarInfo, true);
1210 log.debug("************* Finished to create node {}", nodeType.getKey());
1211 vfcCreated = resourceCreated.getLeft();
1212 csarInfo.getCreatedNodesToscaResourceNames().put(nodeType.getKey(), vfcCreated.getToscaResourceName());
1214 if (vfcCreated != null) {
1215 csarInfo.getCreatedNodes().put(nodeType.getKey(), vfcCreated);
1217 mapToConvert.remove(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName());
1221 private Resource handleNestedVfc(Resource resource, Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1222 List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1224 String yamlName = nodesInfo.get(nodeName).getTemplateFileName();
1225 Map<String, Object> nestedVfcJsonMap = nodesInfo.get(nodeName).getMappedToscaTemplate();
1226 log.debug("************* Going to create node types from yaml {}", yamlName);
1227 createResourcesFromYamlNodeTypesList(yamlName, resource, nestedVfcJsonMap, false, nodesArtifactsToHandle, createdArtifacts,
1228 Collections.emptyMap(), csarInfo, resource.getModel());
1229 log.debug("************* Finished to create node types from yaml {}", yamlName);
1230 if (nestedVfcJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE.getElementName())) {
1231 log.debug("************* Going to handle complex VFC from yaml {}", yamlName);
1232 resource = handleComplexVfc(resource, nodesArtifactsToHandle, createdArtifacts, nodesInfo, csarInfo, nodeName, yamlName);
1237 private Resource handleComplexVfc(final Resource resource,
1238 final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1239 final List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1240 final String nodeName, final String yamlName) {
1241 Resource oldComplexVfc = null;
1242 Resource newComplexVfc = buildValidComplexVfc(resource, csarInfo, nodeName, nodesInfo);
1243 Either<Resource, StorageOperationStatus> oldComplexVfcRes = toscaOperationFacade
1244 .getFullLatestComponentByToscaResourceName(newComplexVfc.getToscaResourceName());
1245 if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() == StorageOperationStatus.NOT_FOUND) {
1246 oldComplexVfcRes = toscaOperationFacade.getFullLatestComponentByToscaResourceName(
1247 buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getRight());
1249 if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() != StorageOperationStatus.NOT_FOUND) {
1250 log.debug("Failed to fetch previous complex VFC by tosca resource name {}. Status is {}. ", newComplexVfc.getToscaResourceName(),
1251 oldComplexVfcRes.right().value());
1252 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1253 } else if (oldComplexVfcRes.isLeft()) {
1254 log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
1255 final Either<Boolean, ResponseFormat> eitherValidation = validateNestedDerivedFromDuringUpdate(oldComplexVfcRes.left().value(),
1256 newComplexVfc, ValidationUtils.hasBeenCertified(oldComplexVfcRes.left().value().getVersion()));
1257 if (eitherValidation.isLeft()) {
1258 oldComplexVfc = oldComplexVfcRes.left().value();
1261 newComplexVfc = handleComplexVfc(nodesArtifactsToHandle, createdArtifacts, nodesInfo, csarInfo, nodeName, yamlName, oldComplexVfc,
1263 csarInfo.getCreatedNodesToscaResourceNames().put(nodeName, newComplexVfc.getToscaResourceName());
1264 final LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT,
1265 LifecycleChanceActionEnum.CREATE_FROM_CSAR);
1266 log.debug("Going to certify cvfc {}. ", newComplexVfc.getName());
1267 final Resource result = propagateStateToCertified(csarInfo.getModifier(), newComplexVfc, lifecycleChangeInfo, true, false, true);
1268 csarInfo.getCreatedNodes().put(nodeName, result);
1269 csarInfo.removeNodeFromQueue();
1273 private Resource handleComplexVfc(Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodesArtifactsToHandle,
1274 List<ArtifactDefinition> createdArtifacts, Map<String, NodeTypeInfo> nodesInfo, CsarInfo csarInfo,
1275 String nodeName, String yamlName, Resource oldComplexVfc, Resource newComplexVfc) {
1276 Resource handleComplexVfcRes;
1277 Map<String, Object> mappedToscaTemplate = nodesInfo.get(nodeName).getMappedToscaTemplate();
1278 String yamlContent = new String(csarInfo.getCsar().get(yamlName));
1279 Map<String, NodeTypeInfo> newNodeTypesInfo = nodesInfo.entrySet().stream().collect(toMap(Entry::getKey, e -> e.getValue().getUnmarkedCopy()));
1280 CsarInfo.markNestedVfc(mappedToscaTemplate, newNodeTypesInfo);
1281 if (oldComplexVfc == null) {
1282 handleComplexVfcRes = createResourceFromYaml(newComplexVfc, yamlContent, yamlName, newNodeTypesInfo, csarInfo, nodesArtifactsToHandle,
1283 false, true, nodeName);
1285 handleComplexVfcRes = updateResourceFromYaml(oldComplexVfc, newComplexVfc, AuditingActionEnum.UPDATE_RESOURCE_METADATA, createdArtifacts,
1286 yamlContent, yamlName, csarInfo, newNodeTypesInfo, nodesArtifactsToHandle, nodeName, true);
1288 return handleComplexVfcRes;
1291 private Resource buildValidComplexVfc(Resource resource, CsarInfo csarInfo, String nodeName, Map<String, NodeTypeInfo> nodesInfo) {
1292 Resource complexVfc = buildComplexVfcMetadata(resource, csarInfo, nodeName, nodesInfo);
1293 log.debug("************* Going to validate complex VFC from yaml {}", complexVfc.getName());
1294 csarInfo.addNodeToQueue(nodeName);
1295 return validateResourceBeforeCreate(complexVfc, csarInfo.getModifier(), AuditingActionEnum.IMPORT_RESOURCE, true, csarInfo);
1298 private String getNodeTypeActualName(final String nodeTypefullName, final String nodeTypeNamePrefix) {
1299 final String nameWithouNamespacePrefix = nodeTypefullName.substring(nodeTypeNamePrefix.length());
1300 final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
1301 if (findTypes.length > 1) {
1302 final String resourceType = findTypes[0];
1303 return nameWithouNamespacePrefix.substring(resourceType.length());
1305 return nameWithouNamespacePrefix;
1308 private ImmutablePair<Resource, ActionStatus> createNodeTypeResourceFromYaml(final String yamlName, final Entry<String, Object> nodeNameValue,
1309 User user, final Map<String, Object> mapToConvert,
1310 final Resource resourceVf, final boolean needLock,
1311 final Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
1312 final List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1313 final boolean forceCertificationAllowed, final CsarInfo csarInfo,
1314 final boolean isNested) {
1315 final UploadResourceInfo resourceMetaData = fillResourceMetadata(yamlName, resourceVf, nodeNameValue.getKey(), user);
1316 final String singleVfcYaml = buildNodeTypeYaml(nodeNameValue, mapToConvert, resourceMetaData.getResourceType(), csarInfo);
1317 user = validateUser(user, "CheckIn Resource", resourceVf, AuditingActionEnum.CHECKIN_RESOURCE, true);
1318 return createResourceFromNodeType(singleVfcYaml, resourceMetaData, user, true, needLock, nodeTypeArtifactsToHandle,
1319 nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeNameValue.getKey(), isNested);
1322 private String buildNodeTypeYaml(final Entry<String, Object> nodeNameValue, final Map<String, Object> mapToConvert, final String nodeResourceType,
1323 final CsarInfo csarInfo) {
1324 // We need to create a Yaml from each node_types in order to create
1326 // resource from each node type using import normative flow.
1327 final DumperOptions options = new DumperOptions();
1328 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
1329 final Yaml yaml = new Yaml(options);
1330 final Map<String, Object> node = new HashMap<>();
1331 node.put(buildNestedToscaResourceName(nodeResourceType, csarInfo.getVfResourceName(), nodeNameValue.getKey()).getLeft(),
1332 nodeNameValue.getValue());
1333 mapToConvert.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), node);
1334 return yaml.dumpAsMap(mapToConvert);
1337 public Boolean validateResourceCreationFromNodeType(Resource resource, User creator) {
1338 validateDerivedFromNotEmpty(creator, resource, AuditingActionEnum.CREATE_RESOURCE);
1342 public ImmutablePair<Resource, ActionStatus> createResourceFromNodeType(String nodeTypeYaml, UploadResourceInfo resourceMetaData, User creator,
1343 boolean isInTransaction, boolean needLock,
1344 Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
1345 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1346 boolean forceCertificationAllowed, CsarInfo csarInfo, String nodeName,
1348 LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT,
1349 LifecycleChanceActionEnum.CREATE_FROM_CSAR);
1350 Function<Resource, Boolean> validator = resource -> validateResourceCreationFromNodeType(resource, creator);
1351 return resourceImportManager
1352 .importCertifiedResource(nodeTypeYaml, resourceMetaData, creator, validator, lifecycleChangeInfo, isInTransaction, true, needLock,
1353 nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeName, isNested);
1357 * Validates if a given node type name has a valid prefix.
1359 * @param nodeName node name from definition file
1360 * @param definedResourceNamespaceList is a list of all node type name prefix allowed
1361 * @return a valid node type name prefix if it`s found
1363 public Optional<String> validateNodeTypeNamePrefix(final String nodeName, final List<String> definedResourceNamespaceList) {
1364 for (final String validNamespace : definedResourceNamespaceList) {
1365 if (nodeName.startsWith(validNamespace)) {
1366 return Optional.of(validNamespace);
1369 return Optional.empty();
1372 private List<String> getDefinedNodeTypeNamespaceList() {
1373 return ConfigurationManager.getConfigurationManager().getConfiguration().getDefinedResourceNamespace();
1376 private UploadResourceInfo fillResourceMetadata(final String yamlName, final Resource resourceVf, final String nodeName, final User user) {
1377 final UploadResourceInfo resourceMetaData = new UploadResourceInfo();
1378 final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeName);
1379 log.debug("Node type Name prefix {}", nodeTypeNamePrefix);
1380 if (!nodeName.startsWith(nodeTypeNamePrefix)) {
1381 log.debug("invalid nodeName:{} does not start with {}.", nodeName, getDefinedNodeTypeNamespaceList());
1382 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeName);
1384 final String actualName = this.getNodeTypeActualName(nodeName, nodeTypeNamePrefix);
1385 final String namePrefix = nodeName.replace(actualName, "");
1386 String resourceType = namePrefix.substring(nodeTypeNamePrefix.length());
1387 log.debug("initial namePrefix:{} resourceType {}. nodeName {} , actualName {} prefix {}", namePrefix, resourceType, nodeName, actualName,
1388 nodeTypeNamePrefix);
1389 // if we import from csar, the node_type name can be
1391 // org.openecomp.resource.abstract.node_name - in this case we always
1394 if (resourceType.equals(Constants.ABSTRACT)) {
1395 resourceType = ResourceTypeEnum.VFC.name().toLowerCase();
1397 if (!ResourceTypeEnum.containsIgnoreCase(resourceType)) {
1398 resourceType = ResourceTypeEnum.VFC.name().toLowerCase();
1401 if (!ResourceTypeEnum.containsName(resourceType.toUpperCase())) {
1402 log.debug("invalid resourceType:{} the type is not one of the valide types:{}.", resourceType.toUpperCase(), ResourceTypeEnum.values());
1403 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeName);
1406 resourceMetaData.setName(resourceVf.getSystemName() + actualName);
1407 // Setting type from name
1408 final String type = resourceType.toUpperCase();
1409 resourceMetaData.setResourceType(type);
1410 resourceMetaData.setDescription(ImportUtils.Constants.INNER_VFC_DESCRIPTION);
1411 resourceMetaData.setIcon(ImportUtils.Constants.DEFAULT_ICON);
1412 resourceMetaData.setContactId(user.getUserId());
1413 resourceMetaData.setVendorName(resourceVf.getVendorName());
1414 resourceMetaData.setVendorRelease(resourceVf.getVendorRelease());
1415 resourceMetaData.setModel(resourceVf.getModel());
1417 final List<String> tags = new ArrayList<>();
1418 tags.add(resourceMetaData.getName());
1419 resourceMetaData.setTags(tags);
1421 final CategoryDefinition category = new CategoryDefinition();
1422 category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME);
1423 final SubCategoryDefinition subCategory = new SubCategoryDefinition();
1424 subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY);
1425 category.addSubCategory(subCategory);
1426 final List<CategoryDefinition> categories = new ArrayList<>();
1427 categories.add(category);
1428 resourceMetaData.setCategories(categories);
1429 return resourceMetaData;
1432 private Resource buildComplexVfcMetadata(final Resource resourceVf, final CsarInfo csarInfo, final String nodeName,
1433 final Map<String, NodeTypeInfo> nodesInfo) {
1434 final Resource cvfc = new Resource();
1435 final NodeTypeInfo nodeTypeInfo = nodesInfo.get(nodeName);
1436 cvfc.setName(buildCvfcName(csarInfo.getVfResourceName(), nodeName));
1437 cvfc.setNormalizedName(ValidationUtils.normaliseComponentName(cvfc.getName()));
1438 cvfc.setSystemName(ValidationUtils.convertToSystemName(cvfc.getName()));
1439 cvfc.setResourceType(ResourceTypeEnum.CVFC);
1440 cvfc.setAbstract(true);
1441 cvfc.setDerivedFrom(nodeTypeInfo.getDerivedFrom());
1442 cvfc.setDescription(ImportUtils.Constants.CVFC_DESCRIPTION);
1443 cvfc.setIcon(ImportUtils.Constants.DEFAULT_ICON);
1444 cvfc.setContactId(csarInfo.getModifier().getUserId());
1445 cvfc.setCreatorUserId(csarInfo.getModifier().getUserId());
1446 cvfc.setVendorName(resourceVf.getVendorName());
1447 cvfc.setVendorRelease(resourceVf.getVendorRelease());
1448 cvfc.setModel(resourceVf.getModel());
1449 cvfc.setResourceVendorModelNumber(resourceVf.getResourceVendorModelNumber());
1450 cvfc.setToscaResourceName(buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getLeft());
1451 cvfc.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
1452 final List<String> tags = new ArrayList<>();
1453 tags.add(cvfc.getName());
1455 final CategoryDefinition category = new CategoryDefinition();
1456 category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME);
1457 SubCategoryDefinition subCategory = new SubCategoryDefinition();
1458 subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY);
1459 category.addSubCategory(subCategory);
1460 final List<CategoryDefinition> categories = new ArrayList<>();
1461 categories.add(category);
1462 cvfc.setCategories(categories);
1463 cvfc.setVersion(ImportUtils.Constants.FIRST_NON_CERTIFIED_VERSION);
1464 cvfc.setLifecycleState(ImportUtils.Constants.NORMATIVE_TYPE_LIFE_CYCLE_NOT_CERTIFIED_CHECKOUT);
1465 cvfc.setHighestVersion(ImportUtils.Constants.NORMATIVE_TYPE_HIGHEST_VERSION);
1469 private String buildCvfcName(final String resourceVfName, final String nodeName) {
1470 String nameWithouNamespacePrefix = nodeName.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length());
1471 String[] findTypes = nameWithouNamespacePrefix.split("\\.");
1472 String resourceType = findTypes[0];
1473 String resourceName = resourceVfName + "-" + nameWithouNamespacePrefix.substring(resourceType.length() + 1);
1474 return addCvfcSuffixToResourceName(resourceName);
1477 private Resource createResourceAndRIsFromYaml(final String yamlName, Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo,
1478 final AuditingActionEnum actionEnum, final boolean isNormative,
1479 final List<ArtifactDefinition> createdArtifacts, final String topologyTemplateYaml,
1480 final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo,
1481 final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1482 final boolean shouldLock, final boolean inTransaction, final String nodeName) {
1483 final List<ArtifactDefinition> nodeTypesNewCreatedArtifacts = new ArrayList<>();
1485 final Either<Boolean, ResponseFormat> lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE);
1486 if (lockResult.isRight()) {
1487 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1488 throw new ByResponseFormatComponentException(lockResult.right().value());
1490 log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult);
1493 log.trace("************* createResourceFromYaml before full create resource {}", yamlName);
1494 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1495 "Starting to add inputs from yaml: {}", yamlName);
1496 if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
1497 final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
1498 (Map<String, Object>) new Yaml().load(topologyTemplateYaml), parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1499 resource.setToscaResourceName(parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1500 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
1501 (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
1502 resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
1503 generatePropertiesFromGenericType(resource, genericResource);
1504 generatePropertiesFromNodeType(resource, substitutableAsNodeType);
1505 final String resourceId = resource.getUniqueId();
1506 resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
1507 UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
1509 createResourcePropertiesOnGraph(resource);
1510 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo, resource.getModel());
1512 if (MapUtils.isNotEmpty(instancesToCreate)) {
1513 log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName);
1514 loggerSupportability
1515 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1516 "Start create nodes, RI and Relations from yaml: {}", yamlName);
1517 resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
1518 nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName,
1519 parsedToscaYamlInfo.getSubstitutionMappingNodeType());
1522 final Resource genericResource = fetchAndSetDerivedFromGenericType(resource, null);
1523 resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
1524 log.trace("************* createResourceFromYaml after full create resource {}", yamlName);
1525 log.trace("************* Going to add inputs from yaml {}", yamlName);
1526 if (resource.shouldGenerateInputs()) {
1527 generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
1529 final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs();
1530 resource = createInputsOnResource(resource, inputs);
1532 log.trace("************* Finish to add inputs from yaml {}", yamlName);
1533 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1534 "Finish to add inputs from yaml: {}", yamlName);
1535 if (resource.getResourceType() == ResourceTypeEnum.PNF) {
1536 log.trace("************* Adding generic properties to PNF");
1537 resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties());
1538 log.trace("************* Adding software information to PNF");
1539 softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo);
1540 log.trace("************* Removing non-mano software information file from PNF");
1541 if (csarInfo.getSoftwareInformationPath().isPresent() && !softwareInformationBusinessLogic.removeSoftwareInformationFile(
1543 log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), "catalog-be",
1544 "Could not remove the software information file.");
1547 final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo);
1549 log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName);
1550 loggerSupportability
1551 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1552 "Start create nodes, RI and Relations from yaml: {}", yamlName);
1553 resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
1554 nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName, null);
1556 log.trace("************* Finished to create nodes, RI and Relation from yaml {}", yamlName);
1557 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1558 "Finished to create nodes, RI and Relation from yaml: {}", yamlName);
1559 // validate update vf module group names
1560 Optional<Map<String, GroupDefinition>> asdGroups = checkAndCreateAsdTypeVfModules(parsedToscaYamlInfo.getInstances());
1561 Map<String, GroupDefinition> parsedGroups = parsedToscaYamlInfo.getGroups();
1562 if (asdGroups.isPresent()) {
1563 parsedGroups.putAll(asdGroups.get());
1565 final Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic
1566 .validateUpdateVfGroupNames(parsedGroups, resource.getSystemName());
1567 if (validateUpdateVfGroupNamesRes.isRight()) {
1568 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1569 throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value());
1571 // add groups to resource
1572 final Map<String, GroupDefinition> groups;
1573 log.trace("************* Going to add groups from yaml {}", yamlName);
1574 loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1575 "Start to add groups from yaml: {}", yamlName);
1576 if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) {
1577 groups = validateUpdateVfGroupNamesRes.left().value();
1579 groups = parsedGroups;
1581 final Either<Resource, ResponseFormat> createGroupsOnResource = createGroupsOnResource(resource, groups);
1582 if (createGroupsOnResource.isRight()) {
1583 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1584 loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1585 "ERROR while adding groups from yaml: {}", yamlName);
1586 throw new ByResponseFormatComponentException(createGroupsOnResource.right().value());
1588 resource = createGroupsOnResource.left().value();
1589 log.trace("************* Finished to add groups from yaml {}", yamlName);
1590 loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1591 "Finished to add groups from yaml: {}", yamlName);
1592 log.trace("************* Going to add artifacts from yaml {}", yamlName);
1593 loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
1594 "Started to add artifacts from yaml: {}", yamlName);
1595 log.trace("************* Starting to add policies from yaml {}", yamlName);
1596 Map<String, PolicyDefinition> policies = parsedToscaYamlInfo.getPolicies();
1597 if (MapUtils.isNotEmpty(policies)) {
1598 resource = createPoliciesOnResource(resource, policies);
1600 log.trace("************* Finished to add policies from yaml {}", yamlName);
1601 final NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName,
1602 nodeTypesArtifactsToCreate);
1603 final Either<Resource, ResponseFormat> createArtifactsEither = createOrUpdateArtifacts(ArtifactOperationEnum.CREATE, createdArtifacts,
1604 yamlName, csarInfo, resource, nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock);
1605 if (createArtifactsEither.isRight()) {
1606 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1607 loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1608 "error happened {}", createArtifactsEither.right().value());
1609 throw new ByResponseFormatComponentException(createArtifactsEither.right().value());
1611 loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
1612 "Finished to add artifacts from yaml: " + resource.getToscaResourceName());
1613 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
1614 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, actionEnum);
1615 ASDCKpiApi.countCreatedResourcesKPI();
1617 } catch (final BusinessLogicException e) {
1618 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(),
1619 "An error has occurred during resource and resource instance creation", e);
1620 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1621 throw new ByResponseFormatComponentException(e.getResponseFormat());
1622 } catch (final ComponentException e) {
1623 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ResourceBusinessLogic.class.getName(),
1624 "An error has occurred during resource and resource instance creation", e);
1625 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1626 throw new ByResponseFormatComponentException(e.getResponseFormat());
1627 } catch (final Exception e) {
1628 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(),
1629 "An error has occurred during resource and resource instance creation", e);
1630 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
1631 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1633 if (!inTransaction) {
1634 janusGraphDao.commit();
1637 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
1642 private Optional<Map<String, GroupDefinition>> checkAndCreateAsdTypeVfModules(Map<String, UploadComponentInstanceInfo> instances) {
1643 Map<String, GroupDefinition> addAsdGroups = new HashMap<>();
1644 if (isNotEmpty(instances) || instances != null) {
1645 for (Map.Entry<String, UploadComponentInstanceInfo> instance : instances.entrySet()) {
1646 if (isNotEmpty(instance.getValue().getArtifacts()) || instance.getValue().getArtifacts() != null) {
1647 Map<String, UploadArtifactInfo> artifactsMap = instance.getValue().getArtifacts()
1648 .get(ToscaTagNamesEnum.ARTIFACTS.getElementName());
1649 if (isNotEmpty(artifactsMap) || artifactsMap != null) {
1650 for (Map.Entry<String, UploadArtifactInfo> artifact : artifactsMap.entrySet()) {
1651 if (artifact.getValue().getType().equals(Constants.ASD_DEPLOYMENT_ITEM)) {
1652 GroupDefinition groupDefinition = new GroupDefinition();
1653 groupDefinition.setName(artifact.getKey());
1654 groupDefinition.setType(Constants.DEFAULT_GROUP_VF_MODULE);
1655 addAsdTypeProperties(groupDefinition);
1656 addAsdGroups.put(groupDefinition.getName(), groupDefinition);
1663 return Optional.of(addAsdGroups);
1666 private void addAsdTypeProperties(GroupDefinition groupDefinition) {
1667 List<GroupProperty> properties = new ArrayList<>();
1668 GroupProperty propIsBase = new GroupProperty();
1669 propIsBase.setName(Constants.IS_BASE);
1670 propIsBase.setValue("true");
1671 properties.add(propIsBase);
1672 GroupProperty propVfModuleLabel = new GroupProperty();
1673 propVfModuleLabel.setName(Constants.VF_MODULE_LABEL);
1674 propVfModuleLabel.setValue(groupDefinition.getName());
1675 properties.add(propVfModuleLabel);
1676 GroupProperty propVfModuleDescription = new GroupProperty();
1677 propVfModuleDescription.setName(Constants.VF_MODULE_DESCRIPTION);
1678 propVfModuleDescription.setValue("VF Module representing deployment item " + groupDefinition.getName());
1679 properties.add(propVfModuleDescription);
1680 GroupProperty propMinVfModuleInstances = new GroupProperty();
1681 propMinVfModuleInstances.setName(Constants.MIN_VF_MODULE_INSTANCES);
1682 propMinVfModuleInstances.setValue("1");
1683 properties.add(propMinVfModuleInstances);
1684 GroupProperty propMaxVfModuleInstances = new GroupProperty();
1685 propMaxVfModuleInstances.setName(Constants.MAX_VF_MODULE_INSTANCES);
1686 propMaxVfModuleInstances.setValue("1");
1687 properties.add(propMaxVfModuleInstances);
1688 GroupProperty propInitialCount = new GroupProperty();
1689 propInitialCount.setName(Constants.INITIAL_COUNT);
1690 propInitialCount.setValue("1");
1691 properties.add(propInitialCount);
1692 GroupProperty propVfModuleType = new GroupProperty();
1693 propVfModuleType.setName(Constants.VF_MODULE_TYPE);
1694 propVfModuleType.setValue("Base");
1695 properties.add(propVfModuleType);
1696 GroupProperty propVolumeGroup = new GroupProperty();
1697 propVolumeGroup.setName(Constants.VOLUME_GROUP);
1698 propVolumeGroup.setValue("false");
1699 properties.add(propVolumeGroup);
1700 groupDefinition.convertFromGroupProperties(properties);
1703 private boolean processSubstitutableAsNodeType(final Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo) {
1704 return !resource.getResourceType().isAtomicType() && StringUtils.isNotEmpty(resource.getModel())
1705 && parsedToscaYamlInfo.getSubstitutionMappingNodeType() != null;
1708 private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo) {
1709 return getInstancesToCreate(parsedToscaYamlInfo, null);
1712 private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo, final String model) {
1713 if (StringUtils.isEmpty(model) || StringUtils.isEmpty(parsedToscaYamlInfo.getSubstitutionMappingNodeType())) {
1714 return parsedToscaYamlInfo.getInstances();
1716 return parsedToscaYamlInfo.getInstances().entrySet().stream()
1717 .filter(entry -> !parsedToscaYamlInfo.getSubstitutionMappingNodeType().equals(entry.getValue().getType()))
1718 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
1721 private void rollback(boolean inTransaction, Resource resource, List<ArtifactDefinition> createdArtifacts,
1722 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts) {
1723 if (!inTransaction) {
1724 janusGraphDao.rollback();
1726 if (isNotEmpty(createdArtifacts) && isNotEmpty(nodeTypesNewCreatedArtifacts)) {
1727 createdArtifacts.addAll(nodeTypesNewCreatedArtifacts);
1728 log.debug("Found {} newly created artifacts to deleted, the component name: {}", createdArtifacts.size(), resource.getName());
1732 private Resource getResourceWithGroups(String resourceId) {
1733 ComponentParametersView filter = new ComponentParametersView();
1734 filter.setIgnoreGroups(false);
1735 Either<Resource, StorageOperationStatus> updatedResource = toscaOperationFacade.getToscaElement(resourceId, filter);
1736 if (updatedResource.isRight()) {
1737 rollbackWithException(componentsUtils.convertFromStorageResponse(updatedResource.right().value()), resourceId);
1739 return updatedResource.left().value();
1742 private Either<Resource, ResponseFormat> createGroupsOnResource(Resource resource, Map<String, GroupDefinition> groups) {
1743 if (groups != null && !groups.isEmpty()) {
1744 List<GroupDefinition> groupsAsList = updateGroupsMembersUsingResource(groups, resource);
1745 handleGroupsProperties(resource, groups);
1746 fillGroupsFinalFields(groupsAsList);
1747 Either<List<GroupDefinition>, ResponseFormat> createGroups = groupBusinessLogic.createGroups(resource, groupsAsList, true);
1748 if (createGroups.isRight()) {
1749 return Either.right(createGroups.right().value());
1752 return Either.left(resource);
1755 private void handleGroupsProperties(Resource resource, Map<String, GroupDefinition> groups) {
1756 List<InputDefinition> inputs = resource.getInputs();
1757 if (MapUtils.isNotEmpty(groups)) {
1758 groups.values().stream().filter(g -> isNotEmpty(g.getProperties())).flatMap(g -> g.getProperties().stream())
1759 .forEach(p -> handleGetInputs(p, inputs));
1763 private Resource createPoliciesOnResource(Resource resource, Map<String, PolicyDefinition> policies) {
1764 policyBusinessLogic.createPolicies(resource, policies);
1768 private void handleGetInputs(PropertyDataDefinition property, List<InputDefinition> inputs) {
1769 if (isNotEmpty(property.getGetInputValues())) {
1770 if (inputs == null || inputs.isEmpty()) {
1771 log.debug("Failed to add property {} to group. Inputs list is empty ", property);
1772 rollbackWithException(ActionStatus.INPUTS_NOT_FOUND,
1773 property.getGetInputValues().stream().map(GetInputValueDataDefinition::getInputName).collect(toList()).toString());
1775 ListIterator<GetInputValueDataDefinition> getInputValuesIter = property.getGetInputValues().listIterator();
1776 while (getInputValuesIter.hasNext()) {
1777 GetInputValueDataDefinition getInput = getInputValuesIter.next();
1778 Either<InputDefinition, RuntimeException> inputEither = findInputByName(inputs, getInput);
1779 if (inputEither.isRight()) {
1780 throw inputEither.right().value();
1782 InputDefinition input = inputEither.left().value();
1783 getInput.setInputId(input.getUniqueId());
1784 if (getInput.getGetInputIndex() != null) {
1785 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
1786 Either<InputDefinition, RuntimeException> newInputEither = findInputByName(inputs, getInputIndex);
1787 if (newInputEither.isRight()) {
1788 throw newInputEither.right().value();
1790 InputDefinition newInput = newInputEither.left().value();
1791 getInputIndex.setInputId(newInput.getUniqueId());
1793 getInputValuesIter.add(getInputIndex);
1800 <T> Either<T, RuntimeException> rollbackWithEither(final ActionStatus actionStatus, final String... params) {
1801 return rollbackWithEither(janusGraphDao, actionStatus, params);
1804 private Either<InputDefinition, RuntimeException> findInputByName(List<InputDefinition> inputs, GetInputValueDataDefinition getInput) {
1805 final String inputName = getInput != null ? getInput.getInputName() : "";
1806 if (inputs == null || inputs.isEmpty()) {
1807 log.debug("#findInputByName - Inputs list is empty");
1808 return rollbackWithEither(ActionStatus.INPUTS_NOT_FOUND, inputName);
1810 Optional<InputDefinition> inputOpt = inputs.stream().filter(p -> p.getName().equals(inputName)).findFirst();
1811 if (inputOpt.isEmpty()) {
1812 log.debug("#findInputByName - Failed to find the input {} ", inputName);
1813 return rollbackWithEither(ActionStatus.INPUTS_NOT_FOUND, inputName);
1815 return Either.left(inputOpt.get());
1820 private void fillGroupsFinalFields(List<GroupDefinition> groupsAsList) {
1821 groupsAsList.forEach(groupDefinition -> {
1822 groupDefinition.setInvariantName(groupDefinition.getName());
1823 groupDefinition.setCreatedFrom(CreatedFrom.CSAR);
1827 private Resource updateGroupsOnResource(Resource resource, Map<String, GroupDefinition> groups) {
1828 if (isEmpty(groups)) {
1831 return updateOrCreateGroups(resource, groups);
1834 private Resource updateOrCreateGroups(Resource resource, Map<String, GroupDefinition> groups) {
1835 List<GroupDefinition> groupsFromResource = resource.getGroups();
1836 List<GroupDefinition> groupsAsList = updateGroupsMembersUsingResource(groups, resource);
1837 List<GroupDefinition> groupsToUpdate = new ArrayList<>();
1838 List<GroupDefinition> groupsToDelete = new ArrayList<>();
1839 List<GroupDefinition> groupsToCreate = new ArrayList<>();
1840 if (isNotEmpty(groupsFromResource)) {
1841 addGroupsToCreateOrUpdate(groupsFromResource, groupsAsList, groupsToUpdate, groupsToCreate);
1842 addGroupsToDelete(groupsFromResource, groupsAsList, groupsToDelete);
1844 groupsToCreate.addAll(groupsAsList);
1846 if (isNotEmpty(groupsToCreate)) {
1847 fillGroupsFinalFields(groupsToCreate);
1848 if (isNotEmpty(groupsFromResource)) {
1849 groupBusinessLogic.addGroups(resource, groupsToCreate, true).left().on(this::throwComponentException);
1851 groupBusinessLogic.createGroups(resource, groupsToCreate, true).left().on(this::throwComponentException);
1854 if (isNotEmpty(groupsToDelete)) {
1855 groupBusinessLogic.deleteGroups(resource, groupsToDelete).left().on(this::throwComponentException);
1857 if (isNotEmpty(groupsToUpdate)) {
1858 groupBusinessLogic.updateGroups(resource, groupsToUpdate, true).left().on(this::throwComponentException);
1863 private void addGroupsToDelete(List<GroupDefinition> groupsFromResource, List<GroupDefinition> groupsAsList,
1864 List<GroupDefinition> groupsToDelete) {
1865 for (GroupDefinition group : groupsFromResource) {
1866 Optional<GroupDefinition> op = groupsAsList.stream().filter(p -> p.getInvariantName().equalsIgnoreCase(group.getInvariantName()))
1868 if (op.isEmpty() && (group.getArtifacts() == null || group.getArtifacts().isEmpty())) {
1869 groupsToDelete.add(group);
1874 private void addGroupsToCreateOrUpdate(List<GroupDefinition> groupsFromResource, List<GroupDefinition> groupsAsList,
1875 List<GroupDefinition> groupsToUpdate, List<GroupDefinition> groupsToCreate) {
1876 for (GroupDefinition group : groupsAsList) {
1877 Optional<GroupDefinition> op = groupsFromResource.stream().filter(p -> p.getInvariantName().equalsIgnoreCase(group.getInvariantName()))
1879 if (op.isPresent()) {
1880 GroupDefinition groupToUpdate = op.get();
1881 groupToUpdate.setMembers(group.getMembers());
1882 groupToUpdate.setCapabilities(group.getCapabilities());
1883 groupToUpdate.setProperties(group.getProperties());
1884 groupsToUpdate.add(groupToUpdate);
1886 groupsToCreate.add(group);
1891 private Resource createInputsOnResource(Resource resource, Map<String, InputDefinition> inputs) {
1892 List<InputDefinition> resourceProperties = resource.getInputs();
1893 if (MapUtils.isNotEmpty(inputs) || isNotEmpty(resourceProperties)) {
1894 Either<List<InputDefinition>, ResponseFormat> createInputs = inputsBusinessLogic.createInputsInGraph(inputs, resource);
1895 if (createInputs.isRight()) {
1896 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
1897 "failed to add inputs from yaml: {}", createInputs.right().value());
1898 throw new ByResponseFormatComponentException(createInputs.right().value());
1900 resource.setInputs(createInputs.left().value());
1905 private Resource generatePropertiesFromNodeType(final Resource resource, final Map<String, Object> nodeType) {
1906 final Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils.getProperties(nodeType);
1907 if (properties.isLeft()) {
1908 final List<PropertyDefinition> propertiesList = new ArrayList<>();
1909 final Map<String, PropertyDefinition> value = properties.left().value();
1910 if (value != null) {
1911 for (Entry<String, PropertyDefinition> entry : value.entrySet()) {
1912 final String name = entry.getKey();
1913 final PropertyDefinition propertyDefinition = entry.getValue();
1914 propertyDefinition.setName(name);
1915 propertiesList.add(propertyDefinition);
1916 resource.getProperties().removeIf(p -> p.getName().equals(name));
1919 resource.getProperties().addAll(propertiesList);
1924 private Resource createResourcePropertiesOnGraph(final Resource resource) {
1925 final List<PropertyDefinition> resourceProperties = resource.getProperties();
1926 for (PropertyDefinition propertyDefinition : resourceProperties) {
1927 final Either<PropertyDefinition, StorageOperationStatus> addPropertyEither = toscaOperationFacade
1928 .addPropertyToComponent(propertyDefinition, resource);
1930 if (addPropertyEither.isRight()) {
1931 final String error = String.format("failed to add properties from yaml: %s", addPropertyEither.right().value());
1932 loggerSupportability.log(LoggerSupportabilityActions.CREATE_PROPERTIES, resource.getComponentMetadataForSupportLog(),
1935 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addPropertyEither.right().value()), error);
1941 private List<GroupDefinition> updateGroupsMembersUsingResource(Map<String, GroupDefinition> groups, Resource component) {
1942 List<GroupDefinition> result = new ArrayList<>();
1943 List<ComponentInstance> componentInstances = component.getComponentInstances();
1944 if (groups != null) {
1945 for (Entry<String, GroupDefinition> entry : groups.entrySet()) {
1946 String groupName = entry.getKey();
1947 GroupDefinition groupDefinition = entry.getValue();
1948 GroupDefinition updatedGroupDefinition = new GroupDefinition(groupDefinition);
1950 updatedGroupDefinition.setMembers(null);
1951 Map<String, String> members = groupDefinition.getMembers();
1952 if (members != null) {
1953 updateGroupMembers(groups, updatedGroupDefinition, component, componentInstances, groupName, members);
1955 result.add(updatedGroupDefinition);
1961 private void updateGroupMembers(Map<String, GroupDefinition> groups, GroupDefinition updatedGroupDefinition, Resource component,
1962 List<ComponentInstance> componentInstances, String groupName, Map<String, String> members) {
1963 Set<String> compInstancesNames = members.keySet();
1964 if (CollectionUtils.isEmpty(componentInstances)) {
1965 String membersAstString = String.join(",", compInstancesNames);
1966 log.debug("The members: {}, in group: {}, cannot be found in component {}. There are no component instances.", membersAstString,
1967 groupName, component.getNormalizedName());
1968 throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1969 component.getNormalizedName(), getComponentTypeForResponse(component));
1971 // Find all component instances with the member names
1972 Map<String, String> memberNames = componentInstances.stream().collect(toMap(ComponentInstance::getName, ComponentInstance::getUniqueId));
1973 memberNames.putAll(groups.keySet().stream().collect(toMap(g -> g, g -> "")));
1974 Map<String, String> relevantInstances = memberNames.entrySet().stream().filter(n -> compInstancesNames.contains(n.getKey()))
1975 .collect(toMap(Entry::getKey, Entry::getValue));
1976 if (relevantInstances.size() != compInstancesNames.size()) {
1977 List<String> foundMembers = new ArrayList<>(relevantInstances.keySet());
1978 foundMembers.forEach(compInstancesNames::remove);
1979 String membersAstString = String.join(",", compInstancesNames);
1980 log.debug("The members: {}, in group: {}, cannot be found in component: {}", membersAstString, groupName, component.getNormalizedName());
1981 throw new ByActionStatusComponentException(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName,
1982 component.getNormalizedName(), getComponentTypeForResponse(component));
1984 updatedGroupDefinition.setMembers(relevantInstances);
1987 private Resource createRIAndRelationsFromYaml(String yamlName, Resource resource,
1988 Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap,
1989 String topologyTemplateYaml, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
1990 Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
1991 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
1992 String nodeName, final String substitutableAsNodeType) {
1993 log.debug("************* Going to create all nodes {}", yamlName);
1994 handleNodeTypes(yamlName, resource, topologyTemplateYaml, false, nodeTypesArtifactsToCreate, nodeTypesNewCreatedArtifacts, nodeTypesInfo,
1995 csarInfo, nodeName, substitutableAsNodeType);
1996 log.debug("************* Finished to create all nodes {}", yamlName);
1997 log.debug("************* Going to create all resource instances {}", yamlName);
1998 Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
1999 resource = createResourceInstances(yamlName, resource, null, uploadComponentInstanceInfoMap, csarInfo.getCreatedNodes(),
2000 existingNodeTypesByResourceNames);
2001 log.debug("************* Finished to create all resource instances {}", yamlName);
2002 log.debug("************* Going to create all relations {}", yamlName);
2003 resource = createResourceInstancesRelations(csarInfo.getModifier(), yamlName, resource, null, uploadComponentInstanceInfoMap,
2004 existingNodeTypesByResourceNames);
2005 log.debug("************* Finished to create all relations {}", yamlName);
2006 log.debug("************* Going to create positions {}", yamlName);
2007 compositionBusinessLogic.setPositionsForComponentInstances(resource, csarInfo.getModifier().getUserId());
2008 log.debug("************* Finished to set positions {}", yamlName);
2012 private void handleAndAddExtractedVfcsArtifacts(List<ArtifactDefinition> vfcArtifacts, List<ArtifactDefinition> artifactsToAdd) {
2013 List<String> vfcArtifactNames = vfcArtifacts.stream().map(ArtifactDataDefinition::getArtifactName).collect(toList());
2014 artifactsToAdd.forEach(a -> {
2015 if (!vfcArtifactNames.contains(a.getArtifactName())) {
2016 vfcArtifacts.add(a);
2018 log.debug("Can't upload two artifact with the same name {}. ", a.getArtifactName());
2023 @SuppressWarnings("unchecked")
2024 private void handleNodeTypes(String yamlName, Resource resource, String topologyTemplateYaml, boolean needLock,
2025 Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
2026 List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
2027 String nodeName, String substitutableAsNodeType) {
2029 for (Entry<String, NodeTypeInfo> nodeTypeEntry : nodeTypesInfo.entrySet()) {
2030 if (nodeTypeEntry.getValue().isNested() && !nodeTypeAlreadyExists(nodeTypeEntry.getKey(), resource.getModel())) {
2031 handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
2032 nodeTypeEntry.getKey());
2033 log.trace("************* finished to create node {}", nodeTypeEntry.getKey());
2036 Map<String, Object> mappedToscaTemplate = null;
2037 if (StringUtils.isNotEmpty(nodeName) && isNotEmpty(nodeTypesInfo) && nodeTypesInfo.containsKey(nodeName)) {
2038 mappedToscaTemplate = nodeTypesInfo.get(nodeName).getMappedToscaTemplate();
2040 if (isEmpty(mappedToscaTemplate)) {
2041 mappedToscaTemplate = (Map<String, Object>) new Yaml().load(topologyTemplateYaml);
2043 createResourcesFromYamlNodeTypesList(yamlName, resource, mappedToscaTemplate, needLock, nodeTypesArtifactsToHandle,
2044 nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, substitutableAsNodeType);
2045 } catch (ComponentException e) {
2046 ResponseFormat responseFormat =
2047 e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2048 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2050 } catch (StorageException e) {
2051 ResponseFormat responseFormat = componentsUtils
2052 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
2053 componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.IMPORT_RESOURCE);
2058 private boolean nodeTypeAlreadyExists(final String toscaResourceName, String modelName) {
2059 return toscaOperationFacade.getLatestByToscaResourceName(toscaResourceName, modelName).isLeft();
2062 private Either<Resource, ResponseFormat> handleVfCsarArtifacts(Resource resource, CsarInfo csarInfo, List<ArtifactDefinition> createdArtifacts,
2063 ArtifactOperationInfo artifactOperation, boolean shouldLock,
2064 boolean inTransaction) {
2065 if (csarInfo.getCsar() != null) {
2066 String vendorLicenseModelId = null;
2067 String vfLicenseModelId = null;
2068 if (artifactOperation.isUpdate()) {
2069 Map<String, ArtifactDefinition> deploymentArtifactsMap = resource.getDeploymentArtifacts();
2070 if (deploymentArtifactsMap != null && !deploymentArtifactsMap.isEmpty()) {
2071 for (Entry<String, ArtifactDefinition> artifactEntry : deploymentArtifactsMap.entrySet()) {
2072 if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VENDOR_LICENSE_MODEL)) {
2073 vendorLicenseModelId = artifactEntry.getValue().getUniqueId();
2075 if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VF_LICENSE_MODEL)) {
2076 vfLicenseModelId = artifactEntry.getValue().getUniqueId();
2081 // Specific Behavior for license artifacts
2082 createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VENDOR_LICENSE_MODEL,
2083 Constants.VENDOR_LICENSE_MODEL, ArtifactTypeEnum.VENDOR_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT,
2084 Constants.VENDOR_LICENSE_LABEL, Constants.VENDOR_LICENSE_DISPLAY_NAME, Constants.VENDOR_LICENSE_DESCRIPTION, vendorLicenseModelId,
2085 artifactOperation, null, true, shouldLock, inTransaction);
2086 createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VF_LICENSE_MODEL,
2087 Constants.VF_LICENSE_MODEL, ArtifactTypeEnum.VF_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT,
2088 Constants.VF_LICENSE_LABEL, Constants.VF_LICENSE_DISPLAY_NAME, Constants.VF_LICENSE_DESCRIPTION, vfLicenseModelId,
2089 artifactOperation, null, true, shouldLock, inTransaction);
2090 Either<Resource, ResponseFormat> eitherCreateResult
2091 = createOrUpdateNonMetaArtifacts(csarInfo, resource, createdArtifacts, shouldLock, inTransaction, artifactOperation);
2092 if (eitherCreateResult.isRight()) {
2093 return Either.right(eitherCreateResult.right().value());
2095 Either<ImmutablePair<String, String>, ResponseFormat> artifacsMetaCsarStatus = CsarValidationUtils
2096 .getArtifactsMeta(csarInfo.getCsar(), csarInfo.getCsarUUID(), componentsUtils);
2097 if (artifacsMetaCsarStatus.isLeft()) {
2098 String artifactsFileName = artifacsMetaCsarStatus.left().value().getKey();
2099 String artifactsContents = artifacsMetaCsarStatus.left().value().getValue();
2100 Either<Resource, ResponseFormat> createArtifactsFromCsar;
2101 if (artifactOperation.isCreateOrLink()) {
2102 createArtifactsFromCsar = csarArtifactsAndGroupsBusinessLogic
2103 .createResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts);
2105 Either<Component, ResponseFormat> result = csarArtifactsAndGroupsBusinessLogic
2106 .updateResourceArtifactsFromCsar(csarInfo, resource, artifactsContents, artifactsFileName, createdArtifacts, shouldLock,
2108 if ((result.left().value() instanceof Resource) && result.isLeft()) {
2109 Resource service1 = (Resource) result.left().value();
2110 createArtifactsFromCsar = Either.left(service1);
2112 createArtifactsFromCsar = Either.right(result.right().value());
2115 if (createArtifactsFromCsar.isRight()) {
2116 log.debug("Couldn't create artifacts from artifacts.meta");
2117 return Either.right(createArtifactsFromCsar.right().value());
2119 return Either.left(createArtifactsFromCsar.left().value());
2122 return Either.left(resource);
2125 private Either<Boolean, ResponseFormat> createOrUpdateSingleNonMetaArtifact(Resource resource, CsarInfo csarInfo, String artifactPath,
2126 String artifactFileName, String artifactType,
2127 ArtifactGroupTypeEnum artifactGroupType, String artifactLabel,
2128 String artifactDisplayName, String artifactDescription,
2129 String artifactId, ArtifactOperationInfo operation,
2130 List<ArtifactDefinition> createdArtifacts, boolean isFromCsar,
2131 boolean shouldLock, boolean inTransaction) {
2132 byte[] artifactFileBytes = null;
2133 if (csarInfo.getCsar().containsKey(artifactPath)) {
2134 artifactFileBytes = csarInfo.getCsar().get(artifactPath);
2136 Either<Boolean, ResponseFormat> result = Either.left(true);
2137 if (operation.isUpdate() || operation.isDelete()) {
2138 if (isArtifactDeletionRequired(artifactId, artifactFileBytes, isFromCsar)) {
2139 Either<ArtifactDefinition, ResponseFormat> handleDelete = artifactsBusinessLogic
2140 .handleDelete(resource.getUniqueId(), artifactId, csarInfo.getModifier(), resource, shouldLock, inTransaction);
2141 if (handleDelete.isRight()) {
2142 result = Either.right(handleDelete.right().value());
2144 ArtifactDefinition value = handleDelete.left().value();
2145 String updatedArtifactId = value.getUniqueId();
2146 if (artifactGroupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
2147 resource.getDeploymentArtifacts().remove(updatedArtifactId);
2149 resource.getArtifacts().remove(updatedArtifactId);
2154 if (StringUtils.isEmpty(artifactId) && artifactFileBytes != null) {
2155 operation = new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE);
2158 if (artifactFileBytes != null) {
2159 Map<String, Object> vendorLicenseModelJson = ArtifactUtils
2160 .buildJsonForUpdateArtifact(artifactId, artifactFileName, artifactType, artifactGroupType, artifactLabel, artifactDisplayName,
2161 artifactDescription, artifactFileBytes, null, isFromCsar);
2162 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts = csarArtifactsAndGroupsBusinessLogic
2163 .createOrUpdateCsarArtifactFromJson(resource, csarInfo.getModifier(), vendorLicenseModelJson, operation);
2164 addNonMetaCreatedArtifactsToSupportRollback(operation, createdArtifacts, eitherNonMetaArtifacts);
2165 if (eitherNonMetaArtifacts.isRight()) {
2166 BeEcompErrorManager.getInstance().logInternalFlowError("UploadLicenseArtifact",
2167 "Failed to upload license artifact: " + artifactFileName + "With csar uuid: " + csarInfo.getCsarUUID(), ErrorSeverity.WARNING);
2168 return Either.right(eitherNonMetaArtifacts.right().value());
2170 ArtifactDefinition artifactDefinition = eitherNonMetaArtifacts.left().value().left().value();
2171 createOrUpdateResourceWithUpdatedArtifact(artifactDefinition, resource, artifactGroupType);
2176 private void createOrUpdateResourceWithUpdatedArtifact(ArtifactDefinition artifact, Resource resource, ArtifactGroupTypeEnum groupTypeEnum) {
2177 if (groupTypeEnum == ArtifactGroupTypeEnum.DEPLOYMENT) {
2178 resource.getDeploymentArtifacts().put(artifact.getArtifactLabel(), artifact);
2180 resource.getArtifacts().put(artifact.getArtifactLabel(), artifact);
2184 private boolean isArtifactDeletionRequired(String artifactId, byte[] artifactFileBytes, boolean isFromCsar) {
2185 return !StringUtils.isEmpty(artifactId) && artifactFileBytes == null && isFromCsar;
2188 private void addNonMetaCreatedArtifactsToSupportRollback(ArtifactOperationInfo operation, List<ArtifactDefinition> createdArtifacts,
2189 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> eitherNonMetaArtifacts) {
2190 if (operation.isCreateOrLink() && createdArtifacts != null && eitherNonMetaArtifacts.isLeft()) {
2191 Either<ArtifactDefinition, Operation> eitherResult = eitherNonMetaArtifacts.left().value();
2192 if (eitherResult.isLeft()) {
2193 createdArtifacts.add(eitherResult.left().value());
2198 private Either<Resource, ResponseFormat> createOrUpdateNonMetaArtifacts(CsarInfo csarInfo, Resource resource,
2199 List<ArtifactDefinition> createdArtifacts, boolean shouldLock,
2200 boolean inTransaction, ArtifactOperationInfo artifactOperation) {
2201 Either<Resource, ResponseFormat> resStatus = null;
2202 Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
2204 Either<List<NonMetaArtifactInfo>, String> artifactPathAndNameList = getValidArtifactNames(csarInfo, collectedWarningMessages);
2205 if (artifactPathAndNameList.isRight()) {
2206 return Either.right(
2207 getComponentsUtils().getResponseFormatByArtifactId(ActionStatus.ARTIFACT_NAME_INVALID, artifactPathAndNameList.right().value(),
2208 VALID_CHARACTERS_ARTIFACT_NAME));
2210 EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle = null;
2211 if (artifactOperation.isCreateOrLink()) {
2212 vfCsarArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
2213 vfCsarArtifactsToHandle.put(artifactOperation.getArtifactOperationEnum(), artifactPathAndNameList.left().value());
2215 Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandleRes = findVfCsarArtifactsToHandle(
2216 resource, artifactPathAndNameList.left().value(), csarInfo.getModifier());
2217 if (findVfCsarArtifactsToHandleRes.isRight()) {
2218 resStatus = Either.right(findVfCsarArtifactsToHandleRes.right().value());
2220 if (resStatus == null) {
2221 vfCsarArtifactsToHandle = findVfCsarArtifactsToHandleRes.left().value();
2224 if (resStatus == null && vfCsarArtifactsToHandle != null) {
2225 resStatus = processCsarArtifacts(csarInfo, resource, createdArtifacts, shouldLock, inTransaction, resStatus, vfCsarArtifactsToHandle);
2227 if (resStatus == null) {
2228 resStatus = Either.left(resource);
2230 } catch (Exception e) {
2231 resStatus = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2232 log.debug("Exception occurred in createNonMetaArtifacts, message:{}", e.getMessage(), e);
2234 CsarUtils.handleWarningMessages(collectedWarningMessages);
2239 private Either<Resource, ResponseFormat> processCsarArtifacts(CsarInfo csarInfo, Resource resource, List<ArtifactDefinition> createdArtifacts,
2240 boolean shouldLock, boolean inTransaction,
2241 Either<Resource, ResponseFormat> resStatus,
2242 EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle) {
2243 for (Entry<ArtifactOperationEnum, List<NonMetaArtifactInfo>> currArtifactOperationPair : vfCsarArtifactsToHandle.entrySet()) {
2244 Optional<ResponseFormat> optionalCreateInDBError =
2245 // Stream of artifacts to be created
2246 currArtifactOperationPair.getValue().stream()
2247 // create each artifact
2248 .map(e -> createOrUpdateSingleNonMetaArtifact(resource, csarInfo, e.getPath(), e.getArtifactName(), e.getArtifactType(),
2249 e.getArtifactGroupType(), e.getArtifactLabel(), e.getDisplayName(), CsarUtils.ARTIFACT_CREATED_FROM_CSAR,
2250 e.getArtifactUniqueId(), new ArtifactOperationInfo(false, false, currArtifactOperationPair.getKey()), createdArtifacts,
2251 e.isFromCsar(), shouldLock, inTransaction))
2252 // filter in only error
2253 .filter(Either::isRight).
2254 // Convert the error from either to
2257 map(e -> e.right().value()).
2258 // Check if an error occurred
2260 // Error found on artifact Creation
2261 if (optionalCreateInDBError.isPresent()) {
2262 resStatus = Either.right(optionalCreateInDBError.get());
2269 private Either<List<NonMetaArtifactInfo>, String> getValidArtifactNames(CsarInfo csarInfo,
2270 Map<String, Set<List<String>>> collectedWarningMessages) {
2271 List<NonMetaArtifactInfo> artifactPathAndNameList =
2272 // Stream of file paths contained in csar
2273 csarInfo.getCsar().entrySet().stream()
2274 // Filter in only VF artifact path location
2275 .filter(e -> Pattern.compile(VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
2276 // Validate and add warnings
2277 .map(e -> CsarUtils.validateNonMetaArtifact(e.getKey(), e.getValue(), collectedWarningMessages))
2278 // Filter in Non Warnings
2279 .filter(Either::isLeft)
2280 // Convert from Either to NonMetaArtifactInfo
2281 .map(e -> e.left().value())
2284 Pattern englishNumbersAndUnderScoresOnly = Pattern.compile(CsarUtils.VALID_ENGLISH_ARTIFACT_NAME);
2285 for (NonMetaArtifactInfo nonMetaArtifactInfo : artifactPathAndNameList) {
2286 if (!englishNumbersAndUnderScoresOnly.matcher(nonMetaArtifactInfo.getDisplayName()).matches()) {
2287 return Either.right(nonMetaArtifactInfo.getArtifactName());
2290 return Either.left(artifactPathAndNameList);
2293 private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandle(Resource resource,
2294 List<NonMetaArtifactInfo> artifactPathAndNameList,
2296 List<ArtifactDefinition> existingArtifacts = new ArrayList<>();
2297 // collect all Deployment and Informational artifacts of VF
2298 if (resource.getDeploymentArtifacts() != null && !resource.getDeploymentArtifacts().isEmpty()) {
2299 existingArtifacts.addAll(resource.getDeploymentArtifacts().values());
2301 if (resource.getArtifacts() != null && !resource.getArtifacts().isEmpty()) {
2302 existingArtifacts.addAll(resource.getArtifacts().values());
2304 existingArtifacts = existingArtifacts.stream()
2305 // filter MANDATORY artifacts, LICENSE artifacts and artifacts
2307 // was created from HEAT.meta
2308 .filter(this::isNonMetaArtifact).collect(toList());
2309 List<String> artifactsToIgnore = new ArrayList<>();
2310 // collect IDs of Artifacts of VF which belongs to any group
2311 if (resource.getGroups() != null) {
2312 resource.getGroups().forEach(g -> {
2313 if (g.getArtifacts() != null && !g.getArtifacts().isEmpty()) {
2314 artifactsToIgnore.addAll(g.getArtifacts());
2318 existingArtifacts = existingArtifacts.stream()
2319 // filter artifacts which belongs to any group
2320 .filter(a -> !artifactsToIgnore.contains(a.getUniqueId())).collect(toList());
2321 return organizeVfCsarArtifactsByArtifactOperation(artifactPathAndNameList, existingArtifacts, resource, user);
2324 private boolean isNonMetaArtifact(ArtifactDefinition artifact) {
2325 return !artifact.getMandatory() && artifact.getArtifactName() != null && isValidArtifactType(artifact);
2328 private boolean isValidArtifactType(ArtifactDefinition artifact) {
2329 return artifact.getArtifactType() != null && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VENDOR_LICENSE
2330 && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VF_LICENSE;
2333 private Resource createResourceInstancesRelations(User user, String yamlName, Resource resource, Resource oldResource,
2334 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2335 Map<String, Resource> existingNodeTypesByResourceNames) {
2336 log.debug("#createResourceInstancesRelations - Going to create relations ");
2337 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2338 "Start to create relations");
2339 List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2340 if (isEmpty(uploadResInstancesMap) || CollectionUtils.isEmpty(componentInstancesList) &&
2341 resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances {
2342 log.debug("#createResourceInstancesRelations - No instances found in the resource {} is empty, yaml template file name {}, ",
2343 resource.getUniqueId(), yamlName);
2344 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2345 "No instances found in the resource: {}, is empty, yaml template file name: {}", resource.getName(), yamlName);
2346 BeEcompErrorManager.getInstance()
2347 .logInternalDataError("createResourceInstancesRelations", "No instances found in a resource or nn yaml template. ",
2348 ErrorSeverity.ERROR);
2349 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2351 Map<String, List<ComponentInstanceProperty>> instProperties = new HashMap<>();
2352 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities = new HashMap<>();
2353 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements = new HashMap<>();
2354 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts = new HashMap<>();
2355 Map<String, Map<String, ArtifactDefinition>> instArtifacts = new HashMap<>();
2356 Map<String, List<AttributeDefinition>> instAttributes = new HashMap<>();
2357 List<RequirementCapabilityRelDef> relations = new ArrayList<>();
2358 Map<String, List<ComponentInstanceInput>> instInputs = new HashMap<>();
2359 Resource finalResource = resource;
2360 uploadResInstancesMap.values().forEach(
2361 i -> processComponentInstance(yamlName, finalResource, componentInstancesList,
2362 componentsUtils.getAllDataTypes(applicationDataTypeCache, resource.getModel()), instProperties, instCapabilities,
2363 instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, existingNodeTypesByResourceNames, instInputs, i));
2364 resource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar()).forEach(
2365 i -> processUiComponentInstance(oldResource, i, instCapabilities, instRequirements, instDeploymentArtifacts, instArtifacts,
2366 instProperties, instInputs, instAttributes));
2367 associateComponentInstancePropertiesToComponent(yamlName, resource, instProperties);
2368 associateComponentInstanceInputsToComponent(yamlName, resource, instInputs);
2369 associateDeploymentArtifactsToInstances(user, yamlName, resource, instDeploymentArtifacts);
2370 associateArtifactsToInstances(yamlName, resource, instArtifacts);
2371 associateOrAddCalculatedCapReq(yamlName, resource, instCapabilities, instRequirements);
2372 associateInstAttributeToComponentToInstances(yamlName, resource, instAttributes);
2373 addRelationsToRI(yamlName, resource, uploadResInstancesMap, componentInstancesList, relations);
2374 associateResourceInstances(yamlName, resource, relations);
2375 handleSubstitutionMappings(resource, uploadResInstancesMap);
2376 log.debug("************* in create relations, getResource start");
2377 loggerSupportability
2378 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, "create relations");
2379 Either<Resource, StorageOperationStatus> eitherGetResource = toscaOperationFacade.getToscaFullElement(resource.getUniqueId());
2380 log.debug("************* in create relations, getResource end");
2381 if (eitherGetResource.isRight()) {
2382 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2383 "ERROR while create relations");
2384 throw new ByResponseFormatComponentException(
2385 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGetResource.right().value()), resource));
2387 return eitherGetResource.left().value();
2390 private void processUiComponentInstance(Resource oldResource, ComponentInstance instance,
2391 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2392 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2393 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2394 Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2395 Map<String, List<ComponentInstanceProperty>> instProperties,
2396 Map<String, List<ComponentInstanceInput>> instInputs,
2397 Map<String, List<AttributeDefinition>> instAttributes) {
2398 Optional<ComponentInstance> foundInstance = findInstance(oldResource, instance);
2399 if (foundInstance.isPresent()) {
2400 if (MapUtils.isNotEmpty(foundInstance.get().getCapabilities())) {
2401 instCapabilities.put(instance, foundInstance.get().getCapabilities());
2403 if (MapUtils.isNotEmpty(foundInstance.get().getRequirements())) {
2404 instRequirements.put(instance, foundInstance.get().getRequirements());
2406 if (MapUtils.isNotEmpty(foundInstance.get().getDeploymentArtifacts())) {
2407 instDeploymentArtifacts.put(instance.getUniqueId(), foundInstance.get().getDeploymentArtifacts());
2409 if (MapUtils.isNotEmpty(foundInstance.get().getArtifacts())) {
2410 instArtifacts.put(instance.getUniqueId(), foundInstance.get().getArtifacts());
2412 if (MapUtils.isNotEmpty(oldResource.getComponentInstancesProperties()) && CollectionUtils
2413 .isNotEmpty(oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()))) {
2414 instProperties.put(instance.getUniqueId(), oldResource.getComponentInstancesProperties().get(foundInstance.get().getUniqueId()));
2416 if (MapUtils.isNotEmpty(oldResource.getComponentInstancesInputs()) && CollectionUtils
2417 .isNotEmpty(oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()))) {
2418 instInputs.put(instance.getUniqueId(), oldResource.getComponentInstancesInputs().get(foundInstance.get().getUniqueId()));
2420 if (MapUtils.isNotEmpty(oldResource.getComponentInstancesAttributes()) && CollectionUtils
2421 .isNotEmpty(oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()))) {
2422 instAttributes.put(instance.getUniqueId(),
2423 oldResource.getComponentInstancesAttributes().get(foundInstance.get().getUniqueId()).stream().map(AttributeDefinition::new)
2424 .collect(toList()));
2429 private Optional<ComponentInstance> findInstance(Resource oldResource, ComponentInstance instance) {
2430 if (oldResource != null && CollectionUtils.isNotEmpty(oldResource.getComponentInstances())) {
2431 return oldResource.getComponentInstances().stream().filter(i -> i.getName().equals(instance.getName())).findFirst();
2433 return Optional.empty();
2436 private void associateResourceInstances(String yamlName, Resource resource, List<RequirementCapabilityRelDef> relations) {
2437 Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> relationsEither = toscaOperationFacade
2438 .associateResourceInstances(resource, resource.getUniqueId(), relations);
2439 if (relationsEither.isRight() && relationsEither.right().value() != StorageOperationStatus.NOT_FOUND) {
2440 StorageOperationStatus status = relationsEither.right().value();
2441 log.debug("failed to associate instances of resource {} status is {}", resource.getUniqueId(), status);
2442 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), yamlName);
2444 setResourceInstanceRelationsOnComponent(resource, relationsEither.left().value());
2448 private void associateInstAttributeToComponentToInstances(String yamlName, Resource resource,
2449 Map<String, List<AttributeDefinition>> instAttributes) {
2450 StorageOperationStatus addArtToInst;
2451 addArtToInst = toscaOperationFacade.associateInstAttributeToComponentToInstances(instAttributes, resource);
2452 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2453 log.debug("failed to associate attributes of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2454 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2458 private void associateOrAddCalculatedCapReq(String yamlName, Resource resource,
2459 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilities,
2460 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements) {
2461 StorageOperationStatus addArtToInst;
2462 addArtToInst = toscaOperationFacade.associateOrAddCalculatedCapReq(instCapabilities, instRequirements, resource);
2463 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2464 log.debug("failed to associate cap and req of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2465 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2469 private void associateArtifactsToInstances(String yamlName, Resource resource, Map<String, Map<String, ArtifactDefinition>> instArtifacts) {
2470 StorageOperationStatus addArtToInst;
2471 addArtToInst = toscaOperationFacade.associateArtifactsToInstances(instArtifacts, resource);
2472 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2473 log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2474 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2478 private void associateDeploymentArtifactsToInstances(User user, String yamlName, Resource resource,
2479 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts) {
2480 StorageOperationStatus addArtToInst = toscaOperationFacade.associateDeploymentArtifactsToInstances(instDeploymentArtifacts, resource, user);
2481 if (addArtToInst != StorageOperationStatus.OK && addArtToInst != StorageOperationStatus.NOT_FOUND) {
2482 log.debug("failed to associate artifact of resource {} status is {}", resource.getUniqueId(), addArtToInst);
2483 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addArtToInst), yamlName);
2487 private void associateComponentInstanceInputsToComponent(String yamlName, Resource resource,
2488 Map<String, List<ComponentInstanceInput>> instInputs) {
2489 if (MapUtils.isNotEmpty(instInputs)) {
2490 Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addInputToInst = toscaOperationFacade
2491 .associateComponentInstanceInputsToComponent(instInputs, resource.getUniqueId());
2492 if (addInputToInst.isRight()) {
2493 StorageOperationStatus addInputToInstError = addInputToInst.right().value();
2494 log.debug("failed to associate inputs value of resource {} status is {}", resource.getUniqueId(), addInputToInstError);
2495 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addInputToInstError), yamlName);
2497 setComponentInstanceInputsOnComponent(resource, instInputs);
2501 private void setComponentInstanceInputsOnComponent(Resource resource, Map<String, List<ComponentInstanceInput>> instInputs) {
2502 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = resource.getComponentInstancesInputs();
2503 if (componentInstancesInputs == null) {
2504 componentInstancesInputs = new HashMap<>();
2506 componentInstancesInputs.putAll(instInputs);
2507 resource.setComponentInstancesInputs(componentInstancesInputs);
2510 private void associateComponentInstancePropertiesToComponent(String yamlName, Resource resource,
2511 Map<String, List<ComponentInstanceProperty>> instProperties) {
2512 Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addPropToInst = toscaOperationFacade
2513 .associateComponentInstancePropertiesToComponent(instProperties, resource.getUniqueId());
2514 if (addPropToInst.isRight()) {
2515 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2516 "ERROR while associate compnent insatnce properties of resource: {} status is: {}", resource.getName(),
2517 addPropToInst.right().value());
2518 StorageOperationStatus storageOperationStatus = addPropToInst.right().value();
2519 log.debug("failed to associate properties of resource {} status is {}", resource.getUniqueId(), storageOperationStatus);
2520 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageOperationStatus), yamlName);
2522 setComponentInstancePropertiesOnComponent(resource, instProperties);
2525 private void setComponentInstancePropertiesOnComponent(Resource resource, Map<String, List<ComponentInstanceProperty>> instProperties) {
2526 Map<String, List<ComponentInstanceProperty>> componentInstanceProps = resource.getComponentInstancesProperties();
2527 if (componentInstanceProps == null) {
2528 componentInstanceProps = new HashMap<>();
2530 componentInstanceProps.putAll(instProperties);
2531 resource.setComponentInstancesProperties(componentInstanceProps);
2534 private void handleSubstitutionMappings(Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2535 Either<Resource, StorageOperationStatus> getResourceRes = null;
2536 if (resource.getResourceType() == ResourceTypeEnum.CVFC) {
2537 getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap);
2538 } else if (StringUtils.isNotEmpty(resource.getModel()) && resource.getResourceType() == ResourceTypeEnum.VF) {
2539 getResourceRes = updateCalculatedCapReqWithSubstitutionMappingsForVf(resource, uploadResInstancesMap);
2541 if (getResourceRes != null && getResourceRes.isRight()) {
2542 ResponseFormat responseFormat = componentsUtils
2543 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource);
2544 throw new ByResponseFormatComponentException(responseFormat);
2549 private void addRelationsToRI(String yamlName, Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2550 List<ComponentInstance> componentInstancesList, List<RequirementCapabilityRelDef> relations) {
2551 for (Entry<String, UploadComponentInstanceInfo> entry : uploadResInstancesMap.entrySet()) {
2552 UploadComponentInstanceInfo uploadComponentInstanceInfo = entry.getValue();
2553 ComponentInstance currentCompInstance = null;
2554 for (ComponentInstance compInstance : componentInstancesList) {
2555 if (compInstance.getName().equals(uploadComponentInstanceInfo.getName())) {
2556 currentCompInstance = compInstance;
2560 if (currentCompInstance == null) {
2561 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2562 BeEcompErrorManager.getInstance()
2563 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2564 ErrorSeverity.ERROR);
2565 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2567 ResponseFormat addRelationToRiRes = addRelationToRI(yamlName, resource, entry.getValue(), relations);
2568 if (addRelationToRiRes.getStatus() != 200) {
2569 throw new ByResponseFormatComponentException(addRelationToRiRes);
2574 private void setResourceInstanceRelationsOnComponent(Resource resource, List<RequirementCapabilityRelDef> relations) {
2575 if (resource.getComponentInstancesRelations() != null) {
2576 resource.getComponentInstancesRelations().addAll(relations);
2578 resource.setComponentInstancesRelations(relations);
2582 private void processComponentInstance(String yamlName, Resource resource, List<ComponentInstance> componentInstancesList,
2583 Map<String, DataTypeDefinition> allDataTypes,
2584 Map<String, List<ComponentInstanceProperty>> instProperties,
2585 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2586 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
2587 Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
2588 Map<String, Map<String, ArtifactDefinition>> instArtifacts,
2589 Map<String, List<AttributeDefinition>> instAttributes, Map<String, Resource> originCompMap,
2590 Map<String, List<ComponentInstanceInput>> instInputs,
2591 UploadComponentInstanceInfo uploadComponentInstanceInfo) {
2592 Optional<ComponentInstance> currentCompInstanceOpt = componentInstancesList.stream()
2593 .filter(i -> i.getName().equals(uploadComponentInstanceInfo.getName())).findFirst();
2594 if (currentCompInstanceOpt.isEmpty()) {
2595 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), resource.getUniqueId());
2596 BeEcompErrorManager.getInstance()
2597 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, resource.getUniqueId(),
2598 ErrorSeverity.ERROR);
2599 throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2601 ComponentInstance currentCompInstance = currentCompInstanceOpt.get();
2602 String resourceInstanceId = currentCompInstance.getUniqueId();
2603 Resource originResource = getOriginResource(originCompMap, currentCompInstance);
2604 if (isNotEmpty(originResource.getRequirements())) {
2605 instRequirements.put(currentCompInstance, originResource.getRequirements());
2607 if (isNotEmpty(originResource.getCapabilities())) {
2608 processComponentInstanceCapabilities(allDataTypes, instCapabilties, uploadComponentInstanceInfo, currentCompInstance, originResource);
2610 if (originResource.getDeploymentArtifacts() != null && !originResource.getDeploymentArtifacts().isEmpty()) {
2611 instDeploymentArtifacts.put(resourceInstanceId, originResource.getDeploymentArtifacts());
2613 if (originResource.getArtifacts() != null && !originResource.getArtifacts().isEmpty()) {
2614 instArtifacts.put(resourceInstanceId, originResource.getArtifacts());
2616 if (originResource.getAttributes() != null && !originResource.getAttributes().isEmpty()) {
2617 instAttributes.put(resourceInstanceId, originResource.getAttributes());
2619 if (originResource.getResourceType() != ResourceTypeEnum.CVFC) {
2620 ResponseFormat addPropertiesValueToRiRes = addPropertyValuesToRi(uploadComponentInstanceInfo, resource, originResource,
2621 currentCompInstance, instProperties, allDataTypes);
2622 if (addPropertiesValueToRiRes.getStatus() != 200) {
2623 throw new ByResponseFormatComponentException(addPropertiesValueToRiRes);
2626 addInputsValuesToRi(uploadComponentInstanceInfo, resource, originResource, currentCompInstance, instInputs, allDataTypes);
2630 private Resource getOriginResource(Map<String, Resource> originCompMap, ComponentInstance currentCompInstance) {
2631 Resource originResource;
2632 if (!originCompMap.containsKey(currentCompInstance.getComponentUid())) {
2633 Either<Resource, StorageOperationStatus> getOriginResourceRes = toscaOperationFacade
2634 .getToscaFullElement(currentCompInstance.getComponentUid());
2635 if (getOriginResourceRes.isRight()) {
2636 log.debug("failed to fetch resource with uniqueId {} and tosca component name {} status is {}", currentCompInstance.getComponentUid(),
2637 currentCompInstance.getToscaComponentName(), getOriginResourceRes);
2638 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getOriginResourceRes.right().value()),
2639 currentCompInstance.getComponentUid());
2641 originResource = getOriginResourceRes.left().value();
2642 originCompMap.put(originResource.getUniqueId(), originResource);
2644 originResource = originCompMap.get(currentCompInstance.getComponentUid());
2646 return originResource;
2649 private void processComponentInstanceCapabilities(Map<String, DataTypeDefinition> allDataTypes,
2650 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2651 UploadComponentInstanceInfo uploadComponentInstanceInfo, ComponentInstance currentCompInstance,
2652 Resource originResource) {
2653 Map<String, List<CapabilityDefinition>> originCapabilities;
2654 if (isNotEmpty(uploadComponentInstanceInfo.getCapabilities())) {
2655 originCapabilities = new HashMap<>();
2656 Map<String, Map<String, UploadPropInfo>> newPropertiesMap = new HashMap<>();
2657 originResource.getCapabilities().forEach((k, v) -> addCapabilities(originCapabilities, k, v));
2658 uploadComponentInstanceInfo.getCapabilities().values().forEach(l -> addCapabilitiesProperties(newPropertiesMap, l));
2659 updateCapabilityPropertiesValues(originCapabilities, newPropertiesMap, allDataTypes);
2661 originCapabilities = originResource.getCapabilities();
2663 instCapabilties.put(currentCompInstance, originCapabilities);
2666 private void updateCapabilityPropertiesValues(Map<String, List<CapabilityDefinition>> originCapabilities,
2667 Map<String, Map<String, UploadPropInfo>> newPropertiesMap,
2668 Map<String, DataTypeDefinition> allDataTypes) {
2669 originCapabilities.values().stream().flatMap(Collection::stream).filter(c -> newPropertiesMap.containsKey(c.getName()))
2670 .forEach(c -> updatePropertyValues(c.getProperties(), newPropertiesMap.get(c.getName()), allDataTypes));
2673 private void addCapabilitiesProperties(Map<String, Map<String, UploadPropInfo>> newPropertiesMap, List<UploadCapInfo> capabilities) {
2674 for (UploadCapInfo capability : capabilities) {
2675 if (isNotEmpty(capability.getProperties())) {
2676 newPropertiesMap.put(capability.getName(), capability.getProperties().stream().collect(toMap(UploadInfo::getName, p -> p)));
2681 private void addCapabilities(Map<String, List<CapabilityDefinition>> originCapabilities, String type, List<CapabilityDefinition> capabilities) {
2682 List<CapabilityDefinition> list = capabilities.stream().map(CapabilityDefinition::new).collect(toList());
2683 originCapabilities.put(type, list);
2686 private void updatePropertyValues(List<ComponentInstanceProperty> properties, Map<String, UploadPropInfo> newProperties,
2687 Map<String, DataTypeDefinition> allDataTypes) {
2688 properties.forEach(p -> updatePropertyValue(p, newProperties.get(p.getName()), allDataTypes));
2691 private String updatePropertyValue(ComponentInstanceProperty property, UploadPropInfo propertyInfo,
2692 Map<String, DataTypeDefinition> allDataTypes) {
2693 String value = null;
2694 List<GetInputValueDataDefinition> getInputs = null;
2695 boolean isValidate = true;
2696 if (null != propertyInfo && propertyInfo.getValue() != null) {
2697 getInputs = propertyInfo.getGet_input();
2698 isValidate = getInputs == null || getInputs.isEmpty();
2700 value = getPropertyJsonStringValue(propertyInfo.getValue(), property.getType());
2702 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
2705 property.setValue(value);
2706 return validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
2709 private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappings(Resource resource,
2710 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2711 Either<Resource, StorageOperationStatus> updateRes = null;
2712 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2713 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2715 StorageOperationStatus status = toscaOperationFacade.deleteAllCalculatedCapabilitiesRequirements(resource.getUniqueId());
2716 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2717 log.debug("Failed to delete all calculated capabilities and requirements of resource {} upon update. Status is {}",
2718 resource.getUniqueId(), status);
2719 updateRes = Either.right(status);
2721 if (updateRes == null) {
2722 fillUpdatedInstCapabilitiesRequirements(resource.getComponentInstances(), uploadResInstancesMap, updatedInstCapabilities,
2723 updatedInstRequirements);
2724 status = toscaOperationFacade.associateOrAddCalculatedCapReq(updatedInstCapabilities, updatedInstRequirements, resource);
2725 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2727 "Failed to associate capabilities and requirementss of resource {}, updated according to a substitution mapping. Status is {}",
2728 resource.getUniqueId(), status);
2729 updateRes = Either.right(status);
2732 if (updateRes == null) {
2733 updateRes = Either.left(resource);
2738 private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappingsForVf(final Resource resource,
2739 final Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
2740 Either<Resource, StorageOperationStatus> updateRes = null;
2741 final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
2742 final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
2744 resource.getComponentInstances().forEach(i -> {
2745 setExternalCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2746 setExternalRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2749 final StorageOperationStatus status = toscaOperationFacade.updateCalculatedCapabilitiesRequirements(updatedInstCapabilities,
2750 updatedInstRequirements, resource);
2751 if (status != StorageOperationStatus.OK) {
2753 "Failed to update capabilities and requirements of resource {}. Status is {}",
2754 resource.getUniqueId(), status);
2755 updateRes = Either.right(status);
2758 if (updateRes == null) {
2759 updateRes = Either.left(resource);
2764 private void fillUpdatedInstCapabilitiesRequirements(List<ComponentInstance> componentInstances,
2765 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
2766 Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities,
2767 Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements) {
2768 componentInstances.forEach(i -> {
2769 fillUpdatedInstCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
2770 fillUpdatedInstRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
2774 private void fillUpdatedInstRequirements(Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2775 ComponentInstance instance, Map<String, String> requirementsNamesToUpdate) {
2776 Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2777 Set<String> updatedReqNames = new HashSet<>();
2778 if (isNotEmpty(requirementsNamesToUpdate)) {
2779 for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2780 updatedRequirements.put(requirements.getKey(), requirements.getValue().stream().filter(
2781 r -> requirementsNamesToUpdate.containsKey(r.getName()) && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2783 r.setParentName(r.getName());
2784 r.setName(requirementsNamesToUpdate.get(r.getName()));
2785 updatedReqNames.add(r.getName());
2787 }).collect(toList()));
2790 if (isNotEmpty(updatedRequirements)) {
2791 updatedInstRequirements.put(instance, updatedRequirements);
2795 private void setExternalRequirements(
2796 final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
2797 final ComponentInstance instance, final Map<String, String> requirementsNamesToUpdate) {
2798 final Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
2799 final Set<String> updatedReqNames = new HashSet<>();
2800 if (isNotEmpty(requirementsNamesToUpdate)) {
2801 for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
2802 updatedRequirements.put(requirements.getKey(),
2803 requirements.getValue().stream()
2804 .filter(r -> requirementsNamesToUpdate.containsKey(r.getName())
2805 && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
2807 r.setExternal(true);
2808 r.setExternalName(requirementsNamesToUpdate.get(r.getName()));
2809 updatedReqNames.add(r.getName());
2811 }).collect(toList()));
2814 if (isNotEmpty(updatedRequirements)) {
2815 updatedInstRequirements.put(instance, updatedRequirements);
2819 private void setExternalCapabilities(
2820 final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2821 final ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2822 final Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2823 final Set<String> updatedCapNames = new HashSet<>();
2824 if (isNotEmpty(capabilitiesNamesToUpdate)) {
2825 for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2826 updatedCapabilities.put(requirements.getKey(),
2827 requirements.getValue().stream()
2828 .filter(c -> capabilitiesNamesToUpdate.containsKey(c.getName())
2829 && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2831 c.setExternal(true);
2832 c.setExternalName(capabilitiesNamesToUpdate.get(c.getName()));
2833 updatedCapNames.add(c.getName());
2835 }).collect(toList()));
2838 if (isNotEmpty(updatedCapabilities)) {
2839 updatedInstCapabilties.put(instance, updatedCapabilities);
2843 private void fillUpdatedInstCapabilities(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
2844 ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
2845 Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
2846 Set<String> updatedCapNames = new HashSet<>();
2847 if (isNotEmpty(capabilitiesNamesToUpdate)) {
2848 for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
2849 updatedCapabilities.put(requirements.getKey(), requirements.getValue().stream().filter(
2850 c -> capabilitiesNamesToUpdate.containsKey(c.getName()) && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
2852 c.setParentName(c.getName());
2853 c.setName(capabilitiesNamesToUpdate.get(c.getName()));
2854 updatedCapNames.add(c.getName());
2856 }).collect(toList()));
2859 if (isNotEmpty(updatedCapabilities)) {
2860 updatedInstCapabilties.put(instance, updatedCapabilities);
2864 private ResponseFormat addRelationToRI(String yamlName, Resource resource, UploadComponentInstanceInfo nodesInfoValue,
2865 List<RequirementCapabilityRelDef> relations) {
2866 List<ComponentInstance> componentInstancesList = resource.getComponentInstances();
2867 ComponentInstance currentCompInstance = null;
2868 for (ComponentInstance compInstance : componentInstancesList) {
2869 if (compInstance.getName().equals(nodesInfoValue.getName())) {
2870 currentCompInstance = compInstance;
2874 if (currentCompInstance == null) {
2875 log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, nodesInfoValue.getName(), resource.getUniqueId());
2876 BeEcompErrorManager.getInstance()
2877 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + nodesInfoValue.getName() + IN_RESOURCE, resource.getUniqueId(),
2878 ErrorSeverity.ERROR);
2879 return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2881 String resourceInstanceId = currentCompInstance.getUniqueId();
2882 Map<String, List<UploadReqInfo>> regMap = nodesInfoValue.getRequirements();
2883 if (regMap != null) {
2884 for (Entry<String, List<UploadReqInfo>> nodesRegInfoEntry : regMap.entrySet()) {
2885 List<UploadReqInfo> uploadRegInfoList = nodesRegInfoEntry.getValue();
2886 for (UploadReqInfo uploadRegInfo : uploadRegInfoList) {
2887 log.debug("Going to create relation {}", uploadRegInfo.getName());
2888 loggerSupportability
2889 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
2890 "Started to create relations on instance: {}", uploadRegInfo.getName());
2891 String regName = uploadRegInfo.getName();
2892 RequirementCapabilityRelDef regCapRelDef = new RequirementCapabilityRelDef();
2893 regCapRelDef.setFromNode(resourceInstanceId);
2894 log.debug("try to find available requirement {} ", regName);
2895 Either<RequirementDefinition, ResponseFormat> eitherReqStatus = findAviableRequiremen(regName, yamlName, nodesInfoValue,
2896 currentCompInstance, uploadRegInfo.getCapabilityName());
2897 if (eitherReqStatus.isRight()) {
2898 log.debug("failed to find available requirement {} status is {}", regName, eitherReqStatus.right().value());
2899 loggerSupportability
2900 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2901 "ERROR while search available requirement {} status is: {}", regName, eitherReqStatus.right().value());
2902 return eitherReqStatus.right().value();
2904 RequirementDefinition validReq = eitherReqStatus.left().value();
2905 List<CapabilityRequirementRelationship> reqAndRelationshipPairList = regCapRelDef.getRelationships();
2906 if (reqAndRelationshipPairList == null) {
2907 reqAndRelationshipPairList = new ArrayList<>();
2909 RelationshipInfo reqAndRelationshipPair = new RelationshipInfo();
2910 reqAndRelationshipPair.setRequirement(regName);
2911 reqAndRelationshipPair.setRequirementOwnerId(validReq.getOwnerId());
2912 reqAndRelationshipPair.setRequirementUid(validReq.getUniqueId());
2913 RelationshipImpl relationship = new RelationshipImpl();
2914 relationship.setType(validReq.getCapability());
2915 reqAndRelationshipPair.setRelationships(relationship);
2916 ComponentInstance currentCapCompInstance = null;
2917 for (ComponentInstance compInstance : componentInstancesList) {
2918 if (compInstance.getName().equals(uploadRegInfo.getNode())) {
2919 currentCapCompInstance = compInstance;
2923 if (currentCapCompInstance == null) {
2924 log.debug("The component instance with name {} not found on resource {} ", uploadRegInfo.getNode(), resource.getUniqueId());
2925 loggerSupportability
2926 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2927 "ERROR component instance with name: {} not found on resource: {}", uploadRegInfo.getNode(), resource.getUniqueId());
2928 BeEcompErrorManager.getInstance()
2929 .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadRegInfo.getNode() + IN_RESOURCE, resource.getUniqueId(),
2930 ErrorSeverity.ERROR);
2931 return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2933 regCapRelDef.setToNode(currentCapCompInstance.getUniqueId());
2934 log.debug("try to find aviable Capability req name is {} ", validReq.getName());
2935 CapabilityDefinition aviableCapForRel = findAvailableCapabilityByTypeOrName(validReq, currentCapCompInstance, uploadRegInfo);
2936 if (aviableCapForRel == null) {
2937 log.debug("aviable capability was not found. req name is {} component instance is {}", validReq.getName(),
2938 currentCapCompInstance.getUniqueId());
2939 loggerSupportability
2940 .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2941 "ERROR available capability was not found. req name is: {} component instance is: {}", validReq.getName(),
2942 currentCapCompInstance.getUniqueId());
2943 BeEcompErrorManager.getInstance().logInternalDataError(
2944 "aviable capability was not found. req name is " + validReq.getName() + " component instance is " + currentCapCompInstance
2945 .getUniqueId(), resource.getUniqueId(), ErrorSeverity.ERROR);
2946 return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
2948 reqAndRelationshipPair.setCapability(aviableCapForRel.getName());
2949 reqAndRelationshipPair.setCapabilityUid(aviableCapForRel.getUniqueId());
2950 reqAndRelationshipPair.setCapabilityOwnerId(aviableCapForRel.getOwnerId());
2951 CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
2952 capReqRel.setRelation(reqAndRelationshipPair);
2953 reqAndRelationshipPairList.add(capReqRel);
2954 regCapRelDef.setRelationships(reqAndRelationshipPairList);
2955 relations.add(regCapRelDef);
2958 } else if (resource.getResourceType() != ResourceTypeEnum.CVFC) {
2959 return componentsUtils.getResponseFormat(ActionStatus.OK, yamlName);
2961 return componentsUtils.getResponseFormat(ActionStatus.OK);
2964 private void addInputsValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
2965 ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceInput>> instInputs,
2966 Map<String, DataTypeDefinition> allDataTypes) {
2967 Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
2968 if (MapUtils.isNotEmpty(propMap)) {
2969 Map<String, InputDefinition> currPropertiesMap = new HashMap<>();
2970 List<ComponentInstanceInput> instPropList = new ArrayList<>();
2971 if (CollectionUtils.isEmpty(originResource.getInputs())) {
2972 log.debug("failed to find properties ");
2973 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2974 "ERROR while try to find properties");
2975 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND);
2977 originResource.getInputs().forEach(p -> addInput(currPropertiesMap, p));
2978 for (List<UploadPropInfo> propertyList : propMap.values()) {
2979 processProperty(resource, currentCompInstance, allDataTypes, currPropertiesMap, instPropList, propertyList);
2981 currPropertiesMap.values().forEach(p -> instPropList.add(new ComponentInstanceInput(p)));
2982 instInputs.put(currentCompInstance.getUniqueId(), instPropList);
2986 private void processProperty(Resource resource, ComponentInstance currentCompInstance, Map<String, DataTypeDefinition> allDataTypes,
2987 Map<String, InputDefinition> currPropertiesMap, List<ComponentInstanceInput> instPropList,
2988 List<UploadPropInfo> propertyList) {
2989 UploadPropInfo propertyInfo = propertyList.get(0);
2990 String propName = propertyInfo.getName();
2991 if (!currPropertiesMap.containsKey(propName)) {
2992 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
2993 "ERROR failed to find property: {}", propName);
2994 log.debug("failed to find property {} ", propName);
2995 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, propName);
2997 InputDefinition curPropertyDef = currPropertiesMap.get(propName);
2998 ComponentInstanceInput property = null;
2999 String value = null;
3000 List<GetInputValueDataDefinition> getInputs = null;
3001 boolean isValidate = true;
3002 if (propertyInfo.getValue() != null) {
3003 getInputs = propertyInfo.getGet_input();
3004 isValidate = getInputs == null || getInputs.isEmpty();
3006 value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3008 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3011 property = new ComponentInstanceInput(curPropertyDef, value, null);
3012 String validPropertyVAlue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3013 property.setValue(validPropertyVAlue);
3014 if (isNotEmpty(getInputs)) {
3015 List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3016 for (GetInputValueDataDefinition getInput : getInputs) {
3017 List<InputDefinition> inputs = resource.getInputs();
3018 if (CollectionUtils.isEmpty(inputs)) {
3019 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3020 "ERROR Failed to add property: " + propName + " to resource instance: {}. Inputs list is empty ",
3021 currentCompInstance.getUniqueId());
3022 log.debug("Failed to add property {} to resource instance {}. Inputs list is empty ", property,
3023 currentCompInstance.getUniqueId());
3024 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3026 Optional<InputDefinition> optional = inputs.stream().filter(p -> p.getName().equals(getInput.getInputName())).findAny();
3027 if (optional.isEmpty()) {
3028 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3029 "ERROR Failed to find input: " + getInput.getInputName());
3030 log.debug("Failed to find input {} ", getInput.getInputName());
3031 // @@TODO error message
3032 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3034 InputDefinition input = optional.get();
3035 getInput.setInputId(input.getUniqueId());
3036 getInputValues.add(getInput);
3037 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3038 processGetInput(getInputValues, inputs, getInputIndex);
3040 property.setGetInputValues(getInputValues);
3042 instPropList.add(property);
3043 // delete overriden property
3044 currPropertiesMap.remove(property.getName());
3047 private void processGetInput(List<GetInputValueDataDefinition> getInputValues, List<InputDefinition> inputs,
3048 GetInputValueDataDefinition getInputIndex) {
3049 Optional<InputDefinition> optional;
3050 if (getInputIndex != null) {
3051 optional = inputs.stream().filter(p -> p.getName().equals(getInputIndex.getInputName())).findAny();
3052 if (optional.isEmpty()) {
3053 log.debug("Failed to find input {} ", getInputIndex.getInputName());
3054 // @@TODO error message
3055 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
3057 InputDefinition inputIndex = optional.get();
3058 getInputIndex.setInputId(inputIndex.getUniqueId());
3059 getInputValues.add(getInputIndex);
3063 private void addInput(Map<String, InputDefinition> currPropertiesMap, InputDefinition prop) {
3064 String propName = prop.getName();
3065 if (!currPropertiesMap.containsKey(propName)) {
3066 currPropertiesMap.put(propName, prop);
3070 private ResponseFormat addPropertyValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, Resource originResource,
3071 ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceProperty>> instProperties,
3072 Map<String, DataTypeDefinition> allDataTypes) {
3073 Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties();
3074 Map<String, PropertyDefinition> currPropertiesMap = new HashMap<>();
3075 List<PropertyDefinition> listFromMap = originResource.getProperties();
3076 if ((propMap != null && !propMap.isEmpty()) && (listFromMap == null || listFromMap.isEmpty())) {
3077 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3078 "ERROR Failed to find properties");
3079 log.debug("failed to find properties");
3080 return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND);
3082 if (listFromMap == null || listFromMap.isEmpty()) {
3083 return componentsUtils.getResponseFormat(ActionStatus.OK);
3085 for (PropertyDefinition prop : listFromMap) {
3086 String propName = prop.getName();
3087 if (!currPropertiesMap.containsKey(propName)) {
3088 currPropertiesMap.put(propName, prop);
3091 List<ComponentInstanceProperty> instPropList = new ArrayList<>();
3092 if (propMap != null && propMap.size() > 0) {
3093 for (List<UploadPropInfo> propertyList : propMap.values()) {
3094 UploadPropInfo propertyInfo = propertyList.get(0);
3095 String propName = propertyInfo.getName();
3096 if (!currPropertiesMap.containsKey(propName)) {
3097 log.debug("failed to find property {} ", propName);
3098 loggerSupportability.log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3099 "ERROR Failed to find property: {}", propName);
3100 return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, propName);
3102 PropertyDefinition curPropertyDef = currPropertiesMap.get(propName);
3103 ComponentInstanceProperty property = null;
3104 String value = null;
3105 List<GetInputValueDataDefinition> getInputs = null;
3106 boolean isValidate = true;
3107 if (propertyInfo.getValue() != null) {
3108 getInputs = propertyInfo.getGet_input();
3109 isValidate = getInputs == null || getInputs.isEmpty();
3111 value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType());
3113 value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
3116 property = new ComponentInstanceProperty(curPropertyDef, value, null);
3117 String validatePropValue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
3118 property.setValue(validatePropValue);
3119 if (getInputs != null && !getInputs.isEmpty()) {
3120 List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
3121 for (GetInputValueDataDefinition getInput : getInputs) {
3122 List<InputDefinition> inputs = resource.getInputs();
3123 if (inputs == null || inputs.isEmpty()) {
3124 log.debug("Failed to add property {} to instance. Inputs list is empty ", property);
3125 loggerSupportability
3126 .log(LoggerSupportabilityActions.PROPERTY, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
3127 "Failed to add property: {} to instance. Inputs list is empty", propName);
3128 rollbackWithException(ActionStatus.INPUTS_NOT_FOUND,
3129 property.getGetInputValues().stream().map(GetInputValueDataDefinition::getInputName).collect(toList()).toString());
3131 Either<InputDefinition, RuntimeException> inputEither = findInputByName(inputs, getInput);
3132 if (inputEither.isRight()) {
3133 throw inputEither.right().value();
3135 InputDefinition input = inputEither.left().value();
3136 getInput.setInputId(input.getUniqueId());
3137 getInputValues.add(getInput);
3138 GetInputValueDataDefinition getInputIndex = getInput.getGetInputIndex();
3139 if (getInputIndex != null) {
3140 Either<InputDefinition, RuntimeException> newInputEither = findInputByName(inputs, getInputIndex);
3141 if (inputEither.isRight()) {
3142 throw newInputEither.right().value();
3144 InputDefinition newInput = newInputEither.left().value();
3145 getInputIndex.setInputId(newInput.getUniqueId());
3147 getInputValues.add(getInputIndex);
3151 property.setGetInputValues(getInputValues);
3153 instPropList.add(property);
3154 // delete overriden property
3155 currPropertiesMap.remove(property.getName());
3158 // add rest of properties
3159 if (!currPropertiesMap.isEmpty()) {
3160 for (PropertyDefinition value : currPropertiesMap.values()) {
3161 instPropList.add(new ComponentInstanceProperty(value));
3164 instProperties.put(currentCompInstance.getUniqueId(), instPropList);
3165 return componentsUtils.getResponseFormat(ActionStatus.OK);
3168 // US740820 Relate RIs according to capability name
3169 private CapabilityDefinition findAvailableCapabilityByTypeOrName(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3170 UploadReqInfo uploadReqInfo) {
3171 if (null == uploadReqInfo.getCapabilityName() || validReq.getCapability()
3172 .equals(uploadReqInfo.getCapabilityName())) {// get
3179 return findAvailableCapability(validReq, currentCapCompInstance);
3181 return findAvailableCapability(validReq, currentCapCompInstance, uploadReqInfo);
3184 private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance currentCapCompInstance,
3185 UploadReqInfo uploadReqInfo) {
3186 CapabilityDefinition cap = null;
3187 Map<String, List<CapabilityDefinition>> capMap = currentCapCompInstance.getCapabilities();
3188 if (!capMap.containsKey(validReq.getCapability())) {
3191 Optional<CapabilityDefinition> capByName = capMap.get(validReq.getCapability()).stream()
3192 .filter(p -> p.getName().equals(uploadReqInfo.getCapabilityName())).findAny();
3193 if (capByName.isEmpty()) {
3196 cap = capByName.get();
3197 if (isBoundedByOccurrences(cap)) {
3198 String leftOccurrences = cap.getLeftOccurrences();
3199 int left = Integer.parseInt(leftOccurrences);
3202 cap.setLeftOccurrences(String.valueOf(left));
3208 private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance instance) {
3209 Map<String, List<CapabilityDefinition>> capMap = instance.getCapabilities();
3210 if (capMap.containsKey(validReq.getCapability())) {
3211 List<CapabilityDefinition> capList = capMap.get(validReq.getCapability());
3212 for (CapabilityDefinition cap : capList) {
3213 if (isBoundedByOccurrences(cap)) {
3214 String leftOccurrences = cap.getLeftOccurrences() != null ? cap.getLeftOccurrences() : cap.getMaxOccurrences();
3215 int left = Integer.parseInt(leftOccurrences);
3218 cap.setLeftOccurrences(String.valueOf(left));
3229 private boolean isBoundedByOccurrences(CapabilityDefinition cap) {
3230 return cap.getMaxOccurrences() != null && !cap.getMaxOccurrences().equals(CapabilityDataDefinition.MAX_OCCURRENCES);
3233 private Either<RequirementDefinition, ResponseFormat> findAviableRequiremen(String regName, String yamlName,
3234 UploadComponentInstanceInfo uploadComponentInstanceInfo,
3235 ComponentInstance currentCompInstance, String capName) {
3236 Map<String, List<RequirementDefinition>> comInstRegDefMap = currentCompInstance.getRequirements();
3237 List<RequirementDefinition> list = comInstRegDefMap.get(capName);
3238 RequirementDefinition validRegDef = null;
3240 for (Entry<String, List<RequirementDefinition>> entry : comInstRegDefMap.entrySet()) {
3241 for (RequirementDefinition reqDef : entry.getValue()) {
3242 if (reqDef.getName().equals(regName)) {
3243 if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3244 String leftOccurrences = reqDef.getLeftOccurrences();
3245 if (leftOccurrences == null) {
3246 leftOccurrences = reqDef.getMaxOccurrences();
3248 int left = Integer.parseInt(leftOccurrences);
3251 reqDef.setLeftOccurrences(String.valueOf(left));
3252 validRegDef = reqDef;
3258 validRegDef = reqDef;
3263 if (validRegDef != null) {
3268 for (RequirementDefinition reqDef : list) {
3269 if (reqDef.getName().equals(regName)) {
3270 if (reqDef.getMaxOccurrences() != null && !reqDef.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
3271 String leftOccurrences = reqDef.getLeftOccurrences();
3272 if (leftOccurrences == null) {
3273 leftOccurrences = reqDef.getMaxOccurrences();
3275 int left = Integer.parseInt(leftOccurrences);
3278 reqDef.setLeftOccurrences(String.valueOf(left));
3279 validRegDef = reqDef;
3285 validRegDef = reqDef;
3291 if (validRegDef == null) {
3292 ResponseFormat responseFormat = componentsUtils
3293 .getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3294 uploadComponentInstanceInfo.getType());
3295 return Either.right(responseFormat);
3297 return Either.left(validRegDef);
3300 private Resource createResourceInstances(String yamlName, Resource resource, Resource oldResource,
3301 Map<String, UploadComponentInstanceInfo> uploadResInstancesMap, Map<String, Resource> nodeNamespaceMap,
3302 Map<String, Resource> existingNodeTypesByResourceNames) {
3303 Either<Resource, ResponseFormat> eitherResource;
3304 log.debug("createResourceInstances is {} - going to create resource instanse from CSAR", yamlName);
3305 if (isEmpty(uploadResInstancesMap) && resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3306 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
3307 throw new ByResponseFormatComponentException(responseFormat);
3309 if (MapUtils.isNotEmpty(nodeNamespaceMap)) {
3310 nodeNamespaceMap.forEach((k, v) -> existingNodeTypesByResourceNames.put(v.getToscaResourceName(), v));
3312 Map<ComponentInstance, Resource> resourcesInstancesMap = new HashMap<>();
3313 uploadResInstancesMap.values().forEach(
3314 i -> createAndAddResourceInstance(i, yamlName, resource, nodeNamespaceMap, existingNodeTypesByResourceNames, resourcesInstancesMap));
3315 if (oldResource != null && oldResource.getResourceType() != ResourceTypeEnum.CVFC && oldResource.getComponentInstances() != null) {
3316 Map<String, Resource> existingNodeTypesByUids = existingNodeTypesByResourceNames.values().stream()
3317 .collect(toMap(Resource::getUniqueId, r -> r));
3318 oldResource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar())
3319 .forEach(uiInst -> resourcesInstancesMap.put(uiInst, getOriginResource(existingNodeTypesByUids, uiInst)));
3321 if (isNotEmpty(resourcesInstancesMap)) {
3323 toscaOperationFacade.associateComponentInstancesToComponent(resource, resourcesInstancesMap, false, oldResource != null);
3324 } catch (StorageException exp) {
3325 if (exp.getStorageOperationStatus() != null && exp.getStorageOperationStatus() != StorageOperationStatus.OK) {
3326 log.debug("Failed to add component instances to container component {}", resource.getName());
3327 ResponseFormat responseFormat = componentsUtils
3328 .getResponseFormat(componentsUtils.convertFromStorageResponse(exp.getStorageOperationStatus()));
3329 eitherResource = Either.right(responseFormat);
3330 throw new ByResponseFormatComponentException(eitherResource.right().value());
3334 if (CollectionUtils.isEmpty(resource.getComponentInstances()) &&
3335 resource.getResourceType() != ResourceTypeEnum.PNF) { // PNF can have no resource instances
3336 log.debug("Error when create resource instance from csar. ComponentInstances list empty");
3337 BeEcompErrorManager.getInstance().logBeDaoSystemError("Error when create resource instance from csar. ComponentInstances list empty");
3338 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE));
3343 private void createAndAddResourceInstance(UploadComponentInstanceInfo uploadComponentInstanceInfo, String yamlName, Resource resource,
3344 Map<String, Resource> nodeNamespaceMap, Map<String, Resource> existingnodeTypeMap,
3345 Map<ComponentInstance, Resource> resourcesInstancesMap) {
3346 Either<Resource, ResponseFormat> eitherResource;
3347 log.debug("*************Going to create resource instances {}", yamlName);
3348 // updating type if the type is node type name - we need to take the
3351 log.debug("*************Going to create resource instances {}", uploadComponentInstanceInfo.getName());
3352 if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3353 uploadComponentInstanceInfo.setType(nodeNamespaceMap.get(uploadComponentInstanceInfo.getType()).getToscaResourceName());
3355 Resource refResource = validateResourceInstanceBeforeCreate(yamlName, uploadComponentInstanceInfo, existingnodeTypeMap, resource);
3356 ComponentInstance componentInstance = new ComponentInstance();
3357 componentInstance.setComponentUid(refResource.getUniqueId());
3358 Collection<String> directives = uploadComponentInstanceInfo.getDirectives();
3359 if (directives != null && !directives.isEmpty()) {
3360 componentInstance.setDirectives(new ArrayList<>(directives));
3362 UploadNodeFilterInfo uploadNodeFilterInfo = uploadComponentInstanceInfo.getUploadNodeFilterInfo();
3363 if (uploadNodeFilterInfo != null) {
3365 .setNodeFilter(new CINodeFilterUtils().getNodeFilterDataDefinition(uploadNodeFilterInfo, componentInstance.getUniqueId()));
3367 ComponentTypeEnum containerComponentType = resource.getComponentType();
3368 NodeTypeEnum containerNodeType = containerComponentType.getNodeType();
3369 if (containerNodeType == NodeTypeEnum.Resource && isNotEmpty(uploadComponentInstanceInfo.getCapabilities()) && isNotEmpty(
3370 refResource.getCapabilities())) {
3371 setCapabilityNamesTypes(refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3372 Map<String, List<CapabilityDefinition>> validComponentInstanceCapabilities = getValidComponentInstanceCapabilities(
3373 refResource.getUniqueId(), refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities());
3374 componentInstance.setCapabilities(validComponentInstanceCapabilities);
3376 if (isNotEmpty(uploadComponentInstanceInfo.getArtifacts())) {
3377 Map<String, Map<String, UploadArtifactInfo>> artifacts = uploadComponentInstanceInfo.getArtifacts();
3378 Map<String, ToscaArtifactDataDefinition> toscaArtifacts = new HashMap<>();
3379 Map<String, Map<String, UploadArtifactInfo>> arts = artifacts.entrySet().stream()
3380 .filter(e -> e.getKey().contains(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName()))
3381 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
3382 Map<String, UploadArtifactInfo> artifact = arts.get(TypeUtils.ToscaTagNamesEnum.ARTIFACTS.getElementName());
3383 for (Map.Entry<String, UploadArtifactInfo> entry : artifact.entrySet()) {
3384 ToscaArtifactDataDefinition to = new ToscaArtifactDataDefinition();
3385 to.setFile(entry.getValue().getFile());
3386 to.setType(entry.getValue().getType());
3387 if (isNotEmpty(entry.getValue().getProperties())) {
3388 Map<String, Object> newPropertiesMap = new HashMap<>();
3389 List<UploadPropInfo> artifactPropsInfo = entry.getValue().getProperties();
3390 for (UploadPropInfo propInfo : artifactPropsInfo) {
3391 newPropertiesMap.put(propInfo.getName(), propInfo.getValue());
3393 to.setProperties(newPropertiesMap);
3395 toscaArtifacts.put(entry.getKey(), to);
3397 componentInstance.setToscaArtifacts(toscaArtifacts);
3399 if (!existingnodeTypeMap.containsKey(uploadComponentInstanceInfo.getType())) {
3400 log.debug("createResourceInstances - not found lates version for resource instance with name {} and type {}",
3401 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3402 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3403 uploadComponentInstanceInfo.getType());
3405 Resource origResource = existingnodeTypeMap.get(uploadComponentInstanceInfo.getType());
3406 componentInstance.setName(uploadComponentInstanceInfo.getName());
3407 componentInstance.setIcon(origResource.getIcon());
3408 componentInstance.setCreatedFrom(CreatedFrom.CSAR);
3409 resourcesInstancesMap.put(componentInstance, origResource);
3412 private void setCapabilityNamesTypes(Map<String, List<CapabilityDefinition>> originCapabilities,
3413 Map<String, List<UploadCapInfo>> uploadedCapabilities) {
3414 for (Entry<String, List<UploadCapInfo>> currEntry : uploadedCapabilities.entrySet()) {
3415 if (originCapabilities.containsKey(currEntry.getKey())) {
3416 currEntry.getValue().forEach(cap -> cap.setType(currEntry.getKey()));
3419 for (Map.Entry<String, List<CapabilityDefinition>> capabilities : originCapabilities.entrySet()) {
3420 capabilities.getValue().forEach(cap -> {
3421 if (uploadedCapabilities.containsKey(cap.getName())) {
3422 uploadedCapabilities.get(cap.getName()).forEach(c -> {
3423 c.setName(cap.getName());
3424 c.setType(cap.getType());
3431 private Resource validateResourceInstanceBeforeCreate(String yamlName, UploadComponentInstanceInfo uploadComponentInstanceInfo,
3432 Map<String, Resource> nodeNamespaceMap, Resource resource) {
3433 log.debug("validateResourceInstanceBeforeCreate - going to validate resource instance with name {} and type {} before create",
3434 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3435 Resource refResource;
3436 if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
3437 refResource = nodeNamespaceMap.get(uploadComponentInstanceInfo.getType());
3439 Either<Resource, StorageOperationStatus> findResourceEither = StringUtils.isEmpty(resource.getModel()) ?
3440 toscaOperationFacade.getByToscaResourceNameMatchingVendorRelease(uploadComponentInstanceInfo.getType(),
3441 ((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()).getVendorRelease()) :
3442 toscaOperationFacade.getLatestByToscaResourceNameAndModel(uploadComponentInstanceInfo.getType(), resource.getModel());
3443 if (findResourceEither.isRight()) {
3444 log.debug("validateResourceInstanceBeforeCreate - not found latest version for resource instance with name {} and type {}",
3445 uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
3446 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(findResourceEither.right().value()));
3448 refResource = findResourceEither.left().value();
3449 nodeNamespaceMap.put(refResource.getToscaResourceName(), refResource);
3451 String componentState = refResource.getComponentMetadataDefinition().getMetadataDataDefinition().getState();
3452 if (componentState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3454 "validateResourceInstanceBeforeCreate - component instance of component {} can not be created because the component is in an illegal state {}.",
3455 refResource.getName(), componentState);
3456 throw new ByActionStatusComponentException(ActionStatus.ILLEGAL_COMPONENT_STATE, refResource.getComponentType().getValue(),
3457 refResource.getName(), componentState);
3459 if (!ModelConverter.isAtomicComponent(refResource) && refResource.getResourceType() != ResourceTypeEnum.CVFC) {
3460 log.debug("validateResourceInstanceBeforeCreate - ref resource type is {} ", refResource.getResourceType());
3461 throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(),
3462 uploadComponentInstanceInfo.getType());
3467 public Resource propagateStateToCertified(User user, Resource resource, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3468 boolean needLock, boolean forceCertificationAllowed) {
3469 boolean failed = false;
3471 if (resource.getLifecycleState() != LifecycleStateEnum.CERTIFIED && forceCertificationAllowed && lifecycleBusinessLogic
3472 .isFirstCertification(resource.getVersion())) {
3473 nodeForceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3475 if (resource.getLifecycleState() == LifecycleStateEnum.CERTIFIED) {
3476 populateToscaArtifacts(resource, user, false, inTransaction, needLock, false);
3479 return nodeFullCertification(resource.getUniqueId(), user, lifecycleChangeInfo, inTransaction, needLock);
3480 } catch (ComponentException e) {
3482 log.debug("The exception has occurred upon certification of resource {}. ", resource.getName(), e);
3486 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3487 if (!inTransaction) {
3488 janusGraphDao.rollback();
3490 } else if (!inTransaction) {
3491 janusGraphDao.commit();
3496 private Resource nodeFullCertification(String uniqueId, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3498 Either<Resource, ResponseFormat> resourceResponse = lifecycleBusinessLogic
3499 .changeState(uniqueId, user, LifeCycleTransitionEnum.CERTIFY, lifecycleChangeInfo, inTransaction, needLock);
3500 if (resourceResponse.isRight()) {
3501 throw new ByResponseFormatComponentException(resourceResponse.right().value());
3503 return resourceResponse.left().value();
3506 private Resource nodeForceCertification(Resource resource, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction,
3508 return lifecycleBusinessLogic.forceResourceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
3511 public ImmutablePair<Resource, ActionStatus> createOrUpdateResourceByImport(final Resource resource, final User user, final boolean isNormative,
3512 final boolean isInTransaction, final boolean needLock,
3513 final CsarInfo csarInfo, final String nodeName,
3514 final boolean isNested) {
3515 ImmutablePair<Resource, ActionStatus> result = null;
3516 // check if resource already exists (search by tosca name = type)
3517 final boolean isNestedResource = isNestedResourceUpdate(csarInfo, nodeName);
3518 final String resourceName = resource.getToscaResourceName();
3519 final Either<Resource, StorageOperationStatus> latestByToscaName = toscaOperationFacade
3520 .getLatestByToscaResourceNameAndModel(resourceName, resource.getModel());
3521 if (latestByToscaName.isLeft() && Objects.nonNull(latestByToscaName.left().value())) {
3522 final Resource foundResource = latestByToscaName.left().value();
3523 // we don't allow updating names of top level types
3524 if (!isNestedResource && !StringUtils.equals(resource.getName(), foundResource.getName())) {
3525 BeEcompErrorManager.getInstance()
3526 .logBeComponentMissingError("Create / Update resource by import", ComponentTypeEnum.RESOURCE.getValue(), resource.getName());
3527 log.debug("resource already exist new name={} old name={} same type={}", resource.getName(), foundResource.getName(),
3528 resource.getToscaResourceName());
3529 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
3530 componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3531 throwComponentException(responseFormat);
3533 result = updateExistingResourceByImport(resource, foundResource, user, isNormative, needLock, isNested);
3534 } else if (isNotFound(latestByToscaName)) {
3535 if (isNestedResource) {
3536 result = createOrUpdateNestedResource(resource, user, isNormative, isInTransaction, needLock, csarInfo, isNested, nodeName);
3538 result = createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3541 StorageOperationStatus status = latestByToscaName.right().value();
3542 log.debug("failed to get latest version of resource {}. status={}", resource.getName(), status);
3543 ResponseFormat responseFormat = componentsUtils
3544 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(latestByToscaName.right().value()), resource);
3545 componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
3546 throwComponentException(responseFormat);
3551 private boolean isNestedResourceUpdate(CsarInfo csarInfo, String nodeName) {
3552 return csarInfo != null && csarInfo.isUpdate() && nodeName != null;
3555 private ImmutablePair<Resource, ActionStatus> createOrUpdateNestedResource(final Resource resource, final User user, final boolean isNormative,
3556 final boolean isInTransaction, final boolean needLock,
3557 final CsarInfo csarInfo, final boolean isNested,
3558 final String nodeName) {
3559 final Either<Component, StorageOperationStatus> latestByToscaName = toscaOperationFacade.getLatestByToscaResourceName(
3560 buildNestedToscaResourceName(resource.getResourceType().name(), csarInfo.getVfResourceName(), nodeName).getRight(), resource.getModel());
3561 if (latestByToscaName.isLeft()) {
3562 final Resource nestedResource = (Resource) latestByToscaName.left().value();
3563 log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
3564 final Either<Boolean, ResponseFormat> eitherValidation = validateNestedDerivedFromDuringUpdate(nestedResource, resource,
3565 ValidationUtils.hasBeenCertified(nestedResource.getVersion()));
3566 if (eitherValidation.isRight()) {
3567 return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3569 return updateExistingResourceByImport(resource, nestedResource, user, isNormative, needLock, isNested);
3571 return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo);
3575 private boolean isNotFound(Either<Resource, StorageOperationStatus> getResourceEither) {
3576 return getResourceEither.isRight() && getResourceEither.right().value() == StorageOperationStatus.NOT_FOUND;
3579 private ImmutablePair<Resource, ActionStatus> createResourceByImport(Resource resource, User user, boolean isNormative, boolean isInTransaction,
3580 CsarInfo csarInfo) {
3581 log.debug("resource with name {} does not exist. create new resource", resource.getName());
3582 validateResourceBeforeCreate(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isInTransaction, csarInfo);
3583 final Resource createResourceByDao = createResourceByDao(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isNormative, isInTransaction);
3584 Resource createdResource = updateCatalog(createResourceByDao, ChangeTypeEnum.LIFECYCLE).left().map(r -> (Resource) r).left().value();
3585 ImmutablePair<Resource, ActionStatus> resourcePair = new ImmutablePair<>(createdResource, ActionStatus.CREATED);
3586 ASDCKpiApi.countImportResourcesKPI();
3587 return resourcePair;
3590 public boolean isResourceExist(String resourceName) {
3591 Either<Resource, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByName(resourceName, null);
3592 return latestByName.isLeft();
3595 private ImmutablePair<Resource, ActionStatus> updateExistingResourceByImport(Resource newResource, Resource oldResource, User user,
3596 boolean inTransaction, boolean needLock, boolean isNested) {
3597 String lockedResourceId = oldResource.getUniqueId();
3598 log.debug("found resource: name={}, id={}, version={}, state={}", oldResource.getName(), lockedResourceId, oldResource.getVersion(),
3599 oldResource.getLifecycleState());
3600 ImmutablePair<Resource, ActionStatus> resourcePair = null;
3602 lockComponent(lockedResourceId, oldResource, needLock, "Update Resource by Import");
3603 oldResource = prepareResourceForUpdate(oldResource, newResource, user, inTransaction, false);
3604 mergeOldResourceMetadataWithNew(oldResource, newResource);
3605 validateResourceFieldsBeforeUpdate(oldResource, newResource, inTransaction, isNested);
3606 validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), newResource, AuditingActionEnum.IMPORT_RESOURCE, inTransaction);
3607 // contact info normalization
3608 newResource.setContactId(newResource.getContactId().toLowerCase());
3609 PropertyConstraintsUtils.validatePropertiesConstraints(newResource, oldResource);
3610 // non-updatable fields
3611 newResource.setCreatorUserId(user.getUserId());
3612 newResource.setCreatorFullName(user.getFullName());
3613 newResource.setLastUpdaterUserId(user.getUserId());
3614 newResource.setLastUpdaterFullName(user.getFullName());
3615 newResource.setUniqueId(oldResource.getUniqueId());
3616 newResource.setVersion(oldResource.getVersion());
3617 newResource.setInvariantUUID(oldResource.getInvariantUUID());
3618 newResource.setLifecycleState(oldResource.getLifecycleState());
3619 newResource.setUUID(oldResource.getUUID());
3620 newResource.setNormalizedName(oldResource.getNormalizedName());
3621 newResource.setSystemName(oldResource.getSystemName());
3622 newResource.setModel(oldResource.getModel());
3623 if (oldResource.getCsarUUID() != null) {
3624 newResource.setCsarUUID(oldResource.getCsarUUID());
3626 if (oldResource.getImportedToscaChecksum() != null) {
3627 newResource.setImportedToscaChecksum(oldResource.getImportedToscaChecksum());
3629 newResource.setAbstract(oldResource.isAbstract());
3630 if (CollectionUtils.isEmpty(newResource.getDerivedFrom())) {
3631 newResource.setDerivedFrom(oldResource.getDerivedFrom());
3633 if (CollectionUtils.isEmpty(newResource.getDataTypes())) {
3634 newResource.setDataTypes(oldResource.getDataTypes());
3636 if (StringUtils.isEmpty(newResource.getDerivedFromGenericType())) {
3637 newResource.setDerivedFromGenericType(oldResource.getDerivedFromGenericType());
3639 if (StringUtils.isEmpty(newResource.getDerivedFromGenericVersion())) {
3640 newResource.setDerivedFromGenericVersion(oldResource.getDerivedFromGenericVersion());
3644 // created without tosca artifacts - add the placeholders
3645 if (MapUtils.isEmpty(newResource.getToscaArtifacts())) {
3646 setToscaArtifactsPlaceHolders(newResource, user);
3648 if (MapUtils.isEmpty(newResource.getInterfaces())) {
3649 newResource.setInterfaces(oldResource.getInterfaces());
3651 if (CollectionUtils.isEmpty(newResource.getAttributes())) {
3652 newResource.setAttributes(oldResource.getAttributes());
3654 if (CollectionUtils.isEmpty(newResource.getProperties())) {
3655 newResource.setProperties(oldResource.getProperties());
3657 Either<Resource, StorageOperationStatus> overrideResource = toscaOperationFacade.overrideComponent(newResource, oldResource);
3658 if (overrideResource.isRight()) {
3659 ResponseFormat responseFormat = componentsUtils
3660 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(overrideResource.right().value()), newResource);
3661 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE);
3662 throwComponentException(responseFormat);
3664 updateCatalog(overrideResource.left().value(), ChangeTypeEnum.LIFECYCLE);
3665 log.debug("Resource updated successfully!!!");
3666 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3667 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3668 ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3669 resourcePair = new ImmutablePair<>(overrideResource.left().value(), ActionStatus.OK);
3670 return resourcePair;
3672 if (resourcePair == null) {
3673 BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify");
3674 janusGraphDao.rollback();
3675 } else if (!inTransaction) {
3676 janusGraphDao.commit();
3679 log.debug("unlock resource {}", lockedResourceId);
3680 graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource);
3686 * Merge old resource with new. Keep old category and vendor name without change
3688 * @param oldResource
3689 * @param newResource
3691 private void mergeOldResourceMetadataWithNew(Resource oldResource, Resource newResource) {
3692 // keep old category and vendor name without change
3694 // merge the rest of the resource metadata
3695 if (newResource.getTags() == null || newResource.getTags().isEmpty()) {
3696 newResource.setTags(oldResource.getTags());
3698 if (newResource.getDescription() == null) {
3699 newResource.setDescription(oldResource.getDescription());
3701 if (newResource.getVendorRelease() == null) {
3702 newResource.setVendorRelease(oldResource.getVendorRelease());
3704 if (newResource.getResourceVendorModelNumber() == null) {
3705 newResource.setResourceVendorModelNumber(oldResource.getResourceVendorModelNumber());
3707 if (newResource.getModel() == null) {
3708 newResource.setModel(oldResource.getModel());
3710 if (newResource.getContactId() == null) {
3711 newResource.setContactId(oldResource.getContactId());
3713 newResource.setIcon(oldResource.getIcon());
3714 newResource.setCategories(oldResource.getCategories());
3715 if (newResource.getVendorName() == null) {
3716 newResource.setVendorName(oldResource.getVendorName());
3718 List<GroupDefinition> oldForUpdate = oldResource.getGroups();
3719 if (CollectionUtils.isNotEmpty(oldForUpdate)) {
3720 List<GroupDefinition> groupForUpdate = oldForUpdate.stream().map(GroupDefinition::new).collect(Collectors.toList());
3721 groupForUpdate.stream().filter(GroupDataDefinition::isVspOriginated).forEach(group -> group.setName(group.getInvariantName()));
3722 newResource.setGroups(groupForUpdate);
3724 if (newResource.getResourceType().isAtomicType() && !newResource.getName().equals("Root")
3725 && newResource.getResourceType() != ResourceTypeEnum.CVFC) {
3726 ResourceTypeEnum updatedResourceType = newResource.getResourceType();
3727 Optional<Component> derivedFromResourceOptional = getParentComponent(newResource);
3728 if (derivedFromResourceOptional.isPresent() && derivedFromResourceOptional.get().getComponentType() == ComponentTypeEnum.RESOURCE) {
3729 Resource parentResource = (Resource) derivedFromResourceOptional.get();
3730 if (!(parentResource.isAbstract() && (ResourceTypeEnum.VFC == parentResource.getResourceType()
3731 || ResourceTypeEnum.ABSTRACT == parentResource.getResourceType())) && parentResource.getResourceType() != updatedResourceType
3732 && oldResource.getResourceType() != updatedResourceType) {
3733 BeEcompErrorManager.getInstance().logInternalDataError("mergeOldResourceMetadataWithNew",
3734 "resource type of the resource does not match to derived from resource type", ErrorSeverity.ERROR);
3736 "#mergeOldResourceMetadataWithNew - resource type {} of the resource {} does not match to derived from resource type {}",
3737 newResource.getResourceType(), newResource.getToscaResourceName(), parentResource.getResourceType());
3738 throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_TYPE);
3744 private Optional<Component> getParentComponent(Resource newResource) {
3745 if (newResource.getDerivedFrom() == null) {
3746 return Optional.empty();
3748 String toscaResourceNameDerivedFrom = newResource.getDerivedFrom().get(0);
3749 Either<Component, StorageOperationStatus> latestByToscaResourceName = toscaOperationFacade
3750 .getLatestByToscaResourceName(toscaResourceNameDerivedFrom, newResource.getModel());
3751 if (latestByToscaResourceName.isRight()) {
3752 BeEcompErrorManager.getInstance()
3753 .logInternalDataError("mergeOldResourceMetadataWithNew", "derived from resource not found", ErrorSeverity.ERROR);
3754 log.debug("#mergeOldResourceMetadataWithNew - derived from resource {} not found", toscaResourceNameDerivedFrom);
3755 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, toscaResourceNameDerivedFrom);
3757 return Optional.of(latestByToscaResourceName.left().value());
3760 private Resource prepareResourceForUpdate(Resource oldResource, Resource newResource, User user, boolean inTransaction, boolean needLock) {
3761 if (!ComponentValidationUtils.canWorkOnResource(oldResource, user.getUserId())) {
3763 return lifecycleBusinessLogic
3764 .changeState(oldResource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, new LifecycleChangeInfoWithAction("update by import"),
3765 inTransaction, needLock).left().on(response -> failOnChangeState(response, user, oldResource, newResource));
3770 private Resource failOnChangeState(ResponseFormat response, User user, Resource oldResource, Resource newResource) {
3771 log.info("resource {} cannot be updated. reason={}", oldResource.getUniqueId(), response.getFormattedMessage());
3772 componentsUtils.auditResource(response, user, newResource, AuditingActionEnum.IMPORT_RESOURCE,
3773 ResourceVersionInfo.newBuilder().state(oldResource.getLifecycleState().name()).version(oldResource.getVersion()).build());
3774 throw new ByResponseFormatComponentException(response);
3777 public Resource validateResourceBeforeCreate(Resource resource, User user, AuditingActionEnum actionEnum, boolean inTransaction,
3778 CsarInfo csarInfo) {
3779 validateResourceFieldsBeforeCreate(user, resource, actionEnum, inTransaction);
3780 validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), resource, actionEnum, inTransaction);
3781 validateLifecycleTypesCreate(user, resource, actionEnum);
3782 validateResourceType(user, resource, actionEnum);
3783 resource.setCreatorUserId(user.getUserId());
3784 resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
3785 resource.setContactId(resource.getContactId().toLowerCase());
3786 if (StringUtils.isEmpty(resource.getToscaResourceName()) && !ModelConverter.isAtomicComponent(resource)) {
3787 String resourceSystemName;
3788 if (csarInfo != null && StringUtils.isNotEmpty(csarInfo.getVfResourceName())) {
3789 resourceSystemName = ValidationUtils.convertToSystemName(csarInfo.getVfResourceName());
3791 resourceSystemName = resource.getSystemName();
3794 .setToscaResourceName(CommonBeUtils.generateToscaResourceName(resource.getResourceType().name().toLowerCase(), resourceSystemName));
3796 // Generate invariant UUID - must be here and not in operation since it
3798 // should stay constant during clone
3801 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
3802 resource.setInvariantUUID(invariantUUID);
3806 private Either<Boolean, ResponseFormat> validateResourceType(User user, Resource resource, AuditingActionEnum actionEnum) {
3807 Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3808 if (resource.getResourceType() == null) {
3809 log.debug("Invalid resource type for resource");
3810 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
3811 eitherResult = Either.right(errorResponse);
3812 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3814 return eitherResult;
3817 private Either<Boolean, ResponseFormat> validateLifecycleTypesCreate(User user, Resource resource, AuditingActionEnum actionEnum) {
3818 Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3819 if (resource.getInterfaces() != null && resource.getInterfaces().size() > 0) {
3820 log.debug("validate interface lifecycle Types Exist");
3821 Iterator<InterfaceDefinition> intItr = resource.getInterfaces().values().iterator();
3822 while (intItr.hasNext() && eitherResult.isLeft()) {
3823 InterfaceDefinition interfaceDefinition = intItr.next();
3824 String intType = interfaceDefinition.getUniqueId();
3825 Either<InterfaceDefinition, StorageOperationStatus> eitherCapTypeFound = interfaceTypeOperation.getInterface(UniqueIdBuilder.buildInterfaceTypeUid(resource.getModel(), intType));
3826 if (eitherCapTypeFound.isRight()) {
3827 if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3828 BeEcompErrorManager.getInstance()
3829 .logBeGraphObjectMissingError("Create Resource - validateLifecycleTypesCreate", "Interface", intType);
3830 log.debug("Lifecycle Type: {} is required by resource: {} but does not exist in the DB", intType, resource.getName());
3831 BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateLifecycleTypesCreate");
3832 log.debug("request to data model failed with error: {}", eitherCapTypeFound.right().value().name());
3834 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_LIFECYCLE_TYPE, intType);
3835 eitherResult = Either.right(errorResponse);
3836 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3840 return eitherResult;
3843 private Either<Boolean, ResponseFormat> validateCapabilityTypesCreate(User user, ICapabilityTypeOperation capabilityTypeOperation,
3844 Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
3845 Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
3846 if (resource.getCapabilities() != null && resource.getCapabilities().size() > 0) {
3847 log.debug("validate capability Types Exist - capabilities section");
3848 for (Entry<String, List<CapabilityDefinition>> typeEntry : resource.getCapabilities().entrySet()) {
3849 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, actionEnum, eitherResult, typeEntry,
3851 if (eitherResult.isRight()) {
3852 return Either.right(eitherResult.right().value());
3856 if (resource.getRequirements() != null && resource.getRequirements().size() > 0) {
3857 log.debug("validate capability Types Exist - requirements section");
3858 for (String type : resource.getRequirements().keySet()) {
3859 eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, resource.getRequirements().get(type), actionEnum,
3860 eitherResult, type, inTransaction);
3861 if (eitherResult.isRight()) {
3862 return Either.right(eitherResult.right().value());
3866 return eitherResult;
3869 // @param typeObject- the object to which the validation is done
3870 private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3871 Resource resource, List<?> validationObjects, AuditingActionEnum actionEnum,
3872 Either<Boolean, ResponseFormat> eitherResult, String type,
3873 boolean inTransaction) {
3874 Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation.getCapabilityType(
3875 UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), type), inTransaction);
3876 if (eitherCapTypeFound.isRight()) {
3877 if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3878 BeEcompErrorManager.getInstance().logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", type);
3879 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", type, resource.getName());
3880 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3882 log.debug("Trying to get capability type {} failed with error: {}", type, eitherCapTypeFound.right().value().name());
3883 ResponseFormat errorResponse = null;
3885 errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, type);
3887 errorResponse = componentsUtils.getResponseFormatByElement(ActionStatus.MISSING_CAPABILITY_TYPE, validationObjects);
3889 eitherResult = Either.right(errorResponse);
3890 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3892 return eitherResult;
3895 private Either<Boolean, ResponseFormat> validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation,
3896 Resource resource, AuditingActionEnum actionEnum,
3897 Either<Boolean, ResponseFormat> eitherResult,
3898 Entry<String, List<CapabilityDefinition>> typeEntry, boolean inTransaction) {
3899 Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation
3900 .getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), typeEntry.getKey()), inTransaction);
3901 if (eitherCapTypeFound.isRight()) {
3902 if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
3903 BeEcompErrorManager.getInstance()
3904 .logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", typeEntry.getKey());
3905 log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", typeEntry.getKey(), resource.getName());
3906 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES);
3908 log.debug("Trying to get capability type {} failed with error: {}", typeEntry.getKey(), eitherCapTypeFound.right().value().name());
3909 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, typeEntry.getKey());
3910 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
3911 return Either.right(errorResponse);
3913 CapabilityTypeDefinition capabilityTypeDefinition = eitherCapTypeFound.left().value();
3914 if (capabilityTypeDefinition.getProperties() != null) {
3915 for (CapabilityDefinition capDef : typeEntry.getValue()) {
3916 List<ComponentInstanceProperty> properties = capDef.getProperties();
3917 List<ComponentInstanceProperty> changedProperties = new ArrayList<>();
3918 if (properties == null || properties.isEmpty()) {
3919 for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
3920 ComponentInstanceProperty newProp = new ComponentInstanceProperty(prop.getValue());
3921 changedProperties.add(newProp);
3924 List<ComponentInstanceProperty> propsToAdd = new ArrayList<>();
3925 for (Entry<String, PropertyDefinition> prop : capabilityTypeDefinition.getProperties().entrySet()) {
3926 PropertyDefinition propFromDef = prop.getValue();
3927 boolean propFound = false;
3928 for (ComponentInstanceProperty cip : properties) {
3929 if (propFromDef.getName().equals(cip.getName())) {
3930 //merge property value and property description only, ignore other fields
3931 if (cip.getDescription() != null && !cip.getDescription().equals(propFromDef.getDescription())) {
3932 propFromDef.setDescription(cip.getDescription());
3934 propertyDataValueMergeBusinessLogic.mergePropertyValue(propFromDef, cip, new ArrayList<>());
3935 if (cip.getValue() != null) {
3936 propFromDef.setValue(cip.getValue());
3938 propsToAdd.add(new ComponentInstanceProperty(propFromDef));
3940 properties.remove(cip);
3945 propsToAdd.add(new ComponentInstanceProperty(propFromDef));
3948 if (!propsToAdd.isEmpty()) {
3949 changedProperties.addAll(propsToAdd);
3952 capDef.setProperties(changedProperties);
3955 return eitherResult;
3958 public Resource createResourceByDao(Resource resource, User user, AuditingActionEnum actionEnum, boolean isNormative, boolean inTransaction) {
3961 // lock new resource name in order to avoid creation resource with same
3964 Resource createdResource = null;
3965 if (!inTransaction) {
3966 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE);
3967 if (lockResult.isRight()) {
3968 ResponseFormat responseFormat = lockResult.right().value();
3969 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3970 throw new ByResponseFormatComponentException(responseFormat);
3972 log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult);
3975 if (resource.deriveFromGeneric()) {
3976 handleResourceGenericType(resource);
3978 createdResource = createResourceTransaction(resource, user, isNormative);
3979 componentsUtils.auditResource(componentsUtils.getResponseFormat(ActionStatus.CREATED), user, createdResource, actionEnum);
3980 ASDCKpiApi.countCreatedResourcesKPI();
3981 } catch (ComponentException e) {
3982 ResponseFormat responseFormat =
3983 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
3984 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3986 } catch (StorageException e) {
3987 ResponseFormat responseFormat = componentsUtils
3988 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
3989 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
3992 if (!inTransaction) {
3993 graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource);
3996 return createdResource;
3999 private Resource createResourceTransaction(Resource resource, User user, boolean isNormative) {
4000 final String resourceName = resource.getName();
4001 final String modelName = resource.getModel();
4002 final ResourceTypeEnum resourceType = resource.getResourceType();
4003 final ComponentTypeEnum componentType = resource.getComponentType();
4004 final Either<Boolean, StorageOperationStatus> eitherValidation = toscaOperationFacade
4005 .validateComponentNameAndModelExists(resourceName, modelName, resourceType, componentType);
4006 if (eitherValidation.isRight()) {
4007 loggerSupportability.log(LoggerSupportabilityActions.VALIDATE_NAME, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4008 "ERROR while validate component name {} Status is: {}", resource.getName(), eitherValidation.right().value());
4009 log.debug("Failed to validate component name {}. Status is {}. ", resource.getName(), eitherValidation.right().value());
4010 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(eitherValidation.right().value()));
4012 if (eitherValidation.left().value()) {
4013 log.debug("resource with name: {}, already exists", resource.getName());
4014 loggerSupportability
4015 .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
4016 "resource with name: {} already exists", resource.getName());
4017 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4018 resource.getName());
4020 log.debug("send resource {} to dao for create", resource.getName());
4021 createArtifactsPlaceHolderData(resource, user);
4024 log.debug("enrich resource with creator, version and state");
4025 resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
4026 resource.setVersion(INITIAL_VERSION);
4027 resource.setHighestVersion(true);
4028 if (resource.getResourceType() != null && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4029 resource.setAbstract(false);
4032 return toscaOperationFacade.createToscaComponent(resource).left().on(r -> throwComponentExceptionByResource(r, resource));
4035 private Resource throwComponentExceptionByResource(StorageOperationStatus status, Resource resource) {
4036 ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(status), resource);
4037 throw new ByResponseFormatComponentException(responseFormat);
4040 private void createArtifactsPlaceHolderData(Resource resource, User user) {
4041 // create mandatory artifacts
4043 // TODO it must be removed after that artifact uniqueId creation will be
4045 // moved to ArtifactOperation
4046 setInformationalArtifactsPlaceHolder(resource, user);
4047 setDeploymentArtifactsPlaceHolder(resource, user);
4048 setToscaArtifactsPlaceHolders(resource, user);
4051 @SuppressWarnings("unchecked")
4053 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
4054 Resource resource = (Resource) component;
4055 Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
4056 if (artifactMap == null) {
4057 artifactMap = new HashMap<>();
4059 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4060 .getDeploymentResourceArtifacts();
4061 if (deploymentResourceArtifacts != null) {
4062 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
4063 deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
4065 resource.setDeploymentArtifacts(artifactMap);
4068 private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
4069 Map<String, Object> artifactDetails = (Map<String, Object>) v;
4070 Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
4071 if (object != null) {
4072 List<String> artifactTypes = (List<String>) object;
4073 if (!artifactTypes.contains(resource.getResourceType().name())) {
4077 log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
4079 if (artifactsBusinessLogic != null) {
4080 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4081 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
4082 if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
4083 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4088 @SuppressWarnings("unchecked")
4089 private void setInformationalArtifactsPlaceHolder(Resource resource, User user) {
4090 Map<String, ArtifactDefinition> artifactMap = resource.getArtifacts();
4091 if (artifactMap == null) {
4092 artifactMap = new HashMap<>();
4094 String resourceUniqueId = resource.getUniqueId();
4095 List<String> exludeResourceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceCategory();
4096 List<String> exludeResourceType = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceType();
4097 Map<String, Object> informationalResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
4098 .getInformationalResourceArtifacts();
4099 List<CategoryDefinition> categories = resource.getCategories();
4100 boolean isCreateArtifact = true;
4101 if (exludeResourceCategory != null) {
4102 String category = categories.get(0).getName();
4103 isCreateArtifact = exludeResourceCategory.stream().noneMatch(e -> e.equalsIgnoreCase(category));
4105 if (isCreateArtifact && exludeResourceType != null) {
4106 String resourceType = resource.getResourceType().name();
4107 isCreateArtifact = exludeResourceType.stream().noneMatch(e -> e.equalsIgnoreCase(resourceType));
4109 if (informationalResourceArtifacts != null && isCreateArtifact) {
4110 Set<String> keys = informationalResourceArtifacts.keySet();
4111 for (String informationalResourceArtifactName : keys) {
4112 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalResourceArtifacts.get(informationalResourceArtifactName);
4113 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
4114 .createArtifactPlaceHolderInfo(resourceUniqueId, informationalResourceArtifactName, artifactInfoMap, user,
4115 ArtifactGroupTypeEnum.INFORMATIONAL);
4116 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
4119 resource.setArtifacts(artifactMap);
4129 public ResponseFormat deleteResource(String resourceId, User user) {
4130 ResponseFormat responseFormat;
4131 validateUserExists(user);
4132 Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4133 if (resourceStatus.isRight()) {
4134 log.debug("failed to get resource {}", resourceId);
4135 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), "");
4137 Resource resource = resourceStatus.left().value();
4138 StorageOperationStatus result = StorageOperationStatus.OK;
4139 lockComponent(resourceId, resource, "Mark resource to delete");
4141 result = markComponentToDelete(resource);
4142 if (result == StorageOperationStatus.OK) {
4143 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4145 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4146 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4148 return responseFormat;
4150 if (!StorageOperationStatus.OK.equals(result)) {
4151 janusGraphDao.rollback();
4153 janusGraphDao.commit();
4155 graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
4159 private boolean isComponentSystemDeployed(Resource resource) {
4160 return resource.getComponentMetadataDefinition().getMetadataDataDefinition().isNormative();
4164 * Deletes every version of the provided resource
4166 * @param resourceId the resource identifier
4167 * @param user the user that performs the deletion
4169 * @throws ComponentException if there is any error in the deletion of the resource operation
4171 public void deleteResourceAllVersions(String resourceId, User user) {
4172 validateUserExists(user);
4173 Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
4174 if (resourceStatus.isRight()) {
4175 log.debug("Failed to get resource {}", resourceId);
4176 componentException(resourceStatus.right().value());
4178 Resource resource = resourceStatus.left().value();
4179 if (isComponentSystemDeployed(resource)) {
4180 throw new ByActionStatusComponentException(ActionStatus.CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES, ComponentTypeEnum.RESOURCE.getValue(),
4181 resource.getName());
4183 if (Boolean.FALSE.equals(resource.isArchived())) {
4184 log.debug("The resource, {}, requested for delete has not been archived.", resourceId);
4185 throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, resourceId);
4188 String model = resource.getModel();
4189 final Optional<Model> modelOptional = modelOperation.findModelByName(model);
4190 List<String> deletedResourceList = toscaOperationFacade.deleteComponent(resource.getInvariantUUID(), NodeTypeEnum.Resource, true);
4191 if (log.isDebugEnabled()) {
4192 deletedResourceList.forEach(deletedR -> log.debug("Component {} was deleted.", deletedR));
4194 if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
4195 modelOperation.deleteModel(modelOptional.get(), true);
4197 toscaOperationFacade.commitAndCheck(resource.getUniqueId());
4198 updateCatalog(resource, ChangeTypeEnum.DELETE);
4199 } catch (ComponentException exception) {
4200 log.debug("Failed to delete resource, {} ", resourceId);
4201 janusGraphDao.rollback();
4206 public ResponseFormat deleteResourceByNameAndVersion(String resourceName, String version, User user) {
4207 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
4208 validateUserExists(user);
4209 Resource resource = null;
4210 StorageOperationStatus result = StorageOperationStatus.OK;
4211 boolean failed = false;
4213 Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade
4214 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, version);
4215 if (resourceStatus.isRight()) {
4216 log.debug("failed to get resource {} version {}", resourceName, version);
4217 return componentsUtils
4218 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), resourceName);
4220 resource = resourceStatus.left().value();
4222 janusGraphDao.commit();
4224 if (resource != null) {
4225 lockComponent(resource.getUniqueId(), resource, DELETE_RESOURCE);
4227 result = markComponentToDelete(resource);
4228 if (result != StorageOperationStatus.OK) {
4229 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
4230 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName());
4231 return responseFormat;
4233 } catch (ComponentException e) {
4237 if (failed || !StorageOperationStatus.OK.equals(result)) {
4238 janusGraphDao.rollback();
4240 janusGraphDao.commit();
4242 graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource);
4245 return responseFormat;
4248 public Either<Resource, ResponseFormat> getResource(String resourceId, User user) {
4250 validateUserExists(user);
4252 Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceId);
4253 if (storageStatus.isRight()) {
4254 log.debug("failed to get resource by id {}", resourceId);
4255 return Either.right(
4256 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), resourceId));
4258 if (storageStatus.left().value() == null) {
4259 return Either.right(componentsUtils
4260 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), resourceId));
4262 return Either.left(storageStatus.left().value());
4265 public Either<Resource, ResponseFormat> getResourceByNameAndVersion(String resourceName, String resourceVersion, String userId) {
4266 validateUserExists(userId);
4267 Either<Resource, StorageOperationStatus> getResource = toscaOperationFacade
4268 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion);
4269 if (getResource.isRight()) {
4270 log.debug("failed to get resource by name {} and version {}", resourceName, resourceVersion);
4271 return Either.right(
4272 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResource.right().value()), resourceName));
4274 return Either.left(getResource.left().value());
4278 * updateResourceMetadata
4280 * @param user - modifier data (userId)
4281 * @param inTransaction TODO
4282 * @param resourceIdToUpdate - the resource identifier
4283 * @param newResource
4284 * @return Either<Resource, responseFormat>
4286 public Resource updateResourceMetadata(String resourceIdToUpdate, Resource newResource, Resource currentResource, User user,
4287 boolean inTransaction) {
4288 validateUserExists(user.getUserId());
4289 log.debug("Get resource with id {}", resourceIdToUpdate);
4290 boolean needToUnlock = false;
4292 if (currentResource == null) {
4293 Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceIdToUpdate);
4294 if (storageStatus.isRight()) {
4295 throw new ByResponseFormatComponentException(
4296 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), ""));
4298 currentResource = storageStatus.left().value();
4300 // verify that resource is checked-out and the user is the last
4303 if (!ComponentValidationUtils.canWorkOnResource(currentResource, user.getUserId())) {
4304 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
4307 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4308 if (lockResult != StorageOperationStatus.OK) {
4309 BeEcompErrorManager.getInstance()
4310 .logBeFailedLockObjectError("Upload Artifact - lock ", NodeTypeEnum.Resource.getName(), resourceIdToUpdate);
4311 log.debug("Failed to lock resource: {}, error - {}", resourceIdToUpdate, lockResult);
4312 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult));
4313 throw new ByResponseFormatComponentException(responseFormat);
4315 needToUnlock = true;
4316 // critical section starts here
4318 // convert json to object
4320 // Update and updated resource must have a non-empty "derivedFrom"
4324 // This code is not called from import resources, because of root
4326 // VF "derivedFrom" should be null (or ignored)
4327 if (ModelConverter.isAtomicComponent(currentResource)) {
4328 validateDerivedFromNotEmpty(null, newResource, null);
4329 validateDerivedFromNotEmpty(null, currentResource, null);
4331 newResource.setDerivedFrom(null);
4333 Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource,
4335 if (dataModelResponse.isRight()) {
4336 log.debug("failed to update resource metadata!!!");
4337 throw new ByResponseFormatComponentException(dataModelResponse.right().value());
4339 log.debug("Resource metadata updated successfully!!!");
4340 return dataModelResponse.left().value();
4341 } catch (ComponentException | StorageException e) {
4342 rollback(inTransaction, newResource, null, null);
4345 if (!inTransaction) {
4346 janusGraphDao.commit();
4349 graphLockOperation.unlockComponent(resourceIdToUpdate, NodeTypeEnum.Resource);
4354 private Either<Resource, ResponseFormat> updateResourceMetadata(String resourceIdToUpdate, Resource newResource, User user,
4355 Resource currentResource, boolean inTransaction) {
4356 updateVfModuleGroupsNames(currentResource, newResource);
4357 validateResourceFieldsBeforeUpdate(currentResource, newResource, inTransaction, false);
4358 // Setting last updater and uniqueId
4359 newResource.setContactId(newResource.getContactId().toLowerCase());
4360 newResource.setLastUpdaterUserId(user.getUserId());
4361 newResource.setUniqueId(resourceIdToUpdate);
4362 // Cannot set highest version through UI
4363 newResource.setHighestVersion(currentResource.isHighestVersion());
4364 newResource.setCreationDate(currentResource.getCreationDate());
4365 Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom = processUpdateOfDerivedFrom(currentResource, newResource, user.getUserId(),
4367 if (processUpdateOfDerivedFrom.isRight()) {
4368 log.debug("Couldn't update derived from for resource {}", resourceIdToUpdate);
4369 return Either.right(processUpdateOfDerivedFrom.right().value());
4371 log.debug("send resource {} to dao for update", newResource.getUniqueId());
4372 if (isNotEmpty(newResource.getGroups())) {
4373 for (GroupDefinition group : newResource.getGroups()) {
4374 if (DEFAULT_GROUP_VF_MODULE.equals(group.getType())) {
4376 .validateAndUpdateGroupMetadata(newResource.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId(), user,
4377 newResource.getComponentType(), group, true, false);
4381 Either<Resource, StorageOperationStatus> dataModelResponse = toscaOperationFacade.updateToscaElement(newResource);
4382 if (dataModelResponse.isRight()) {
4383 ResponseFormat responseFormat = componentsUtils
4384 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), newResource);
4385 return Either.right(responseFormat);
4386 } else if (dataModelResponse.left().value() == null) {
4387 log.debug("No response from updateResource");
4388 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
4390 return Either.left(dataModelResponse.left().value());
4393 private void updateVfModuleGroupsNames(Resource currentResource, Resource newResource) {
4394 if (currentResource.getGroups() != null && !currentResource.getName().equals(newResource.getName())) {
4395 List<GroupDefinition> updatedGroups = currentResource.getGroups().stream()
4396 .map(group -> getUpdatedGroup(group, currentResource.getName(), newResource.getName())).collect(toList());
4397 newResource.setGroups(updatedGroups);
4401 private GroupDefinition getUpdatedGroup(GroupDefinition currGroup, String replacePattern, String with) {
4402 GroupDefinition updatedGroup = new GroupDefinition(currGroup);
4403 if (updatedGroup.isSamePrefix(replacePattern) && updatedGroup.getType().equals(DEFAULT_GROUP_VF_MODULE)) {
4404 String prefix = updatedGroup.getName().substring(0, replacePattern.length());
4405 String newGroupName = updatedGroup.getName().replaceFirst(prefix, with);
4406 updatedGroup.setName(newGroupName);
4408 return updatedGroup;
4412 * validateResourceFieldsBeforeCreate
4414 * @param user - modifier data (userId)
4416 private void validateResourceFieldsBeforeCreate(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4417 componentValidator.validate(user, resource, actionEnum);
4418 // validate category
4419 log.debug("validate category");
4420 validateCategory(user, resource, actionEnum, inTransaction);
4421 // validate vendor name & release & model number
4422 log.debug("validate vendor name");
4423 validateVendorName(user, resource, actionEnum);
4424 log.debug("validate vendor release");
4425 validateVendorReleaseName(user, resource, actionEnum);
4426 log.debug("validate resource vendor model number");
4427 validateResourceVendorModelNumber(user, resource, actionEnum);
4429 log.debug("validate cost");
4430 validateCost(resource);
4431 // validate licenseType
4432 log.debug("validate licenseType");
4433 validateLicenseType(user, resource, actionEnum);
4434 // validate template (derived from)
4435 log.debug("validate derived from");
4436 if (!ModelConverter.isAtomicComponent(resource) && resource.getResourceType() != ResourceTypeEnum.CVFC) {
4437 resource.setDerivedFrom(null);
4439 validateDerivedFromExist(user, resource, actionEnum);
4440 // warn about non-updatable fields
4441 checkComponentFieldsForOverrideAttempt(resource);
4442 String currentCreatorFullName = resource.getCreatorFullName();
4443 if (currentCreatorFullName != null) {
4444 log.debug("Resource Creator fullname is automatically set and cannot be updated");
4446 String currentLastUpdaterFullName = resource.getLastUpdaterFullName();
4447 if (currentLastUpdaterFullName != null) {
4448 log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4450 Long currentLastUpdateDate = resource.getLastUpdateDate();
4451 if (currentLastUpdateDate != null) {
4452 log.debug("Resource last update date is automatically set and cannot be updated");
4454 Boolean currentAbstract = resource.isAbstract();
4455 if (currentAbstract != null) {
4456 log.debug("Resource abstract is automatically set and cannot be updated");
4461 * validateResourceFieldsBeforeUpdate
4463 * @param currentResource - Resource object to validate
4466 private void validateResourceFieldsBeforeUpdate(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4467 validateFields(currentResource, updateInfoResource, inTransaction, isNested);
4468 warnNonEditableFields(currentResource, updateInfoResource);
4471 private void warnNonEditableFields(Resource currentResource, Resource updateInfoResource) {
4472 String currentResourceVersion = currentResource.getVersion();
4473 String updatedResourceVersion = updateInfoResource.getVersion();
4474 if ((updatedResourceVersion != null) && (!updatedResourceVersion.equals(currentResourceVersion))) {
4475 log.debug("Resource version is automatically set and cannot be updated");
4477 String currentCreatorUserId = currentResource.getCreatorUserId();
4478 String updatedCreatorUserId = updateInfoResource.getCreatorUserId();
4479 if ((updatedCreatorUserId != null) && (!updatedCreatorUserId.equals(currentCreatorUserId))) {
4480 log.debug("Resource Creator UserId is automatically set and cannot be updated");
4482 String currentCreatorFullName = currentResource.getCreatorFullName();
4483 String updatedCreatorFullName = updateInfoResource.getCreatorFullName();
4484 if ((updatedCreatorFullName != null) && (!updatedCreatorFullName.equals(currentCreatorFullName))) {
4485 log.debug("Resource Creator fullname is automatically set and cannot be updated");
4487 String currentLastUpdaterUserId = currentResource.getLastUpdaterUserId();
4488 String updatedLastUpdaterUserId = updateInfoResource.getLastUpdaterUserId();
4489 if ((updatedLastUpdaterUserId != null) && (!updatedLastUpdaterUserId.equals(currentLastUpdaterUserId))) {
4490 log.debug("Resource LastUpdater userId is automatically set and cannot be updated");
4492 String currentLastUpdaterFullName = currentResource.getLastUpdaterFullName();
4493 String updatedLastUpdaterFullName = updateInfoResource.getLastUpdaterFullName();
4494 if ((updatedLastUpdaterFullName != null) && (!updatedLastUpdaterFullName.equals(currentLastUpdaterFullName))) {
4495 log.debug("Resource LastUpdater fullname is automatically set and cannot be updated");
4497 Long currentCreationDate = currentResource.getCreationDate();
4498 Long updatedCreationDate = updateInfoResource.getCreationDate();
4499 if ((updatedCreationDate != null) && (!updatedCreationDate.equals(currentCreationDate))) {
4500 log.debug("Resource Creation date is automatically set and cannot be updated");
4502 Long currentLastUpdateDate = currentResource.getLastUpdateDate();
4503 Long updatedLastUpdateDate = updateInfoResource.getLastUpdateDate();
4504 if ((updatedLastUpdateDate != null) && (!updatedLastUpdateDate.equals(currentLastUpdateDate))) {
4505 log.debug("Resource last update date is automatically set and cannot be updated");
4507 LifecycleStateEnum currentLifecycleState = currentResource.getLifecycleState();
4508 LifecycleStateEnum updatedLifecycleState = updateInfoResource.getLifecycleState();
4509 if ((updatedLifecycleState != null) && (!updatedLifecycleState.equals(currentLifecycleState))) {
4510 log.debug("Resource lifecycle state date is automatically set and cannot be updated");
4512 Boolean currentAbstract = currentResource.isAbstract();
4513 Boolean updatedAbstract = updateInfoResource.isAbstract();
4514 if ((updatedAbstract != null) && (!updatedAbstract.equals(currentAbstract))) {
4515 log.debug("Resource abstract is automatically set and cannot be updated");
4517 Boolean currentHighestVersion = currentResource.isHighestVersion();
4518 Boolean updatedHighestVersion = updateInfoResource.isHighestVersion();
4519 if ((updatedHighestVersion != null) && (!updatedHighestVersion.equals(currentHighestVersion))) {
4520 log.debug("Resource highest version is automatically set and cannot be updated");
4522 String currentUuid = currentResource.getUUID();
4523 String updatedUuid = updateInfoResource.getUUID();
4524 if ((updatedUuid != null) && (!updatedUuid.equals(currentUuid))) {
4525 log.debug("Resource UUID is automatically set and cannot be updated");
4527 log.debug("Resource Type cannot be updated");
4528 String currentInvariantUuid = currentResource.getInvariantUUID();
4529 String updatedInvariantUuid = updateInfoResource.getInvariantUUID();
4530 if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
4531 log.debug("Resource invariant UUID is automatically set and cannot be updated");
4532 updateInfoResource.setInvariantUUID(currentInvariantUuid);
4536 private void validateFields(Resource currentResource, Resource updateInfoResource, boolean inTransaction, boolean isNested) {
4537 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentResource.getVersion());
4538 log.debug("validate resource name before update");
4539 validateResourceName(currentResource, updateInfoResource, hasBeenCertified, isNested);
4540 log.debug("validate description before update");
4541 componentDescriptionValidator.validateAndCorrectField(null, updateInfoResource, null);
4542 log.debug("validate icon before update");
4543 validateIcon(currentResource, updateInfoResource, hasBeenCertified);
4544 log.debug("validate tags before update");
4545 componentTagsValidator.validateAndCorrectField(null, updateInfoResource, null);
4546 log.debug("validate vendor name before update");
4547 validateVendorName(null, updateInfoResource, null);
4548 log.debug("validate resource vendor model number before update");
4549 validateResourceVendorModelNumber(currentResource, updateInfoResource);
4550 log.debug("validate vendor release before update");
4551 validateVendorReleaseName(null, updateInfoResource, null);
4552 log.debug("validate contact info before update");
4553 componentContactIdValidator.validateAndCorrectField(null, updateInfoResource, null);
4554 log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
4555 validateDerivedFromDuringUpdate(currentResource, updateInfoResource, hasBeenCertified);
4556 log.debug("validate category before update");
4557 validateCategory(currentResource, updateInfoResource, hasBeenCertified, inTransaction);
4560 private boolean isResourceNameEquals(Resource currentResource, Resource updateInfoResource) {
4561 String resourceNameUpdated = updateInfoResource.getName();
4562 String resourceNameCurrent = currentResource.getName();
4563 if (resourceNameCurrent.equals(resourceNameUpdated)) {
4566 // In case of CVFC type we should support the case of old VF with CVFC
4568 // instances that were created without the "Cvfc" suffix
4569 return currentResource.getResourceType() == ResourceTypeEnum.CVFC && resourceNameUpdated
4570 .equals(addCvfcSuffixToResourceName(resourceNameCurrent));
4573 private String addCvfcSuffixToResourceName(String resourceName) {
4574 return resourceName + "Cvfc";
4577 private void validateResourceName(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified, boolean isNested) {
4578 String resourceNameUpdated = updateInfoResource.getName();
4579 if (!isResourceNameEquals(currentResource, updateInfoResource)) {
4580 if (isNested || !hasBeenCertified) {
4581 componentNameValidator.validateAndCorrectField(null, updateInfoResource, null);
4582 validateResourceNameUniqueness(updateInfoResource);
4583 currentResource.setName(resourceNameUpdated);
4584 currentResource.setNormalizedName(ValidationUtils.normaliseComponentName(resourceNameUpdated));
4585 currentResource.setSystemName(ValidationUtils.convertToSystemName(resourceNameUpdated));
4587 log.info("Resource name: {}, cannot be updated once the resource has been certified once.", resourceNameUpdated);
4588 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NAME_CANNOT_BE_CHANGED);
4593 private void validateIcon(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) {
4594 String iconUpdated = updateInfoResource.getIcon();
4595 String iconCurrent = currentResource.getIcon();
4596 if (!iconCurrent.equals(iconUpdated)) {
4597 if (!hasBeenCertified) {
4598 componentIconValidator.validateAndCorrectField(null, updateInfoResource, null);
4600 log.info("Icon {} cannot be updated once the resource has been certified once.", iconUpdated);
4601 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_ICON_CANNOT_BE_CHANGED);
4606 private void validateResourceVendorModelNumber(Resource currentResource, Resource updateInfoResource) {
4607 String updatedResourceVendorModelNumber = updateInfoResource.getResourceVendorModelNumber();
4608 String currentResourceVendorModelNumber = currentResource.getResourceVendorModelNumber();
4609 if (!currentResourceVendorModelNumber.equals(updatedResourceVendorModelNumber)) {
4610 validateResourceVendorModelNumber(null, updateInfoResource, null);
4614 private Either<Boolean, ResponseFormat> validateCategory(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified,
4615 boolean inTransaction) {
4616 validateCategory(null, updateInfoResource, null, inTransaction);
4617 if (hasBeenCertified) {
4618 CategoryDefinition currentCategory = currentResource.getCategories().get(0);
4619 SubCategoryDefinition currentSubCategory = currentCategory.getSubcategories().get(0);
4620 CategoryDefinition updateCategory = updateInfoResource.getCategories().get(0);
4621 SubCategoryDefinition updtaeSubCategory = updateCategory.getSubcategories().get(0);
4622 if (!currentCategory.getName().equals(updateCategory.getName()) || !currentSubCategory.getName().equals(updtaeSubCategory.getName())) {
4623 log.info("Category {} cannot be updated once the resource has been certified once.", currentResource.getCategories());
4624 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CATEGORY_CANNOT_BE_CHANGED);
4625 return Either.right(errorResponse);
4628 return Either.left(true);
4631 private Either<Boolean, ResponseFormat> validateDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4632 boolean hasBeenCertified) {
4633 List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4634 List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4635 if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4636 log.trace("Update normative types");
4637 return Either.left(true);
4639 String derivedFromCurrent = currentDerivedFrom.get(0);
4640 String derivedFromUpdated = updatedDerivedFrom.get(0);
4641 if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4642 if (!hasBeenCertified) {
4643 validateDerivedFromExist(null, updateInfoResource, null);
4645 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4647 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4648 log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4649 return validateDerivedFromExtending;
4653 // For derived from, we must know whether it was actually changed,
4655 // otherwise we must do no action.
4657 // Due to changes it inflicts on data model (remove artifacts,
4659 // properties...), it's not like a flat field which can be
4661 // overwritten if not changed.
4663 // So we must indicate that derived from is not changed
4664 updateInfoResource.setDerivedFrom(null);
4666 return Either.left(true);
4669 private Either<Boolean, ResponseFormat> validateNestedDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource,
4670 boolean hasBeenCertified) {
4671 List<String> currentDerivedFrom = currentResource.getDerivedFrom();
4672 List<String> updatedDerivedFrom = updateInfoResource.getDerivedFrom();
4673 if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) {
4674 log.trace("Update normative types");
4675 return Either.left(true);
4677 String derivedFromCurrent = currentDerivedFrom.get(0);
4678 String derivedFromUpdated = updatedDerivedFrom.get(0);
4679 if (!derivedFromCurrent.equals(derivedFromUpdated)) {
4680 if (!hasBeenCertified) {
4681 validateDerivedFromExist(null, updateInfoResource, null);
4683 Either<Boolean, ResponseFormat> validateDerivedFromExtending = validateDerivedFromExtending(null, currentResource, updateInfoResource,
4685 if (validateDerivedFromExtending.isRight() || !validateDerivedFromExtending.left().value()) {
4686 log.debug("Derived from cannot be updated if it doesnt inherits directly or extends inheritance");
4687 return validateDerivedFromExtending;
4691 return Either.left(true);
4694 private void validateDerivedFromExist(User user, Resource resource, AuditingActionEnum actionEnum) {
4695 if (resource.getDerivedFrom() == null || resource.getDerivedFrom().isEmpty()) {
4698 String templateName = resource.getDerivedFrom().get(0);
4699 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateToscaResourceNameExists(templateName);
4700 if (dataModelResponse.isRight()) {
4701 StorageOperationStatus storageStatus = dataModelResponse.right().value();
4702 BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateDerivedFromExist");
4703 log.debug("request to data model failed with error: {}", storageStatus);
4704 ResponseFormat responseFormat = componentsUtils
4705 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), resource);
4706 log.trace("audit before sending response");
4707 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4708 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageStatus));
4709 } else if (!dataModelResponse.left().value()) {
4710 log.info("resource template with name: {}, does not exists", templateName);
4711 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4712 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4713 throw new ByActionStatusComponentException(ActionStatus.PARENT_RESOURCE_NOT_FOUND);
4717 // Tal G for extending inheritance US815447
4718 private Either<Boolean, ResponseFormat> validateDerivedFromExtending(User user, Resource currentResource, Resource updateInfoResource,
4719 AuditingActionEnum actionEnum) {
4720 String currentTemplateName = currentResource.getDerivedFrom().get(0);
4721 String updatedTemplateName = updateInfoResource.getDerivedFrom().get(0);
4722 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
4723 .validateToscaResourceNameExtends(currentTemplateName, updatedTemplateName, currentResource.getModel());
4724 if (dataModelResponse.isRight()) {
4725 StorageOperationStatus storageStatus = dataModelResponse.right().value();
4726 BeEcompErrorManager.getInstance().logBeDaoSystemError("Create/Update Resource - validateDerivingFromExtendingType");
4727 ResponseFormat responseFormat = componentsUtils
4728 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), currentResource);
4729 log.trace("audit before sending response");
4730 componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4731 return Either.right(responseFormat);
4733 if (!dataModelResponse.left().value()) {
4734 log.info("resource template with name {} does not inherit as original {}", updatedTemplateName, currentTemplateName);
4735 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_DOES_NOT_EXTEND);
4736 componentsUtils.auditResource(responseFormat, user, currentResource, actionEnum);
4737 return Either.right(responseFormat);
4739 return Either.left(true);
4742 public void validateDerivedFromNotEmpty(User user, Resource resource, AuditingActionEnum actionEnum) {
4743 log.debug("validate resource derivedFrom field");
4744 if ((resource.getDerivedFrom() == null) || (resource.getDerivedFrom().isEmpty()) || (resource.getDerivedFrom().get(0)) == null || (resource
4745 .getDerivedFrom().get(0).trim().isEmpty())) {
4746 log.info("derived from (template) field is missing for the resource");
4747 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4748 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4749 throw new ByActionStatusComponentException(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE);
4753 private void validateResourceNameUniqueness(Resource resource) {
4754 Either<Boolean, StorageOperationStatus> resourceOperationResponse = toscaOperationFacade
4755 .validateComponentNameExists(resource.getName(), resource.getResourceType(), resource.getComponentType());
4756 if (resourceOperationResponse.isLeft() && resourceOperationResponse.left().value()) {
4757 log.debug("resource with name: {}, already exists", resource.getName());
4758 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(),
4759 resource.getName());
4760 } else if (resourceOperationResponse.isRight()) {
4761 log.debug("error while validateResourceNameExists for resource: {}", resource.getName());
4762 throw new StorageException(resourceOperationResponse.right().value());
4766 private void validateCategory(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) {
4767 List<CategoryDefinition> categories = resource.getCategories();
4768 if (CollectionUtils.isEmpty(categories)) {
4769 log.debug(CATEGORY_IS_EMPTY);
4770 ResponseFormat responseFormat = componentsUtils
4771 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4772 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4773 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4775 if (categories.size() > 1) {
4776 log.debug("Must be only one category for resource");
4777 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.RESOURCE.getValue());
4779 CategoryDefinition category = categories.get(0);
4780 List<SubCategoryDefinition> subcategories = category.getSubcategories();
4781 if (CollectionUtils.isEmpty(subcategories)) {
4782 log.debug("Missinig subcategory for resource");
4783 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY);
4785 if (subcategories.size() > 1) {
4786 log.debug("Must be only one sub category for resource");
4787 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_TOO_MUCH_SUBCATEGORIES);
4789 SubCategoryDefinition subcategory = subcategories.get(0);
4790 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
4791 log.debug(CATEGORY_IS_EMPTY);
4792 ResponseFormat responseFormat = componentsUtils
4793 .getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4794 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4795 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4797 if (!ValidationUtils.validateStringNotEmpty(subcategory.getName())) {
4798 log.debug(CATEGORY_IS_EMPTY);
4799 ResponseFormat responseFormat = componentsUtils
4800 .getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4801 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4802 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4804 validateCategoryListed(category, subcategory, user, resource, actionEnum, inTransaction);
4807 private void validateCategoryListed(CategoryDefinition category, SubCategoryDefinition subcategory, User user, Resource resource,
4808 AuditingActionEnum actionEnum, boolean inTransaction) {
4809 ResponseFormat responseFormat;
4810 if (category != null && subcategory != null) {
4811 log.debug("validating resource category {} against valid categories list", category);
4812 Either<List<CategoryDefinition>, ActionStatus> categories = elementDao.getAllCategories(NodeTypeEnum.ResourceNewCategory, inTransaction);
4813 if (categories.isRight()) {
4814 log.debug("failed to retrieve resource categories from JanusGraph");
4815 responseFormat = componentsUtils.getResponseFormat(categories.right().value());
4816 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4817 throw new ByActionStatusComponentException(categories.right().value());
4819 List<CategoryDefinition> categoryList = categories.left().value();
4820 Optional<CategoryDefinition> foundCategory = categoryList.stream().filter(cat -> cat.getName().equals(category.getName())).findFirst();
4821 if (foundCategory.isEmpty()) {
4822 log.debug("Category {} is not part of resource category group. Resource category valid values are {}", category, categoryList);
4823 failOnInvalidCategory(user, resource, actionEnum);
4824 return; // explisite output even if failOnInvalidCategory throw an exception
4826 Optional<SubCategoryDefinition> foundSubcategory = foundCategory.get().getSubcategories().stream()
4827 .filter(subcat -> subcat.getName().equals(subcategory.getName())).findFirst();
4828 if (foundSubcategory.isEmpty()) {
4829 log.debug("SubCategory {} is not part of resource category group. Resource subcategory valid values are {}", subcategory,
4830 foundCategory.get().getSubcategories());
4831 failOnInvalidCategory(user, resource, actionEnum);
4836 private void failOnInvalidCategory(User user, Resource resource, AuditingActionEnum actionEnum) {
4837 ResponseFormat responseFormat;
4838 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4839 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4840 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue());
4843 public void validateVendorReleaseName(User user, Resource resource, AuditingActionEnum actionEnum) {
4844 String vendorRelease = resource.getVendorRelease();
4845 log.debug("validate vendor relese name");
4846 if (!ValidationUtils.validateStringNotEmpty(vendorRelease)) {
4847 log.info("vendor relese name is missing.");
4848 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_RELEASE);
4849 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4850 throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_RELEASE);
4852 validateVendorReleaseName(vendorRelease, user, resource, actionEnum);
4855 public void validateVendorReleaseName(String vendorRelease, User user, Resource resource, AuditingActionEnum actionEnum) {
4856 if (vendorRelease != null) {
4857 if (!ValidationUtils.validateVendorReleaseLength(vendorRelease)) {
4858 log.info("vendor release exceds limit.");
4859 ResponseFormat errorResponse = componentsUtils
4860 .getResponseFormat(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4861 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4862 throw new ByActionStatusComponentException(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH);
4864 if (!ValidationUtils.validateVendorRelease(vendorRelease)) {
4865 log.info("vendor release is not valid.");
4866 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_RELEASE);
4867 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4868 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_RELEASE, vendorRelease);
4873 private void validateVendorName(User user, Resource resource, AuditingActionEnum actionEnum) {
4874 String vendorName = resource.getVendorName();
4875 if (!ValidationUtils.validateStringNotEmpty(vendorName)) {
4876 log.info("vendor name is missing.");
4877 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_NAME);
4878 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4879 throw new ByActionStatusComponentException(ActionStatus.MISSING_VENDOR_NAME);
4881 validateVendorName(vendorName, user, resource, actionEnum);
4884 private void validateVendorName(String vendorName, User user, Resource resource, AuditingActionEnum actionEnum) {
4885 if (vendorName != null) {
4886 if (!ValidationUtils.validateVendorNameLength(vendorName)) {
4887 log.info("vendor name exceds limit.");
4888 ResponseFormat errorResponse = componentsUtils
4889 .getResponseFormat(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4890 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4891 throw new ByActionStatusComponentException(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH);
4893 if (!ValidationUtils.validateVendorName(vendorName)) {
4894 log.info("vendor name is not valid.");
4895 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_NAME);
4896 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4897 throw new ByActionStatusComponentException(ActionStatus.INVALID_VENDOR_NAME, vendorName);
4902 private void validateResourceVendorModelNumber(User user, Resource resource, AuditingActionEnum actionEnum) {
4903 String resourceVendorModelNumber = resource.getResourceVendorModelNumber();
4904 if (StringUtils.isNotEmpty(resourceVendorModelNumber)) {
4905 if (!ValidationUtils.validateResourceVendorModelNumberLength(resourceVendorModelNumber)) {
4906 log.info("resource vendor model number exceeds limit.");
4907 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4908 "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4909 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4910 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT,
4911 "" + ValidationUtils.RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH);
4913 // resource vendor model number is currently validated as vendor
4916 if (!ValidationUtils.validateVendorName(resourceVendorModelNumber)) {
4917 log.info("resource vendor model number is not valid.");
4918 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4919 componentsUtils.auditResource(errorResponse, user, resource, actionEnum);
4920 throw new ByActionStatusComponentException(ActionStatus.INVALID_RESOURCE_VENDOR_MODEL_NUMBER);
4925 private void validateCost(Resource resource) {
4926 String cost = resource.getCost();
4928 if (!ValidationUtils.validateCost(cost)) {
4929 log.debug("resource cost is invalid.");
4930 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4935 private void validateLicenseType(User user, Resource resource, AuditingActionEnum actionEnum) {
4936 log.debug("validate licenseType");
4937 String licenseType = resource.getLicenseType();
4938 if (licenseType != null) {
4939 List<String> licenseTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getLicenseTypes();
4940 if (!licenseTypes.contains(licenseType)) {
4941 log.debug("License type {} isn't configured", licenseType);
4942 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
4943 if (actionEnum != null) {
4944 // In update case, no audit is required
4945 componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
4947 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
4952 private Either<Boolean, ResponseFormat> processUpdateOfDerivedFrom(Resource currentResource, Resource updatedResource, String userId,
4953 boolean inTransaction) {
4954 if (updatedResource.getDerivedFrom() != null) {
4955 log.debug("Starting derived from update for resource {}", updatedResource.getUniqueId());
4956 log.debug("1. Removing interface artifacts from graph");
4957 // Remove all interface artifacts of resource
4958 String resourceId = updatedResource.getUniqueId();
4959 Map<String, InterfaceDefinition> interfaces = currentResource.getInterfaces();
4960 if (interfaces != null) {
4961 Collection<InterfaceDefinition> values = interfaces.values();
4962 for (InterfaceDefinition interfaceDefinition : values) {
4963 String interfaceType = interfaceTypeOperation.getShortInterfaceName(interfaceDefinition);
4964 log.trace("Starting interface artifacts removal for interface type {}", interfaceType);
4965 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
4966 if (operations != null) {
4967 for (Entry<String, Operation> operationEntry : operations.entrySet()) {
4968 Operation operation = operationEntry.getValue();
4969 ArtifactDefinition implementation = operation.getImplementationArtifact();
4970 if (implementation != null) {
4971 String uniqueId = implementation.getUniqueId();
4972 log.debug("Removing interface artifact definition {}, operation {}, interfaceType {}", uniqueId,
4973 operationEntry.getKey(), interfaceType);
4974 // only thing that transacts and locks here
4975 Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface = artifactsBusinessLogic
4976 .deleteArtifactByInterface(resourceId, userId, uniqueId, true);
4977 if (deleteArtifactByInterface.isRight()) {
4978 log.debug("Couldn't remove artifact definition with id {}", uniqueId);
4979 if (!inTransaction) {
4980 janusGraphDao.rollback();
4982 return Either.right(deleteArtifactByInterface.right().value());
4985 log.trace("No implementation found for operation {} - nothing to delete", operationEntry.getKey());
4989 log.trace("No operations found for interface type {}", interfaceType);
4993 log.debug("2. Removing properties");
4994 Either<Map<String, PropertyDefinition>, StorageOperationStatus> findPropertiesOfNode = propertyOperation
4995 .deleteAllPropertiesAssociatedToNode(NodeTypeEnum.Resource, resourceId);
4996 if (findPropertiesOfNode.isRight() && findPropertiesOfNode.right().value() != StorageOperationStatus.OK) {
4997 log.debug("Failed to remove all properties of resource");
4998 if (!inTransaction) {
4999 janusGraphDao.rollback();
5002 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findPropertiesOfNode.right().value())));
5005 log.debug("Derived from wasn't changed during update");
5007 if (inTransaction) {
5008 return Either.left(true);
5010 janusGraphDao.commit();
5011 return Either.left(true);
5014 public ICapabilityTypeOperation getCapabilityTypeOperation() {
5015 return capabilityTypeOperation;
5019 public void setCapabilityTypeOperation(ICapabilityTypeOperation capabilityTypeOperation) {
5020 this.capabilityTypeOperation = capabilityTypeOperation;
5023 public Boolean validatePropertiesDefaultValues(Resource resource) {
5024 log.debug("validate resource properties default values");
5025 List<PropertyDefinition> properties = resource.getProperties();
5026 if (properties != null) {
5027 iterateOverProperties(properties, resource.getModel());
5032 public void iterateOverProperties(List<PropertyDefinition> properties, String model) {
5033 for (PropertyDefinition property : properties) {
5034 if (!propertyOperation.isPropertyTypeValid(property, model)) {
5035 log.info("Invalid type for property {}", property);
5036 throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
5038 Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
5039 String type = property.getType();
5040 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5041 ResponseFormat responseFormat = validateMapOrListPropertyType(property, allDataTypes);
5042 if (responseFormat != null) {
5046 validateDefaultPropertyValue(property, allDataTypes, type);
5050 private void validateDefaultPropertyValue(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes, String type) {
5051 if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes)) {
5052 log.info("Invalid default value for property {}", property);
5053 ResponseFormat responseFormat;
5054 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
5055 throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type,
5056 property.getDefaultValue());
5058 throw new ByActionStatusComponentException(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
5062 private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property,
5063 Map<String, DataTypeDefinition> allDataTypes) {
5064 ResponseFormat responseFormat = null;
5065 ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, allDataTypes);
5066 String innerType = propertyInnerTypeValid.getLeft();
5067 if (Boolean.FALSE.equals(propertyInnerTypeValid.getRight())) {
5068 log.info("Invalid inner type for property {}", property);
5069 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
5071 return responseFormat;
5075 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
5076 return deleteMarkedComponents(ComponentTypeEnum.RESOURCE);
5080 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
5081 return componentInstanceBusinessLogic;
5084 private String getComponentTypeForResponse(Component component) {
5085 String componentTypeForResponse = "SERVICE";
5086 if (component instanceof Resource) {
5087 componentTypeForResponse = ((Resource) component).getResourceType().name();
5089 return componentTypeForResponse;
5092 public Either<Resource, ResponseFormat> getLatestResourceFromCsarUuid(String csarUuid, User user) {
5095 validateUserExists(user);
5097 // get resource from csar uuid
5098 Either<Resource, StorageOperationStatus> either = toscaOperationFacade
5099 .getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, csarUuid, "");
5100 if (either.isRight()) {
5101 ResponseFormat resp = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUuid);
5102 return Either.right(resp);
5104 return Either.left(either.left().value());
5108 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
5112 private Map<String, List<CapabilityDefinition>> getValidComponentInstanceCapabilities(String resourceId,
5113 Map<String, List<CapabilityDefinition>> defaultCapabilities,
5114 Map<String, List<UploadCapInfo>> uploadedCapabilities) {
5115 Map<String, List<CapabilityDefinition>> validCapabilitiesMap = new HashMap<>();
5116 uploadedCapabilities.forEach((k, v) -> addValidComponentInstanceCapabilities(k, v, resourceId, defaultCapabilities, validCapabilitiesMap));
5117 return validCapabilitiesMap;
5120 private void addValidComponentInstanceCapabilities(String key, List<UploadCapInfo> capabilities, String resourceId,
5121 Map<String, List<CapabilityDefinition>> defaultCapabilities,
5122 Map<String, List<CapabilityDefinition>> validCapabilitiesMap) {
5123 String capabilityType = capabilities.get(0).getType();
5124 if (defaultCapabilities.containsKey(capabilityType)) {
5125 CapabilityDefinition defaultCapability = getCapability(resourceId, defaultCapabilities, capabilityType);
5126 validateCapabilityProperties(capabilities, resourceId, defaultCapability);
5127 List<CapabilityDefinition> validCapabilityList = new ArrayList<>();
5128 validCapabilityList.add(defaultCapability);
5129 validCapabilitiesMap.put(key, validCapabilityList);
5131 throw new ByActionStatusComponentException(ActionStatus.MISSING_CAPABILITY_TYPE, capabilityType);
5135 private void validateCapabilityProperties(List<UploadCapInfo> capabilities, String resourceId, CapabilityDefinition defaultCapability) {
5136 if (CollectionUtils.isEmpty(defaultCapability.getProperties()) && isNotEmpty(capabilities.get(0).getProperties())) {
5137 log.debug("Failed to validate capability {} of component {}. Property list is empty. ", defaultCapability.getName(), resourceId);
5138 log.debug("Failed to update capability property values. Property list of fetched capability {} is empty. ", defaultCapability.getName());
5139 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, resourceId);
5140 } else if (isNotEmpty(capabilities.get(0).getProperties())) {
5141 validateUniquenessUpdateUploadedComponentInstanceCapability(defaultCapability, capabilities.get(0));
5145 private CapabilityDefinition getCapability(String resourceId, Map<String, List<CapabilityDefinition>> defaultCapabilities,
5146 String capabilityType) {
5147 CapabilityDefinition defaultCapability;
5148 if (isNotEmpty(defaultCapabilities.get(capabilityType).get(0).getProperties())) {
5149 defaultCapability = defaultCapabilities.get(capabilityType).get(0);
5151 Either<Component, StorageOperationStatus> getFullComponentRes = toscaOperationFacade.getToscaFullElement(resourceId);
5152 if (getFullComponentRes.isRight()) {
5153 log.debug("Failed to get full component {}. Status is {}. ", resourceId, getFullComponentRes.right().value());
5154 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, resourceId);
5156 defaultCapability = getFullComponentRes.left().value().getCapabilities().get(capabilityType).get(0);
5158 return defaultCapability;
5161 private void validateUniquenessUpdateUploadedComponentInstanceCapability(CapabilityDefinition defaultCapability,
5162 UploadCapInfo uploadedCapability) {
5163 List<ComponentInstanceProperty> validProperties = new ArrayList<>();
5164 Map<String, PropertyDefinition> defaultProperties = defaultCapability.getProperties().stream()
5165 .collect(toMap(PropertyDefinition::getName, Function.identity()));
5166 List<UploadPropInfo> uploadedProperties = uploadedCapability.getProperties();
5167 for (UploadPropInfo property : uploadedProperties) {
5168 String propertyName = property.getName().toLowerCase();
5169 String propertyType = property.getType();
5170 ComponentInstanceProperty validProperty;
5171 if (defaultProperties.containsKey(propertyName) && propertTypeEqualsTo(defaultProperties, propertyName, propertyType)) {
5172 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, propertyName);
5174 validProperty = new ComponentInstanceProperty();
5175 validProperty.setName(propertyName);
5176 if (property.getValue() != null) {
5177 validProperty.setValue(property.getValue().toString());
5179 validProperty.setDescription(property.getDescription());
5180 validProperty.setPassword(property.isPassword());
5181 validProperties.add(validProperty);
5183 defaultCapability.setProperties(validProperties);
5186 private boolean propertTypeEqualsTo(Map<String, PropertyDefinition> defaultProperties, String propertyName, String propertyType) {
5187 return propertyType != null && !defaultProperties.get(propertyName).getType().equals(propertyType);
5190 private Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> organizeVfCsarArtifactsByArtifactOperation(
5191 List<NonMetaArtifactInfo> artifactPathAndNameList, List<ArtifactDefinition> existingArtifactsToHandle, Resource resource, User user) {
5192 EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> nodeTypeArtifactsToHandle = new EnumMap<>(ArtifactOperationEnum.class);
5193 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
5194 Either<EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>>, ResponseFormat> nodeTypeArtifactsToHandleRes = Either
5195 .left(nodeTypeArtifactsToHandle);
5197 // add all found Csar artifacts to list to upload
5198 List<NonMetaArtifactInfo> artifactsToUpload = new ArrayList<>(artifactPathAndNameList);
5199 List<NonMetaArtifactInfo> artifactsToUpdate = new ArrayList<>();
5200 List<NonMetaArtifactInfo> artifactsToDelete = new ArrayList<>();
5201 for (NonMetaArtifactInfo currNewArtifact : artifactPathAndNameList) {
5202 ArtifactDefinition foundArtifact;
5203 if (!existingArtifactsToHandle.isEmpty()) {
5204 foundArtifact = existingArtifactsToHandle.stream().filter(a -> a.getArtifactName().equals(currNewArtifact.getArtifactName()))
5205 .findFirst().orElse(null);
5206 if (foundArtifact != null) {
5207 if (foundArtifact.getArtifactType().equals(currNewArtifact.getArtifactType())) {
5208 if (!foundArtifact.getArtifactChecksum().equals(currNewArtifact.getArtifactChecksum())) {
5209 currNewArtifact.setArtifactUniqueId(foundArtifact.getUniqueId());
5210 // if current artifact already exists, but has
5212 // different content, add him to the list to
5215 artifactsToUpdate.add(currNewArtifact);
5217 // remove found artifact from the list of existing
5219 // artifacts to handle, because it was already
5222 existingArtifactsToHandle.remove(foundArtifact);
5223 // and remove found artifact from the list to
5225 // upload, because it should either be updated or be
5228 artifactsToUpload.remove(currNewArtifact);
5230 log.debug("Can't upload two artifact with the same name {}.", currNewArtifact.getArtifactName());
5231 ResponseFormat responseFormat = ResponseFormatManager.getInstance()
5232 .getResponseFormat(ActionStatus.ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, currNewArtifact.getArtifactName(),
5233 currNewArtifact.getArtifactType(), foundArtifact.getArtifactType());
5234 AuditingActionEnum auditingAction = artifactsBusinessLogic
5235 .detectAuditingType(new ArtifactOperationInfo(false, false, ArtifactOperationEnum.CREATE),
5236 foundArtifact.getArtifactChecksum());
5237 artifactsBusinessLogic
5238 .handleAuditing(auditingAction, resource, resource.getUniqueId(), user, null, null, foundArtifact.getUniqueId(),
5239 responseFormat, resource.getComponentType(), null);
5240 responseWrapper.setInnerElement(responseFormat);
5246 if (responseWrapper.isEmpty()) {
5247 for (ArtifactDefinition currArtifact : existingArtifactsToHandle) {
5248 if (currArtifact.getIsFromCsar()) {
5249 artifactsToDelete.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5250 currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5252 artifactsToUpdate.add(new NonMetaArtifactInfo(currArtifact.getArtifactName(), null, currArtifact.getArtifactType(),
5253 currArtifact.getArtifactGroupType(), null, currArtifact.getUniqueId(), currArtifact.getIsFromCsar()));
5257 if (responseWrapper.isEmpty()) {
5258 if (!artifactsToUpload.isEmpty()) {
5259 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.CREATE, artifactsToUpload);
5261 if (!artifactsToUpdate.isEmpty()) {
5262 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.UPDATE, artifactsToUpdate);
5264 if (!artifactsToDelete.isEmpty()) {
5265 nodeTypeArtifactsToHandle.put(ArtifactOperationEnum.DELETE, artifactsToDelete);
5268 if (!responseWrapper.isEmpty()) {
5269 nodeTypeArtifactsToHandleRes = Either.right(responseWrapper.getInnerElement());
5271 } catch (Exception e) {
5272 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
5273 responseWrapper.setInnerElement(responseFormat);
5274 log.debug("Exception occurred when findNodeTypeArtifactsToHandle, error is:{}", e.getMessage(), e);
5276 return nodeTypeArtifactsToHandleRes;
5279 ImmutablePair<String, String> buildNestedToscaResourceName(final String nodeResourceType, final String vfResourceName,
5280 final String nodeTypeFullName) {
5282 String actualVfName;
5283 if (ResourceTypeEnum.CVFC.name().equals(nodeResourceType)) {
5284 actualVfName = vfResourceName + ResourceTypeEnum.CVFC.name();
5285 actualType = ResourceTypeEnum.VFC.name();
5287 actualVfName = vfResourceName;
5288 actualType = nodeResourceType;
5290 String nameWithouNamespacePrefix;
5292 final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
5293 log.debug("####### buildNestedToscaResourceName nodeResourceType {}, vfResourceName {}, "
5294 + "nodeTypeFullName {}, actualType {}, vfResourceName {} ", nodeResourceType, vfResourceName, nodeTypeFullName, actualType,
5296 final StringBuilder toscaResourceName = new StringBuilder(nodeTypeNamePrefix);
5297 if (!nodeTypeFullName.contains(nodeTypeNamePrefix)) {
5298 nameWithouNamespacePrefix = nodeTypeFullName;
5300 nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.length());
5302 final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
5304 if (nodeResourceType.equalsIgnoreCase(findTypes[0])) {
5305 actualName = nameWithouNamespacePrefix.substring(nodeResourceType.length());
5307 actualName = "." + nameWithouNamespacePrefix;
5309 if (actualName.startsWith(Constants.ABSTRACT)) {
5310 toscaResourceName.append(nodeResourceType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName));
5312 toscaResourceName.append(actualType.toLowerCase()).append('.').append(ValidationUtils.convertToSystemName(actualVfName)).append('.')
5313 .append(Constants.ABSTRACT);
5315 final StringBuilder previousToscaResourceName = new StringBuilder(toscaResourceName);
5316 final String[] actualNames = actualName.split("\\.");
5317 if (actualNames.length < 3) {
5318 return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5319 previousToscaResourceName.append(actualName).toString());
5321 return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(),
5322 previousToscaResourceName.append(actualName.substring(actualNames[1].length() + 1).toLowerCase()).toString());
5323 } catch (final Exception e) {
5324 log.debug("Exception occured when buildNestedToscaResourceName, error is:{}", e.getMessage(), e);
5325 throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE, vfResourceName);
5330 * Extracts a Node Type Name prefix from the given Node Type Name.
5332 * @param fullName Node Type Name
5333 * @return Node Type Name Prefix
5335 private String getNodeTypeNamePrefix(final String fullName) {
5336 String tempPrefix = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX;
5337 final List<String> definedNodeTypeNamespaceList = getDefinedNodeTypeNamespaceList();
5338 log.debug("************* getPrefiX fullName {} FROM {}", fullName, definedNodeTypeNamespaceList);
5339 final Optional<String> validNameSpace = validateNodeTypeNamePrefix(fullName, definedNodeTypeNamespaceList);
5340 if (validNameSpace.isPresent()) {
5341 tempPrefix = validNameSpace.get();
5343 log.debug("************* getNodeTypeNamePrefix return fullName {} ", tempPrefix);
5348 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId,
5349 List<String> dataParamsToReturn) {
5350 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
5351 Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, paramsToReturn);
5352 if (resourceResultEither.isRight()) {
5353 if (resourceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
5354 log.debug("Failed to found resource with id {} ", resourceId);
5355 Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
5357 log.debug("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn);
5358 return Either.right(
5359 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceResultEither.right().value()), ""));
5361 Resource resource = resourceResultEither.left().value();
5362 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
5363 ListUtils.emptyIfNull(resource.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
5365 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromResourceByParams(resource, dataParamsToReturn);
5366 return Either.left(dataTransfer);
5370 public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
5371 Resource resource = (Resource) clonedComponent;
5372 if (ModelConverter.isAtomicComponent(resource.getResourceType())) {
5373 Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived = toscaOperationFacade.shouldUpgradeToLatestDerived(resource);
5374 if (shouldUpgradeToLatestDerived.isRight()) {
5375 return Either.right(componentsUtils.convertFromStorageResponse(shouldUpgradeToLatestDerived.right().value()));
5377 return Either.left(shouldUpgradeToLatestDerived.left().value());
5379 return super.shouldUpgradeToLatestDerived(clonedComponent);