2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.be.components.impl;
19 import fj.data.Either;
20 import org.apache.commons.collections.CollectionUtils;
21 import org.apache.commons.collections.MapUtils;
22 import org.apache.commons.lang.StringUtils;
23 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
24 import org.openecomp.sdc.be.components.validation.CapabilitiesValidation;
25 import org.openecomp.sdc.be.config.BeEcompErrorManager;
26 import org.openecomp.sdc.be.dao.api.ActionStatus;
27 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
28 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
29 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
30 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
31 import org.openecomp.sdc.be.model.CapabilityDefinition;
32 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
33 import org.openecomp.sdc.be.model.Component;
34 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
35 import org.openecomp.sdc.be.model.ComponentParametersView;
36 import org.openecomp.sdc.be.model.User;
37 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
38 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.CapabilitiesOperation;
39 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
41 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
42 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
43 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
44 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
45 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
46 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
47 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
48 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
49 import org.openecomp.sdc.exception.ResponseFormat;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52 import org.springframework.beans.factory.annotation.Autowired;
54 import java.util.ArrayList;
55 import java.util.Collection;
56 import java.util.Collections;
57 import java.util.HashMap;
58 import java.util.List;
60 import java.util.Objects;
61 import java.util.Optional;
62 import java.util.UUID;
63 import java.util.stream.Collectors;
65 @org.springframework.stereotype.Component("capabilitiesBusinessLogic")
66 public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
67 private static final Logger LOGGER = LoggerFactory.getLogger(CapabilitiesBusinessLogic.class);
68 private static final String FAILED_TO_LOCK_COMPONENT_RESPONSE_IS = "Failed to lock component {}. Response is {}";
69 private static final String DELETE_CAPABILITIES = "deleteCapability";
70 private static final String GET_CAPABILITIES = "getCapabilities";
71 private static final String EXCEPTION_OCCURRED_DURING_CAPABILITIES = "Exception occurred during {}. Response is {}";
73 private final ICapabilityTypeOperation capabilityTypeOperation;
75 private CapabilitiesOperation capabilitiesOperation;
76 private CapabilitiesValidation capabilitiesValidation;
79 public CapabilitiesBusinessLogic(IElementOperation elementDao,
80 IGroupOperation groupOperation,
81 IGroupInstanceOperation groupInstanceOperation,
82 IGroupTypeOperation groupTypeOperation,
83 GroupBusinessLogic groupBusinessLogic,
84 InterfaceOperation interfaceOperation,
85 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
86 ICapabilityTypeOperation capabilityTypeOperation,
87 ArtifactsOperations artifactToscaOperation) {
88 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
89 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
90 this.capabilityTypeOperation = capabilityTypeOperation;
94 public void setCapabilitiesValidation(CapabilitiesValidation capabilitiesValidation) {
95 this.capabilitiesValidation = capabilitiesValidation;
99 public void setCapabilitiesOperation(CapabilitiesOperation capabilitiesOperation) {
100 this.capabilitiesOperation = capabilitiesOperation;
103 public Either<List<CapabilityDefinition>, ResponseFormat> createCapabilities(String componentId,
104 List<CapabilityDefinition> capabilityDefinitions,
105 User user, String errorContext, boolean lock) {
106 Either<Component, ResponseFormat> validateUserAndCapabilitiesEither =
107 validateUserAndCapabilities(user, componentId, errorContext, capabilityDefinitions);
108 if(validateUserAndCapabilitiesEither.isRight()) {
109 return Either.right(validateUserAndCapabilitiesEither.right().value());
111 Component storedComponent = validateUserAndCapabilitiesEither.left().value();
113 Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, errorContext);
114 if (lockResult.isRight()) {
115 return Either.right(lockResult.right().value());
118 return createCapability(componentId, capabilityDefinitions, storedComponent);
119 } catch (Exception e) {
120 janusGraphDao.rollback();
121 LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "addOrUpdate", e);
122 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
124 if (lockResult.isLeft() && lockResult.left().value()) {
125 graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
126 NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
132 private Either<Component, ResponseFormat> validateUserAndCapabilities(User user, String componentId,
134 List<CapabilityDefinition> capabilityDefinitions ) {
135 validateUserExists(user.getUserId());
136 Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
137 if (componentEither.isRight()) {
138 return Either.right(componentEither.right().value());
140 Component storedComponent = componentEither.left().value();
141 Either<Boolean, ResponseFormat> capabilitiesValidationEither = capabilitiesValidation
142 .validateCapabilities(capabilityDefinitions, storedComponent, false);
143 if (capabilitiesValidationEither.isRight()) {
144 return Either.right(capabilitiesValidationEither.right().value());
146 return Either.left(storedComponent);
149 private Either<List<CapabilityDefinition>, ResponseFormat> createCapability(String componentId,
150 List<CapabilityDefinition> capabilityDefinitions,
151 Component storedComponent) {
152 Either<List<CapabilityDefinition>, StorageOperationStatus> result;
153 List<CapabilityDefinition> capabilitiesListStoredInComponent = null;
154 Map<String, List<CapabilityDefinition>> storedComponentCapabilities = storedComponent.getCapabilities();
155 if (MapUtils.isNotEmpty(storedComponentCapabilities)) {
156 CapabilityDefinition capabilityDefinitionToGetType = capabilityDefinitions.get(0);
157 if (Objects.isNull(capabilityDefinitionToGetType)) {
158 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
160 capabilitiesListStoredInComponent = getCapabilityStoredInComponentByType(capabilityDefinitionToGetType
161 .getType(), storedComponentCapabilities);
163 List<CapabilityDefinition> capabilitiesDefListToCreate;
164 List<CapabilityDefinition> capabilitiesToReturn;
165 if (CollectionUtils.isNotEmpty(capabilitiesListStoredInComponent)) {
166 capabilitiesDefListToCreate = capabilityDefinitions.stream().map(capabilityDefinition ->
167 initiateNewCapability(storedComponent, capabilityDefinition)).collect(Collectors.toList());
168 capabilitiesToReturn = capabilitiesDefListToCreate;
169 capabilitiesDefListToCreate.addAll(capabilitiesListStoredInComponent);
170 result = capabilitiesOperation.updateCapabilities(componentId, capabilitiesDefListToCreate);
172 capabilitiesToReturn = capabilityDefinitions.stream().map(capabilityDefinition ->
173 initiateNewCapability(storedComponent, capabilityDefinition)).collect(Collectors.toList());
174 result = capabilitiesOperation.addCapabilities(componentId, capabilitiesToReturn);
176 if (result.isRight()) {
177 janusGraphDao.rollback();
178 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result
179 .right().value(), storedComponent.getComponentType()), ""));
181 Map<String, MapPropertiesDataDefinition> propertiesMap =
182 getCapabilitiesPropertiesDataDefinitionMap(capabilityDefinitions);
183 if (MapUtils.isNotEmpty(propertiesMap)) {
184 StorageOperationStatus storageOperationStatus = capabilitiesOperation
185 .createOrUpdateCapabilityProperties(componentId, propertiesMap);
186 if (storageOperationStatus != StorageOperationStatus.OK) {
187 janusGraphDao.rollback();
188 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
191 janusGraphDao.commit();
192 return Either.left(capabilitiesToReturn);
195 public Either<List<CapabilityDefinition>, ResponseFormat> updateCapabilities(String componentId,
196 List<CapabilityDefinition> capabilityDefinitions,
197 User user, String errorContext, boolean lock) {
198 validateUserExists(user.getUserId());
199 Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
200 if (componentEither.isRight()) {
201 return Either.right(componentEither.right().value());
203 Component storedComponent = componentEither.left().value();
204 Either<Boolean, ResponseFormat> capabilitiesValidationEither = capabilitiesValidation
205 .validateCapabilities(capabilityDefinitions, storedComponent, true);
206 if (capabilitiesValidationEither.isRight()) {
207 return Either.right(capabilitiesValidationEither.right().value());
210 Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, errorContext);
211 if (lockResult.isRight()) {
212 return Either.right(lockResult.right().value());
215 Either<List<CapabilityDefinition>, StorageOperationStatus> result;
216 List<CapabilityDefinition> capabilitiesListStoredInComponent = null;
217 Map<String, List<CapabilityDefinition>> storedComponentCapabilities = storedComponent.getCapabilities();
218 if (org.apache.commons.collections.MapUtils.isNotEmpty(storedComponentCapabilities)) {
219 CapabilityDefinition capabilityDefinitionToGetType = capabilityDefinitions.get(0);
220 if (Objects.isNull(capabilityDefinitionToGetType)) {
221 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
223 capabilitiesListStoredInComponent = getCapabilityStoredInComponentByType(capabilityDefinitionToGetType
224 .getType(), storedComponentCapabilities);
226 List<CapabilityDefinition> capabilitiesDefListToUpdate = new ArrayList<>();
227 List<CapabilityDefinition> capabilitiesToReturn = null;
228 if (CollectionUtils.isNotEmpty(capabilitiesListStoredInComponent)) {
229 if (capabilityDefinitions.stream().anyMatch(capabilityDefinition ->
230 isCapabilityUsedInServiceComposition(capabilityDefinition, storedComponent))) {
231 LOGGER.error("Capability can't be edited, since it is" + " used in service composition");
232 return Either.right(componentsUtils.getResponseFormat(ActionStatus.
233 CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION));
235 for (CapabilityDefinition capabilityDefinitionToUpdate : capabilityDefinitions) {
236 capabilitiesToReturn = capabilitiesListStoredInComponent.stream().filter(capToUpdate ->
237 capToUpdate.getUniqueId().equals(capabilityDefinitionToUpdate.getUniqueId()))
238 .map(capabilityDefinition -> updateCapability(capabilityDefinition,
239 capabilityDefinitionToUpdate, storedComponent)).collect(Collectors.toList());
240 capabilitiesListStoredInComponent.removeIf(capToUpdate -> capToUpdate.getUniqueId()
241 .equals(capabilityDefinitionToUpdate.getUniqueId()));
242 if (CollectionUtils.isNotEmpty(capabilitiesToReturn)) {
243 capabilitiesListStoredInComponent.addAll(capabilitiesToReturn);
244 capabilitiesDefListToUpdate.addAll(capabilitiesListStoredInComponent);
246 Either<List<CapabilityDefinition>, ResponseFormat> capTypeUpdateEither
247 = handleCapabilityTypeUpdateWhenNewTypeExist(storedComponent, storedComponent
248 .getCapabilities(), capabilitiesToReturn, capabilityDefinitionToUpdate);
249 if (capTypeUpdateEither.isRight()) {
250 return Either.right(capTypeUpdateEither.right().value());
252 capabilitiesDefListToUpdate = capTypeUpdateEither.left().value();
255 result = capabilitiesOperation.updateCapabilities(componentId, capabilitiesDefListToUpdate);
257 Either<List<CapabilityDefinition>, ResponseFormat> capabilityDefinitionToDelete
258 = handleCapabilityTypeUpdateWhenNewTypeNotExist(capabilityDefinitions, storedComponent,
259 storedComponentCapabilities);
260 if (capabilityDefinitionToDelete != null) {
261 return capabilityDefinitionToDelete;
263 capabilitiesToReturn = capabilityDefinitions.stream().map(capabilityDefinition ->
264 initiateNewCapability(storedComponent, capabilityDefinition)).collect(Collectors.toList());
265 result = capabilitiesOperation.addCapabilities(componentId, capabilitiesToReturn);
267 if (result.isRight()) {
268 janusGraphDao.rollback();
269 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result
270 .right().value(), storedComponent.getComponentType()), ""));
272 Map<String, MapPropertiesDataDefinition> propertiesMap =
273 getCapabilitiesPropertiesDataDefinitionMap(capabilityDefinitions);
274 if (MapUtils.isNotEmpty(propertiesMap)) {
275 StorageOperationStatus storageOperationStatus = capabilitiesOperation
276 .createOrUpdateCapabilityProperties(componentId, propertiesMap);
277 if (storageOperationStatus != StorageOperationStatus.OK) {
278 janusGraphDao.rollback();
279 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
282 janusGraphDao.commit();
283 return Either.left(capabilitiesToReturn);
284 } catch (Exception e) {
285 janusGraphDao.rollback();
286 LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "addOrUpdate", e);
287 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
289 if (lockResult.isLeft() && lockResult.left().value()) {
290 graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
291 NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
296 private Either<List<CapabilityDefinition>, ResponseFormat> handleCapabilityTypeUpdateWhenNewTypeExist(
297 Component storedComponent,
298 Map<String, List<CapabilityDefinition>> storedComponentCapabilities,
299 List<CapabilityDefinition> capabilitiesToReturn,
300 CapabilityDefinition capabilityDefinitionToUpdate) {
302 List<CapabilityDefinition> capabilitiesListStoredInComponent;
303 List<CapabilityDefinition> capabilitiesDefsToCreateOrUpdate = new ArrayList<>();
304 Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities.values().stream()
305 .flatMap(Collection::stream).filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
306 .equals(capabilityDefinitionToUpdate.getUniqueId())).findAny();
307 if (!definitionOptional.isPresent()) {
308 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND,
309 storedComponent.getUniqueId()));
311 CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
313 capabilitiesListStoredInComponent = getCapabilityStoredInComponentByType(capabilityDefinitionToUpdate.getType(),
314 storedComponentCapabilities);
315 Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapabilityEither
316 = deleteCapability(storedComponent, storedComponentCapabilities, capabilityDefinitionToDelete);
317 if (deleteCapabilityEither.isRight()) {
318 janusGraphDao.rollback();
319 return Either.right(componentsUtils.getResponseFormat(deleteCapabilityEither.right().value()));
321 StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
322 .deleteCapabilityProperties(storedComponent, buildCapPropKey(capabilityDefinitionToDelete));
323 if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
324 janusGraphDao.rollback();
325 return Either.right(componentsUtils.getResponseFormat(deleteStorageOperationStatus));
327 capabilitiesToReturn.add(initiateNewCapability(storedComponent, capabilityDefinitionToUpdate));
329 capabilitiesDefsToCreateOrUpdate.addAll(capabilitiesToReturn);
330 capabilitiesDefsToCreateOrUpdate.addAll(capabilitiesListStoredInComponent);
331 return Either.left(capabilitiesDefsToCreateOrUpdate);
334 private Either<List<CapabilityDefinition>, ResponseFormat> handleCapabilityTypeUpdateWhenNewTypeNotExist(
335 List<CapabilityDefinition> capabilityDefinitions,
336 Component storedComponent,
337 Map<String, List<CapabilityDefinition>> storedComponentCapabilities) {
338 for (CapabilityDefinition capabilityDefinitionToUpdate : capabilityDefinitions) {
340 Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities.values().stream()
341 .flatMap(Collection::stream).filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
342 .equals(capabilityDefinitionToUpdate.getUniqueId())).findAny();
343 if (!definitionOptional.isPresent()) {
344 return Either.right(componentsUtils.getResponseFormat(ActionStatus
345 .CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
347 CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
348 Boolean isCapabilityUsedInServiceComposition = isCapabilityUsedInServiceComposition(capabilityDefinitionToDelete,
350 if (isCapabilityUsedInServiceComposition) {
351 LOGGER.error("Capability {} can't be edited, since it is used in service composition",
352 capabilityDefinitionToDelete.getUniqueId());
353 return Either.right(componentsUtils.getResponseFormat(
354 ActionStatus.CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION,
355 capabilityDefinitionToDelete.getName()));
357 Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapabilityEither
358 = deleteCapability(storedComponent, storedComponentCapabilities, capabilityDefinitionToDelete);
359 if (deleteCapabilityEither.isRight()) {
360 janusGraphDao.rollback();
361 return Either.right(componentsUtils.getResponseFormat(deleteCapabilityEither.right().value()));
363 StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
364 .deleteCapabilityProperties(storedComponent, buildCapPropKey(capabilityDefinitionToDelete));
365 if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
366 janusGraphDao.rollback();
367 return Either.right(componentsUtils.getResponseFormat(deleteStorageOperationStatus));
373 public Either<CapabilityDefinition, ResponseFormat> getCapability(String componentId, String capabilityToGet,
374 User user, boolean lock) {
375 validateUserExists(user.getUserId());
376 Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
377 if (componentEither.isRight()) {
378 return Either.right(componentEither.right().value());
380 Component storedComponent = componentEither.left().value();
382 Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, GET_CAPABILITIES);
383 if (lockResult.isRight()) {
384 return Either.right(lockResult.right().value());
387 Either<CapabilityDefinition, ResponseFormat> getCapabilityDefinitionEither =
388 getCapabilityDefinition(capabilityToGet, storedComponent);
389 if (getCapabilityDefinitionEither.isRight()) {
390 return Either.right(getCapabilityDefinitionEither.right().value());
392 return Either.left(getCapabilityDefinitionEither.left().value());
393 } catch (Exception e) {
394 LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "get", e);
395 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, componentId));
397 if (lockResult.isLeft() && lockResult.left().value()) {
398 graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
399 NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
404 private Either<CapabilityDefinition, ResponseFormat> getCapabilityDefinition(String capabilityIdToGet,
405 Component storedComponent) {
406 List<CapabilityDefinition> capabilityDefinitions = storedComponent.getCapabilities().values()
407 .stream().flatMap(Collection::stream).collect(Collectors.toList());
408 if (capabilityDefinitions.isEmpty()) {
409 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND,
410 storedComponent.getUniqueId()));
412 CapabilityDefinition capabilityDefinitionToReturn;
413 Optional<CapabilityDefinition> capabilityDefinitionOptional = capabilityDefinitions.stream()
414 .filter(capabilityDefinition -> capabilityDefinition.getUniqueId().equals(capabilityIdToGet)).findAny();
415 if (capabilityDefinitionOptional.isPresent()) {
416 capabilityDefinitionToReturn = capabilityDefinitionOptional.get();
418 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND,
419 storedComponent.getUniqueId()));
422 return Either.left(capabilityDefinitionToReturn);
425 public Either<CapabilityDefinition, ResponseFormat> deleteCapability(String componentId, String capabilityIdToDelete,
426 User user, boolean lock) {
427 validateUserExists(user.getUserId());
428 Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
429 if (componentEither.isRight()) {
430 return Either.right(componentEither.right().value());
432 Component storedComponent = componentEither.left().value();
434 Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, DELETE_CAPABILITIES);
435 if (lockResult.isRight()) {
436 return Either.right(lockResult.right().value());
439 return deleteCapability(capabilityIdToDelete, storedComponent);
440 } catch (Exception e) {
441 LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "delete", e);
442 janusGraphDao.rollback();
443 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND));
445 if (lockResult.isLeft() && lockResult.left().value()) {
446 graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
447 NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
452 private Either<CapabilityDefinition, ResponseFormat> deleteCapability(String capabilityIdToDelete,
453 Component storedComponent) {
454 Map<String, List<CapabilityDefinition>> storedComponentCapabilities = storedComponent.getCapabilities();
455 if (storedComponentCapabilities.isEmpty()) {
456 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
458 Either<CapabilityDefinition, ResponseFormat> capabilityDefinitionToDeleteEither =
459 getAndValidateCapabilitiesToDelete(storedComponent, storedComponentCapabilities, capabilityIdToDelete);
461 if(capabilityDefinitionToDeleteEither.isRight()) {
462 return Either.right(capabilityDefinitionToDeleteEither.right().value());
464 Either<List<CapabilityDefinition>, StorageOperationStatus> result = deleteCapability(storedComponent,
465 storedComponentCapabilities, capabilityDefinitionToDeleteEither.left().value());
466 if (result.isRight()) {
467 janusGraphDao.rollback();
468 LOGGER.error("Failed to delete capability from component {}. Response is {}", storedComponent.getName(),
469 result.right().value());
470 return Either.right(componentsUtils.getResponseFormat(
471 componentsUtils.convertFromStorageResponse(result.right().value(),
472 storedComponent.getComponentType())));
474 janusGraphDao.commit();
476 return Either.left(capabilityDefinitionToDeleteEither.left().value());
479 private Either<CapabilityDefinition, ResponseFormat> getAndValidateCapabilitiesToDelete(Component storedComponent,
480 Map<String, List<CapabilityDefinition>> storedComponentCapabilities,
481 String capabilityIdToDelete) {
483 Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities.values().stream()
484 .flatMap(Collection::stream).filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
485 .equals(capabilityIdToDelete)).findAny();
486 if (!definitionOptional.isPresent()) {
487 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
489 CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
490 Boolean isCapabilityUsedInServiceComposition
491 = isCapabilityUsedInServiceComposition(capabilityDefinitionToDelete, storedComponent);
492 if (isCapabilityUsedInServiceComposition) {
493 LOGGER.error("Capability {} can't be deleted, since it is used in service composition",
494 capabilityDefinitionToDelete.getUniqueId());
495 return Either.right(componentsUtils.getResponseFormat(ActionStatus
496 .CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION, capabilityDefinitionToDelete.getName()));
499 return Either.left(capabilityDefinitionToDelete);
501 private Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapability(Component storedComponent,
502 Map<String, List<CapabilityDefinition>> storedComponentCapabilities,
503 CapabilityDefinition capabilityDefinitionToDelete) {
505 List<CapabilityDefinition> capabilitiesListStoredInComponent =
506 getCapabilityStoredInComponentByType(capabilityDefinitionToDelete.getType(), storedComponentCapabilities);
507 capabilitiesListStoredInComponent.removeIf(capabilityDefinition ->
508 capabilityDefinition.getUniqueId().equals(capabilityDefinitionToDelete.getUniqueId()));
509 Either<List<CapabilityDefinition>, StorageOperationStatus> result;
510 if (capabilitiesListStoredInComponent.isEmpty()) {
511 StorageOperationStatus operationStatus = capabilitiesOperation.deleteCapabilities(storedComponent,
512 capabilityDefinitionToDelete.getType());
513 if (StorageOperationStatus.OK.equals(operationStatus)) {
514 result = Either.left(Collections.singletonList(capabilityDefinitionToDelete));
516 result = Either.right(operationStatus);
519 result = capabilitiesOperation.updateCapabilities(storedComponent.getUniqueId(),
520 capabilitiesListStoredInComponent);
522 if (result.isLeft()) {
523 StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
524 .deleteCapabilityProperties(storedComponent, buildCapPropKey(capabilityDefinitionToDelete));
525 if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
526 result = Either.right(deleteStorageOperationStatus);
533 private Either<Component, ResponseFormat> getComponentDetails(String componentId) {
534 ComponentParametersView filter = new ComponentParametersView(true);
535 filter.setIgnoreCapabilities(false);
536 filter.setIgnoreCapabiltyProperties(false);
537 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither =
538 toscaOperationFacade.getToscaElement(componentId, filter);
539 if (componentStorageOperationStatusEither.isRight()) {
540 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
541 LOGGER.error("Failed to fetch component information by component id {}, Response is {}",
542 componentId, errorStatus);
543 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
545 return Either.left(componentStorageOperationStatusEither.left().value());
548 private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock, Component component, String action) {
551 lockComponent(component.getUniqueId(), component, action);
552 } catch (ComponentException e){
553 LOGGER.debug(FAILED_TO_LOCK_COMPONENT_RESPONSE_IS, component.getName(), e.getMessage());
554 janusGraphDao.rollback();
558 return Either.left(true);
561 private List<CapabilityDefinition> getCapabilityStoredInComponentByType(String capabilityType, Map<String,
562 List<CapabilityDefinition>> capabilities) {
563 Optional<Map.Entry<String, List<CapabilityDefinition>>> entryOptional = capabilities.entrySet().stream()
564 .filter(map -> map.getKey().equals(capabilityType)).findFirst();
565 return entryOptional.map(Map.Entry::getValue).orElse(Collections.emptyList());
568 private CapabilityDefinition initiateNewCapability(Component component, CapabilityDefinition capabilityDefinition) {
569 if (StringUtils.isEmpty(capabilityDefinition.getUniqueId()))
570 capabilityDefinition.setUniqueId(UUID.randomUUID().toString());
571 if (StringUtils.isEmpty(capabilityDefinition.getOwnerId()))
572 capabilityDefinition.setOwnerId(component.getUniqueId());
573 if (StringUtils.isEmpty(capabilityDefinition.getOwnerName()))
574 capabilityDefinition.setOwnerName(component.getName());
575 capabilityDefinition.setLeftOccurrences(capabilityDefinition.getMaxOccurrences());
576 List<ComponentInstanceProperty> capabilityProperties = capabilityDefinition.getProperties();
577 initiateProperties(capabilityDefinition, capabilityProperties);
578 return capabilityDefinition;
581 private void initiateProperties(CapabilityDefinition capabilityDefinition,
582 List<ComponentInstanceProperty> capabilityProperties) {
583 if (CollectionUtils.isNotEmpty(capabilityProperties)) {
584 capabilityProperties.stream().filter(prop -> prop != null && StringUtils.isEmpty(prop.getUniqueId()))
585 .forEach(propDef -> {
586 String uid = UniqueIdBuilder.buildRequirementUid(capabilityDefinition.getUniqueId(), propDef.getName());
587 propDef.setUniqueId(uid);
588 propDef.setParentUniqueId(capabilityDefinition.getUniqueId());
593 private CapabilityDefinition updateCapability(CapabilityDefinition storedCapability,
594 CapabilityDefinition capabilityToUpdate, Component component) {
595 storedCapability.setName(capabilityToUpdate.getName());
596 storedCapability.setDescription(capabilityToUpdate.getDescription());
597 storedCapability.setType(capabilityToUpdate.getType());
598 storedCapability.setValidSourceTypes(capabilityToUpdate.getValidSourceTypes());
599 storedCapability.setMinOccurrences(capabilityToUpdate.getMinOccurrences());
600 storedCapability.setMaxOccurrences(capabilityToUpdate.getMaxOccurrences());
601 if (!storedCapability.getType().equals(capabilityToUpdate.getType())) {
602 List<ComponentInstanceProperty> capabilityProperties = capabilityToUpdate.getProperties();
603 initiateProperties(capabilityToUpdate, capabilityProperties);
604 storedCapability.setProperties(capabilityToUpdate.getProperties());
606 if (!storedCapability.getName().equals(capabilityToUpdate.getName())) {
607 StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
608 .deleteCapabilityProperties(component, buildCapPropKey(storedCapability));
609 if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
610 janusGraphDao.rollback();
614 return storedCapability;
618 private Boolean isCapabilityUsedInServiceComposition(CapabilityDefinition capabilityDefinition, Component component) {
619 Either<List<Component>, StorageOperationStatus> componentList = toscaOperationFacade
620 .getParentComponents(component.getUniqueId());
621 if (componentList.isRight()) {
622 return Boolean.FALSE;
624 return componentList.left().value().stream().flatMap(parentComponent -> parentComponent
625 .getComponentInstancesRelations().stream()).flatMap(requirementCapabilityRelDef ->
626 requirementCapabilityRelDef.getRelationships().stream()).anyMatch(capabilityRequirementRelationship ->
627 capabilityRequirementRelationship.getRelation().getCapabilityUid().equals(capabilityDefinition.getUniqueId()));
630 public Either<Map<String, CapabilityTypeDefinition>, ResponseFormat> getAllCapabilityTypes() {
631 Either<Map<String, CapabilityTypeDefinition>, JanusGraphOperationStatus> capabilityTypeCacheAll =
632 capabilityTypeOperation.getAllCapabilityTypes();
633 if (capabilityTypeCacheAll.isRight()) {
634 JanusGraphOperationStatus operationStatus = capabilityTypeCacheAll.right().value();
635 if (JanusGraphOperationStatus.NOT_FOUND == operationStatus) {
636 BeEcompErrorManager.getInstance().logInternalDataError("FetchCapabilityTypes",
637 "Capability types are not loaded", BeEcompErrorManager.ErrorSeverity.ERROR);
638 return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY));
640 BeEcompErrorManager.getInstance().logInternalFlowError("FetchCapabilityTypes",
641 "Failed to fetch capability types", BeEcompErrorManager.ErrorSeverity.ERROR);
642 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
645 return Either.left(capabilityTypeCacheAll.left().value());
648 private Map<String, MapPropertiesDataDefinition> getCapabilitiesPropertiesDataDefinitionMap(
649 List<CapabilityDefinition> capabilityDefinitions) {
650 CapabilityDefinition capabilityDefinitionToAddOrUpdateCapProp = capabilityDefinitions.get(0);
651 List<ComponentInstanceProperty> componentInstanceProperties = null;
652 if (Objects.nonNull(capabilityDefinitionToAddOrUpdateCapProp)) {
653 componentInstanceProperties = capabilityDefinitionToAddOrUpdateCapProp.getProperties();
655 Map<String, MapPropertiesDataDefinition> propertiesMap = new HashMap<>();
656 if (CollectionUtils.isNotEmpty(componentInstanceProperties)) {
657 MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
658 for (ComponentInstanceProperty cip : componentInstanceProperties) {
659 dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
661 propertiesMap.put(buildCapPropKey(capabilityDefinitionToAddOrUpdateCapProp), dataToCreate);
663 return propertiesMap;
666 private String buildCapPropKey(CapabilityDefinition capabilityDefinitionToAddOrUpdateCapProp) {
667 return capabilityDefinitionToAddOrUpdateCapProp.getType() + ModelConverter.CAP_PROP_DELIM +
668 capabilityDefinitionToAddOrUpdateCapProp.getName();