2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2022 Nordix Foundation.
 
   4  * ================================================================================
 
   5  * Licensed under the Apache License, Version 2.0 (the "License");
 
   6  * you may not use this file except in compliance with the License.
 
   7  * You may obtain a copy of the License at
 
   9  *      http://www.apache.org/licenses/LICENSE-2.0
 
  11  * Unless required by applicable law or agreed to in writing, software
 
  12  * distributed under the License is distributed on an "AS IS" BASIS,
 
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  * See the License for the specific language governing permissions and
 
  15  * limitations under the License.
 
  17  * SPDX-License-Identifier: Apache-2.0
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.policy.clamp.acm.participant.a1pms.handler;
 
  23 import java.lang.invoke.MethodHandles;
 
  24 import java.util.HashMap;
 
  27 import java.util.UUID;
 
  28 import javax.validation.ConstraintViolation;
 
  29 import javax.validation.Validation;
 
  30 import javax.validation.ValidationException;
 
  31 import lombok.AccessLevel;
 
  33 import lombok.RequiredArgsConstructor;
 
  35 import org.apache.http.HttpStatus;
 
  36 import org.onap.policy.clamp.acm.participant.a1pms.exception.A1PolicyServiceException;
 
  37 import org.onap.policy.clamp.acm.participant.a1pms.models.ConfigurationEntity;
 
  38 import org.onap.policy.clamp.acm.participant.a1pms.webclient.AcA1PmsClient;
 
  39 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
 
  40 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
 
  41 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 
  42 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
 
  43 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
 
  44 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
 
  45 import org.onap.policy.common.utils.coder.Coder;
 
  46 import org.onap.policy.common.utils.coder.CoderException;
 
  47 import org.onap.policy.common.utils.coder.StandardCoder;
 
  48 import org.onap.policy.models.base.PfModelException;
 
  49 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
  50 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 
  51 import org.slf4j.Logger;
 
  52 import org.slf4j.LoggerFactory;
 
  53 import org.springframework.stereotype.Component;
 
  56  * This class handles implementation of automationCompositionElement updates.
 
  59 @RequiredArgsConstructor
 
  60 public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
 
  62     private static final Coder CODER = new StandardCoder();
 
  64     private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
  67     private ParticipantIntermediaryApi intermediaryApi;
 
  69     private final AcA1PmsClient acA1PmsClient;
 
  71     // Map of acElement Id and A1PMS services
 
  72     @Getter(AccessLevel.PACKAGE)
 
  73     private final Map<UUID, ConfigurationEntity> configRequestMap = new HashMap<>();
 
  76      * Handle a automation composition element state change.
 
  78      * @param automationCompositionElementId the ID of the automation composition element
 
  79      * @param currentState                   the current state of the automation composition element
 
  80      * @param newState                       the state to which the automation composition element is changing to
 
  81      * @throws PfModelException in case of a model exception
 
  84     public void automationCompositionElementStateChange(ToscaConceptIdentifier automationCompositionId,
 
  85             UUID automationCompositionElementId, AutomationCompositionState currentState,
 
  86             AutomationCompositionOrderedState newState) throws A1PolicyServiceException {
 
  89                 ConfigurationEntity configurationEntity = configRequestMap.get(automationCompositionElementId);
 
  90                 if (configurationEntity != null && acA1PmsClient.isPmsHealthy()) {
 
  91                     acA1PmsClient.deleteService(configurationEntity.getPolicyServiceEntities());
 
  92                     configRequestMap.remove(automationCompositionElementId);
 
  93                     intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
 
  94                             automationCompositionElementId, newState, AutomationCompositionState.UNINITIALISED,
 
  95                             ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE);
 
  97                     LOGGER.warn("Failed to connect with A1PMS. Service configuration is: {}", configurationEntity);
 
  98                     throw new A1PolicyServiceException(HttpStatus.SC_SERVICE_UNAVAILABLE,
 
  99                             "Unable to connect with A1PMS");
 
 103                 intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
 
 104                         automationCompositionElementId, newState, AutomationCompositionState.PASSIVE,
 
 105                         ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE);
 
 108                 intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
 
 109                         automationCompositionElementId, newState, AutomationCompositionState.RUNNING,
 
 110                         ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE);
 
 113                 LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState);
 
 119      * Callback method to handle an update on an automation composition element.
 
 121      * @param element      the information on the automation composition element
 
 122      * @param nodeTemplate toscaNodeTemplate
 
 125     public void automationCompositionElementUpdate(ToscaConceptIdentifier automationCompositionId,
 
 126             AutomationCompositionElement element, ToscaNodeTemplate nodeTemplate) throws A1PolicyServiceException {
 
 128             var configurationEntity = CODER.convert(nodeTemplate.getProperties(), ConfigurationEntity.class);
 
 129             Set<ConstraintViolation<ConfigurationEntity>> violations =
 
 130                     Validation.buildDefaultValidatorFactory().getValidator().validate(configurationEntity);
 
 131             if (violations.isEmpty()) {
 
 132                 if (acA1PmsClient.isPmsHealthy()) {
 
 133                     acA1PmsClient.createService(configurationEntity.getPolicyServiceEntities());
 
 134                     configRequestMap.put(element.getId(), configurationEntity);
 
 136                     intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
 
 137                             AutomationCompositionOrderedState.PASSIVE, AutomationCompositionState.PASSIVE,
 
 138                             ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE);
 
 140                     LOGGER.error("Failed to connect with A1PMS");
 
 141                     throw new A1PolicyServiceException(HttpStatus.SC_SERVICE_UNAVAILABLE,
 
 142                             "Unable to connect with A1PMS");
 
 145                 LOGGER.error("Violations found in the config request parameters: {}", violations);
 
 146                 throw new ValidationException("Constraint violations in the config request");
 
 148         } catch (ValidationException | CoderException e) {
 
 149             LOGGER.error("Error invoking the A1PMS request for the config ", e);
 
 150             throw new A1PolicyServiceException(HttpStatus.SC_BAD_REQUEST, "Invalid Configuration", e);
 
 151         } catch (A1PolicyServiceException e) {
 
 152             LOGGER.error("Error invoking the A1PMS request for the config ", e);