2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  *  Copyright (C) 2021 Nordix Foundation. 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
 
  12  *  Unless required by applicable law or agreed to in writing, software
 
  13  *  distributed under the License is distributed on an "AS IS" BASIS,
 
  14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.zone-instance.component.ts
 
  15  *  See the License for the specific language governing permissions and
 
  16  *  limitations under the License.
 
  18  *  SPDX-License-Identifier: Apache-2.0
 
  19  *  ============LICENSE_END=========================================================
 
  21 package org.openecomp.sdc.be.components.impl;
 
  23 import fj.data.Either;
 
  24 import java.util.Arrays;
 
  25 import java.util.HashMap;
 
  26 import java.util.List;
 
  28 import java.util.Optional;
 
  29 import java.util.UUID;
 
  30 import org.apache.commons.collections.CollectionUtils;
 
  31 import org.apache.commons.collections.MapUtils;
 
  32 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
 
  33 import org.openecomp.sdc.be.components.validation.ComponentValidations;
 
  34 import org.openecomp.sdc.be.dao.api.ActionStatus;
 
  35 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
 
  36 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 
  37 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 
  38 import org.openecomp.sdc.be.model.Component;
 
  39 import org.openecomp.sdc.be.model.ComponentInstance;
 
  40 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
 
  41 import org.openecomp.sdc.be.model.ComponentParametersView;
 
  42 import org.openecomp.sdc.be.model.InterfaceDefinition;
 
  43 import org.openecomp.sdc.be.model.User;
 
  44 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
 
  45 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
 
  46 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
 
  47 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
 
  48 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
 
  49 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
 
  50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
  51 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
 
  52 import org.openecomp.sdc.be.user.Role;
 
  53 import org.openecomp.sdc.common.datastructure.Wrapper;
 
  54 import org.openecomp.sdc.exception.ResponseFormat;
 
  55 import org.slf4j.Logger;
 
  56 import org.slf4j.LoggerFactory;
 
  57 import org.springframework.beans.factory.annotation.Autowired;
 
  59 @org.springframework.stereotype.Component("componentInterfaceOperationBusinessLogic")
 
  60 public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic {
 
  62     private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationBusinessLogic.class);
 
  63     private final ComponentValidations componentValidations;
 
  66     public ComponentInterfaceOperationBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
 
  67                                                     final IGroupInstanceOperation groupInstanceOperation,
 
  68                                                     final IGroupTypeOperation groupTypeOperation, final InterfaceOperation interfaceOperation,
 
  69                                                     final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
 
  70                                                     final ArtifactsOperations artifactToscaOperation,
 
  71                                                     final ComponentValidations componentValidations) {
 
  72         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
 
  73             artifactToscaOperation);
 
  74         this.componentValidations = componentValidations;
 
  77     public Optional<ComponentInstance> updateComponentInstanceInterfaceOperation(final String componentId, final String componentInstanceId,
 
  78                                                                                  final InterfaceDefinition interfaceDefinition,
 
  79                                                                                  final ComponentTypeEnum componentTypeEnum,
 
  80                                                                                  final Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
 
  81         throws BusinessLogicException {
 
  82         final Component component = getComponent(componentId);
 
  83         final Optional<ComponentInstance> componentInstanceOptional = componentValidations.getComponentInstance(component, componentInstanceId);
 
  84         ResponseFormat responseFormat;
 
  85         if (componentInstanceOptional.isEmpty()) {
 
  86             responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
 
  87             LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
 
  88             errorWrapper.setInnerElement(responseFormat);
 
  89             return Optional.empty();
 
  91         Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaceMap = component.getComponentInstancesInterfaces();
 
  92         if (MapUtils.isEmpty(componentInstancesInterfaceMap)) {
 
  93             componentInstancesInterfaceMap = new HashMap<>();
 
  94             component.setComponentInstancesInterfaces(componentInstancesInterfaceMap);
 
  96         final List<ComponentInstanceInterface> componentInstanceInterfaceList = componentInstancesInterfaceMap.get(componentInstanceId);
 
  97         if (CollectionUtils.isEmpty(componentInstanceInterfaceList)) {
 
  98             responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
 
  99             LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
 
 100             errorWrapper.setInnerElement(responseFormat);
 
 101             return Optional.empty();
 
 103         final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
 
 104         if (optionalOperationDataDefinition.isEmpty()) {
 
 105             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
 
 106             LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentInstanceId, responseFormat);
 
 107             errorWrapper.setInnerElement(responseFormat);
 
 108             return Optional.empty();
 
 110         final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
 
 111         final Optional<ComponentInstanceInterface> optionalComponentInstanceInterface = componentInstanceInterfaceList.stream().filter(
 
 112                 ci -> ci.getOperations().values().stream().anyMatch(
 
 113                     operationDataDefinition -> operationDataDefinition.getUniqueId().equalsIgnoreCase(updatedOperationDataDefinition.getUniqueId())))
 
 115         if (optionalComponentInstanceInterface.isEmpty()) {
 
 116             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT);
 
 118                 .debug("Failed to found ComponentInstanceInterface on component instance with id {}, error: {}", componentInstanceId, responseFormat);
 
 119             errorWrapper.setInnerElement(responseFormat);
 
 120             return Optional.empty();
 
 122         updateOperationDefinitionImplementation(updatedOperationDataDefinition);
 
 123         optionalComponentInstanceInterface.get().getOperations().replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
 
 124         boolean wasLocked = false;
 
 127                 lockComponent(componentId, component, "Update Interface Operation on Component instance");
 
 130             final StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(component, componentInstanceId);
 
 131             if (status != StorageOperationStatus.OK) {
 
 132                 janusGraphDao.rollback();
 
 133                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
 
 134                 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
 
 135                 errorWrapper.setInnerElement(responseFormat);
 
 136                 return Optional.empty();
 
 138             final ComponentParametersView componentFilter = new ComponentParametersView();
 
 139             componentFilter.disableAll();
 
 140             componentFilter.setIgnoreUsers(false);
 
 141             componentFilter.setIgnoreComponentInstances(false);
 
 142             componentFilter.setIgnoreInterfaces(false);
 
 143             componentFilter.setIgnoreComponentInstancesInterfaces(false);
 
 144             final Either<Component, StorageOperationStatus> operationStatusEither = toscaOperationFacade
 
 145                 .updateComponentInstanceMetadataOfTopologyTemplate(component, componentFilter);
 
 146             if (operationStatusEither.isRight()) {
 
 147                 janusGraphDao.rollback();
 
 148                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
 
 149                 LOGGER.error("Exception occurred when updating Component Instance Topology template {}", responseFormat);
 
 150                 errorWrapper.setInnerElement(responseFormat);
 
 151                 return Optional.empty();
 
 153             janusGraphDao.commit();
 
 154         } catch (final Exception e) {
 
 155             janusGraphDao.rollback();
 
 156             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: {}", e.getMessage(), e);
 
 157             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
 
 158             errorWrapper.setInnerElement(responseFormat);
 
 159             throw new BusinessLogicException(responseFormat);
 
 162                 unlockComponent(component.getUniqueId(), componentTypeEnum);
 
 165         return componentInstanceOptional;
 
 168     public Optional<Component> updateResourceInterfaceOperation(final String componentId,
 
 169                                                                 final InterfaceDefinition interfaceDefinition,
 
 170                                                                 final ComponentTypeEnum componentTypeEnum,
 
 171                                                                 final Wrapper<ResponseFormat> errorWrapper,
 
 172                                                                 final boolean shouldLock) throws BusinessLogicException {
 
 173         final var component = getComponent(componentId);
 
 174         ResponseFormat responseFormat;
 
 176         Map<String, InterfaceDefinition> componentInterfaceMap = component.getInterfaces();
 
 177         final String interfaceDefinitionType = interfaceDefinition.getType();
 
 178         if (MapUtils.isEmpty(componentInterfaceMap)) {
 
 179             componentInterfaceMap = new HashMap<>();
 
 180             componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
 
 181             component.setInterfaces(componentInterfaceMap);
 
 183             InterfaceDefinition componentInterfaceDefinition = componentInterfaceMap.get(interfaceDefinitionType);
 
 184             if (componentInterfaceDefinition == null) {
 
 185                 componentInterfaceDefinition = interfaceDefinition;
 
 186                 componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
 
 189             final Map<String, OperationDataDefinition> interfaceDefinitionOperations = interfaceDefinition.getOperations();
 
 190             final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinitionOperations.values().stream().findFirst();
 
 191             if (optionalOperationDataDefinition.isEmpty()) {
 
 192                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
 
 193                 LOGGER.debug("Failed to found interface operation on provided InterfaceDefinition {}, error: {}",
 
 194                     interfaceDefinitionType, responseFormat);
 
 195                 errorWrapper.setInnerElement(responseFormat);
 
 196                 return Optional.empty();
 
 198             final var updatedOperationDataDefinition = optionalOperationDataDefinition.get();
 
 199             updateOperationDefinitionImplementation(updatedOperationDataDefinition);
 
 200             Map<String, OperationDataDefinition> componentOperationDataDefinitionMap = componentInterfaceDefinition.getOperations();
 
 201             if (MapUtils.isEmpty(componentOperationDataDefinitionMap)) {
 
 202                 componentOperationDataDefinitionMap = new HashMap<>();
 
 203                 componentInterfaceDefinition.setOperations(componentOperationDataDefinitionMap);
 
 205             componentOperationDataDefinitionMap.replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
 
 207         boolean wasLocked = false;
 
 210                 lockComponent(componentId, component, "Update Interface Operation on Component instance");
 
 213             final StorageOperationStatus status = toscaOperationFacade.updateComponentInterfaces(component, interfaceDefinitionType);
 
 214             if (status != StorageOperationStatus.OK) {
 
 215                 janusGraphDao.rollback();
 
 216                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
 
 217                 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
 
 218                 errorWrapper.setInnerElement(responseFormat);
 
 219                 return Optional.empty();
 
 221             janusGraphDao.commit();
 
 222         } catch (final Exception e) {
 
 223             janusGraphDao.rollback();
 
 224             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e);
 
 225             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
 
 226             errorWrapper.setInnerElement(responseFormat);
 
 227             throw new BusinessLogicException(responseFormat);
 
 230                 unlockComponent(component.getUniqueId(), componentTypeEnum);
 
 233         return Optional.of(component);
 
 236     public Optional<Component> createInterfaceOperationInResource(final String componentId, final InterfaceDefinition interfaceDefinition,
 
 237                                                                   final ComponentTypeEnum componentTypeEnum,
 
 238                                                                   final Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
 
 239         throws BusinessLogicException {
 
 240         final Component component = getComponent(componentId);
 
 241         ResponseFormat responseFormat;
 
 242         final String componentInterfaceUpdatedKey = interfaceDefinition.getType();
 
 244         Map<String, InterfaceDefinition> componentInterfaceMap = component.getInterfaces();
 
 245         if (MapUtils.isEmpty(componentInterfaceMap)) {
 
 246             componentInterfaceMap = new HashMap<>();
 
 247             component.setInterfaces(componentInterfaceMap);
 
 250         interfaceDefinition.setUniqueId(componentInterfaceUpdatedKey);
 
 251         interfaceDefinition.setToscaResourceName(componentInterfaceUpdatedKey);
 
 252         interfaceDefinition.setUserCreated(true);
 
 254         final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
 
 255         if (optionalOperationDataDefinition.isEmpty()) {
 
 256             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
 
 257             LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentId, responseFormat);
 
 258             errorWrapper.setInnerElement(responseFormat);
 
 259             return Optional.empty();
 
 262         final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
 
 263         updatedOperationDataDefinition.setUniqueId(UUID.randomUUID().toString());
 
 265         final InterfaceDefinition interfaceDefinitionFound = componentInterfaceMap.get(componentInterfaceUpdatedKey);
 
 266         if (interfaceDefinitionFound != null) {
 
 267             final Map<String, OperationDataDefinition> operationsFromComponent = interfaceDefinitionFound.getOperations();
 
 268             final String updatedOperationDataDefinitionName = updatedOperationDataDefinition.getName();
 
 269             final boolean find = operationsFromComponent.containsKey(updatedOperationDataDefinitionName);
 
 271                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE,
 
 272                     updatedOperationDataDefinitionName);
 
 273                 LOGGER.error("Operation '{}' for Interface '{}' already exist, error: '{}'", updatedOperationDataDefinitionName,
 
 274                     componentInterfaceUpdatedKey, responseFormat);
 
 275                 errorWrapper.setInnerElement(responseFormat);
 
 276                 return Optional.empty();
 
 278                 operationsFromComponent.put(updatedOperationDataDefinitionName, updatedOperationDataDefinition);
 
 279                 interfaceDefinition.setOperations(operationsFromComponent);
 
 283         componentInterfaceMap.put(componentInterfaceUpdatedKey, interfaceDefinition);
 
 285         boolean wasLocked = false;
 
 288                 lockComponent(componentId, component, "Update Interface Operation on Component instance");
 
 291             final Either<InterfaceDefinition, StorageOperationStatus> operationStatusEither =
 
 292                 toscaOperationFacade.addInterfaceToComponent(componentInterfaceUpdatedKey, interfaceDefinition, component);
 
 293             if (operationStatusEither.isRight()) {
 
 294                 janusGraphDao.rollback();
 
 295                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
 
 296                 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
 
 297                 errorWrapper.setInnerElement(responseFormat);
 
 298                 return Optional.empty();
 
 300             janusGraphDao.commit();
 
 301         } catch (final Exception e) {
 
 302             janusGraphDao.rollback();
 
 303             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e);
 
 304             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
 
 305             errorWrapper.setInnerElement(responseFormat);
 
 306             throw new BusinessLogicException(responseFormat);
 
 309                 unlockComponent(component.getUniqueId(), componentTypeEnum);
 
 312         return Optional.of(component);
 
 315     public User validateUser(final String userId) {
 
 316         final User user = userValidations.validateUserExists(userId);
 
 317         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
 
 321     private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
 
 322         graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
 
 325     private void updateOperationDefinitionImplementation(final OperationDataDefinition updatedOperationDataDefinition) {
 
 326         final ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition(updatedOperationDataDefinition.getImplementation());
 
 327         artifactInfo.setArtifactName(String.format("'%s'", updatedOperationDataDefinition.getImplementation().getArtifactName()));
 
 328         updatedOperationDataDefinition.setImplementation(artifactInfo);