From adfe6d2d2e5b11a24208b3bce5383f1c38cec61e Mon Sep 17 00:00:00 2001 From: "saul.gill" Date: Tue, 10 Jan 2023 11:11:08 +0000 Subject: Add participant controller in ACM Added participant controller Altered openapi spec Added participantId Issue-ID: POLICY-4496 Change-Id: I0c0ea93dacb6927e6f16bd4638d03db6266be3bd Signed-off-by: saul.gill --- .../runtime/main/rest/ParticipantController.java | 67 ++++++++ .../participants/AcmParticipantProvider.java | 102 ++++++++++++ .../runtime/supervision/SupervisionHandler.java | 72 ++++----- .../supervision/SupervisionParticipantHandler.java | 6 +- .../runtime/supervision/SupervisionScanner.java | 43 ++--- .../src/main/resources/openapi/openapi.yaml | 7 +- .../participant/ParticipantControllerTest.java | 176 +++++++++++++++++++++ .../SupervisionParticipantHandlerTest.java | 12 +- .../supervision/SupervisionScannerTest.java | 38 ++--- .../test/resources/providers/TestParticipant.json | 15 ++ .../test/resources/providers/TestParticipant2.json | 15 ++ 11 files changed, 463 insertions(+), 90 deletions(-) create mode 100644 runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java create mode 100644 runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java create mode 100644 runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java create mode 100644 runtime-acm/src/test/resources/providers/TestParticipant.json create mode 100644 runtime-acm/src/test/resources/providers/TestParticipant2.json (limited to 'runtime-acm') diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java new file mode 100644 index 000000000..abcef7a94 --- /dev/null +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.runtime.main.rest; + +import java.util.List; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.acm.runtime.main.rest.gen.ParticipantMonitoringApi; +import org.onap.policy.clamp.acm.runtime.main.web.AbstractRestController; +import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider; +import org.onap.policy.clamp.models.acm.concepts.ParticipantInformation; +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@Profile("default") +public class ParticipantController extends AbstractRestController implements ParticipantMonitoringApi { + + private final AcmParticipantProvider acmParticipantProvider; + + @Override + public ResponseEntity getParticipant(UUID participantId, UUID requestId) { + ParticipantInformation participantInformation = acmParticipantProvider + .getParticipantById(participantId.toString()); + return ResponseEntity.ok().body(participantInformation); + } + + @Override + public ResponseEntity orderAllParticipantsReport(UUID requestId) { + acmParticipantProvider.sendAllParticipantStatusRequest(); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + @Override + public ResponseEntity orderParticipantReport(UUID participantId, UUID requestId) { + acmParticipantProvider.sendParticipantStatusRequest(participantId.toString()); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + @Override + public ResponseEntity> queryParticipants(String name, String version, + UUID requestId) { + List participantInformationList = acmParticipantProvider.getAllParticipants(); + return ResponseEntity.ok().body(participantInformationList); + } +} diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java new file mode 100644 index 000000000..e1d0423d1 --- /dev/null +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.runtime.participants; + +import java.util.ArrayList; +import java.util.List; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantStatusReqPublisher; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.concepts.ParticipantInformation; +import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class AcmParticipantProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(AcmParticipantProvider.class); + private final ParticipantProvider participantProvider; + private final ParticipantStatusReqPublisher participantStatusReqPublisher; + + public AcmParticipantProvider(ParticipantProvider participantProvider, + ParticipantStatusReqPublisher participantStatusReqPublisher) { + this.participantProvider = participantProvider; + this.participantStatusReqPublisher = participantStatusReqPublisher; + } + + /** + * Get all participants. + * + * @return A list of available participants + */ + public List getAllParticipants() { + List participants = this.participantProvider.getParticipants(); + + List participantInformationList = new ArrayList<>(); + participants.forEach(participant -> { + ParticipantInformation participantInformation = new ParticipantInformation(); + participantInformation.setParticipant(participant); + participantInformationList.add(participantInformation); + }); + return participantInformationList; + } + + /** + * Get a participant. + * + * @param participantId The UUID of the participant to get + * @return The participant + */ + public ParticipantInformation getParticipantById(String participantId) { + Participant participant = this.participantProvider.getParticipantById(participantId); + ParticipantInformation participantInformation = new ParticipantInformation(); + participantInformation.setParticipant(participant); + return participantInformation; + } + + /** + * Send a participant status request. + * + * @param participantId The UUID of the participant to send request to + */ + public void sendParticipantStatusRequest(String participantId) { + Participant participant = this.participantProvider.getParticipantById(participantId); + ToscaConceptIdentifier id = participant.getKey().asIdentifier(); + + LOGGER.debug("Requesting Participant Status Now ParticipantStatusReq"); + participantStatusReqPublisher.send(id); + participant.setParticipantState(ParticipantState.OFF_LINE); + participantProvider.updateParticipant(participant); + } + + /** + * Send status request to all participants. + * + */ + public void sendAllParticipantStatusRequest() { + this.participantStatusReqPublisher.send((ToscaConceptIdentifier) null); + } +} diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java index c27447405..761c3800c 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java @@ -57,9 +57,9 @@ public class SupervisionHandler { private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionHandler.class); private static final String AUTOMATION_COMPOSITION_CANNOT_TRANSITION_FROM_STATE = - "Automation composition can't transition from state "; + "Automation composition can't transition from state "; private static final String AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE = - "Automation composition is already in state "; + "Automation composition is already in state "; private static final String TO_STATE = " to state "; private static final String AND_TRANSITIONING_TO_STATE = " and transitioning to state "; @@ -78,7 +78,7 @@ public class SupervisionHandler { */ public void handleSendCommissionMessage(AutomationCompositionDefinition acmDefinition) { LOGGER.debug("Participant update message with serviveTemplate {} being sent to all participants", - acmDefinition.getCompositionId()); + acmDefinition.getCompositionId()); participantUpdatePublisher.sendComissioningBroadcast(acmDefinition); } @@ -98,8 +98,8 @@ public class SupervisionHandler { */ @MessageIntercept @Timed( - value = "listener.automation_composition_update_ack", - description = "AUTOMATION_COMPOSITION_UPDATE_ACK messages received") + value = "listener.automation_composition_update_ack", + description = "AUTOMATION_COMPOSITION_UPDATE_ACK messages received") public void handleAutomationCompositionUpdateAckMessage(AutomationCompositionAck automationCompositionAckMessage) { LOGGER.debug("AutomationComposition Update Ack message received {}", automationCompositionAckMessage); setAcElementStateInDb(automationCompositionAckMessage); @@ -123,10 +123,10 @@ public class SupervisionHandler { */ @MessageIntercept @Timed( - value = "listener.automation_composition_statechange_ack", - description = "AUTOMATION_COMPOSITION_STATECHANGE_ACK messages received") + value = "listener.automation_composition_statechange_ack", + description = "AUTOMATION_COMPOSITION_STATECHANGE_ACK messages received") public void handleAutomationCompositionStateChangeAckMessage( - AutomationCompositionAck automationCompositionAckMessage) { + AutomationCompositionAck automationCompositionAckMessage) { LOGGER.debug("AutomationComposition StateChange Ack message received {}", automationCompositionAckMessage); setAcElementStateInDb(automationCompositionAckMessage); } @@ -134,23 +134,23 @@ public class SupervisionHandler { private void setAcElementStateInDb(AutomationCompositionAck automationCompositionAckMessage) { if (automationCompositionAckMessage.getAutomationCompositionResultMap() != null) { var automationComposition = automationCompositionProvider - .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId()); + .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId()); if (automationComposition.isPresent()) { var updated = updateState(automationComposition.get(), - automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet()); + automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet()); updated |= setPrimed(automationComposition.get()); if (updated) { automationCompositionProvider.updateAutomationComposition(automationComposition.get()); } } else { LOGGER.warn("AutomationComposition not found in database {}", - automationCompositionAckMessage.getAutomationCompositionId()); + automationCompositionAckMessage.getAutomationCompositionId()); } } } private boolean updateState(AutomationComposition automationComposition, - Set> automationCompositionResultSet) { + Set> automationCompositionResultSet) { var updated = false; for (var acElementAck : automationCompositionResultSet) { var element = automationComposition.getElements().get(acElementAck.getKey()); @@ -167,9 +167,9 @@ public class SupervisionHandler { if (acElements != null) { Boolean primedFlag = true; var checkOpt = automationComposition.getElements().values().stream() - .filter(acElement -> (!acElement.getState().equals(AutomationCompositionState.PASSIVE) - || !acElement.getState().equals(AutomationCompositionState.RUNNING))) - .findAny(); + .filter(acElement -> (!acElement.getState().equals(AutomationCompositionState.PASSIVE) + || !acElement.getState().equals(AutomationCompositionState.RUNNING))) + .findAny(); if (checkOpt.isEmpty()) { primedFlag = false; } @@ -188,7 +188,7 @@ public class SupervisionHandler { * @throws AutomationCompositionException on supervision errors */ public void triggerAutomationCompositionSupervision(AutomationComposition automationComposition) - throws AutomationCompositionException { + throws AutomationCompositionException { switch (automationComposition.getOrderedState()) { case UNINITIALISED: superviseAutomationCompositionUninitialization(automationComposition); @@ -204,8 +204,8 @@ public class SupervisionHandler { default: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - "A automation composition cannot be commanded to go into state " - + automationComposition.getOrderedState().name()); + "A automation composition cannot be commanded to go into state " + + automationComposition.getOrderedState().name()); } } @@ -218,39 +218,39 @@ public class SupervisionHandler { * @throws AutomationCompositionException on supervision errors */ private void superviseAutomationCompositionUninitialization(AutomationComposition automationComposition) - throws AutomationCompositionException { + throws AutomationCompositionException { switch (automationComposition.getState()) { case UNINITIALISED: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name()); + AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name()); break; case UNINITIALISED2PASSIVE: case PASSIVE: automationComposition.setState(AutomationCompositionState.PASSIVE2UNINITIALISED); automationCompositionStateChangePublisher.send(automationComposition, - getFirstStartPhase(automationComposition)); + getFirstStartPhase(automationComposition)); break; case PASSIVE2UNINITIALISED: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name() - + AND_TRANSITIONING_TO_STATE + automationComposition.getOrderedState()); + AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name() + + AND_TRANSITIONING_TO_STATE + automationComposition.getOrderedState()); break; default: exceptionOccured(Response.Status.NOT_ACCEPTABLE, AUTOMATION_COMPOSITION_CANNOT_TRANSITION_FROM_STATE - + automationComposition.getState().name() + TO_STATE + automationComposition.getOrderedState()); + + automationComposition.getState().name() + TO_STATE + automationComposition.getOrderedState()); break; } } private void superviseAutomationCompositionPassivation(AutomationComposition automationComposition) - throws AutomationCompositionException { + throws AutomationCompositionException { switch (automationComposition.getState()) { case PASSIVE: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name()); + AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name()); break; case UNINITIALISED: automationComposition.setState(AutomationCompositionState.UNINITIALISED2PASSIVE); @@ -260,46 +260,46 @@ public class SupervisionHandler { case UNINITIALISED2PASSIVE: case RUNNING2PASSIVE: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name() - + AND_TRANSITIONING_TO_STATE + automationComposition.getOrderedState()); + AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name() + + AND_TRANSITIONING_TO_STATE + automationComposition.getOrderedState()); break; case RUNNING: automationComposition.setState(AutomationCompositionState.RUNNING2PASSIVE); automationCompositionStateChangePublisher.send(automationComposition, - getFirstStartPhase(automationComposition)); + getFirstStartPhase(automationComposition)); break; default: exceptionOccured(Response.Status.NOT_ACCEPTABLE, AUTOMATION_COMPOSITION_CANNOT_TRANSITION_FROM_STATE - + automationComposition.getState().name() + TO_STATE + automationComposition.getOrderedState()); + + automationComposition.getState().name() + TO_STATE + automationComposition.getOrderedState()); break; } } private void superviseAutomationCompositionActivation(AutomationComposition automationComposition) - throws AutomationCompositionException { + throws AutomationCompositionException { switch (automationComposition.getState()) { case RUNNING: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name()); + AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name()); break; case PASSIVE2RUNNING: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name() - + AND_TRANSITIONING_TO_STATE + automationComposition.getOrderedState()); + AUTOMATION_COMPOSITION_IS_ALREADY_IN_STATE + automationComposition.getState().name() + + AND_TRANSITIONING_TO_STATE + automationComposition.getOrderedState()); break; case PASSIVE: automationComposition.setState(AutomationCompositionState.PASSIVE2RUNNING); automationCompositionStateChangePublisher.send(automationComposition, - getFirstStartPhase(automationComposition)); + getFirstStartPhase(automationComposition)); break; default: exceptionOccured(Response.Status.NOT_ACCEPTABLE, AUTOMATION_COMPOSITION_CANNOT_TRANSITION_FROM_STATE - + automationComposition.getState().name() + TO_STATE + automationComposition.getOrderedState()); + + automationComposition.getState().name() + TO_STATE + automationComposition.getOrderedState()); break; } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java index da9187d22..2c9e84ba7 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java @@ -59,7 +59,7 @@ public class SupervisionParticipantHandler { saveParticipantStatus(participantRegisterMsg); participantRegisterAckPublisher.send(participantRegisterMsg.getMessageId(), - participantRegisterMsg.getParticipantId(), participantRegisterMsg.getParticipantType()); + participantRegisterMsg.getParticipantId(), participantRegisterMsg.getParticipantType()); } /** @@ -76,7 +76,7 @@ public class SupervisionParticipantHandler { if (participantOpt.isPresent()) { var participant = participantOpt.get(); participant.setParticipantState(ParticipantState.OFF_LINE); - participantProvider.saveParticipant(participant); + participantProvider.updateParticipant(participant); } participantDeregisterAckPublisher.send(participantDeregisterMsg.getMessageId()); @@ -110,7 +110,7 @@ public class SupervisionParticipantHandler { var participant = participantOpt.get(); participant.setParticipantState(ParticipantState.ON_LINE); - participantProvider.saveParticipant(participant); + participantProvider.updateParticipant(participant); } } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java index e595f3bee..f758c9893 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java @@ -71,10 +71,11 @@ public class SupervisionScanner { * @param acRuntimeParameterGroup the parameters for the automation composition runtime */ public SupervisionScanner(final AutomationCompositionProvider automationCompositionProvider, - AcDefinitionProvider acDefinitionProvider, - final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher, - AutomationCompositionUpdatePublisher automationCompositionUpdatePublisher, - ParticipantProvider participantProvider, final AcRuntimeParameterGroup acRuntimeParameterGroup) { + AcDefinitionProvider acDefinitionProvider, + final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher, + AutomationCompositionUpdatePublisher automationCompositionUpdatePublisher, + ParticipantProvider participantProvider, + final AcRuntimeParameterGroup acRuntimeParameterGroup) { this.automationCompositionProvider = automationCompositionProvider; this.acDefinitionProvider = acDefinitionProvider; this.automationCompositionStateChangePublisher = automationCompositionStateChangePublisher; @@ -82,12 +83,12 @@ public class SupervisionScanner { this.participantProvider = participantProvider; automationCompositionCounter.setMaxRetryCount( - acRuntimeParameterGroup.getParticipantParameters().getUpdateParameters().getMaxRetryCount()); + acRuntimeParameterGroup.getParticipantParameters().getUpdateParameters().getMaxRetryCount()); automationCompositionCounter - .setMaxWaitMs(acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs()); + .setMaxWaitMs(acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs()); participantStatusCounter.setMaxRetryCount( - acRuntimeParameterGroup.getParticipantParameters().getUpdateParameters().getMaxRetryCount()); + acRuntimeParameterGroup.getParticipantParameters().getUpdateParameters().getMaxRetryCount()); participantStatusCounter.setMaxWaitMs(acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs()); } @@ -123,11 +124,11 @@ public class SupervisionScanner { return; } if (participantStatusCounter.getDuration(id) > participantStatusCounter.getMaxWaitMs() - && !participantStatusCounter.count(id)) { + && !participantStatusCounter.count(id)) { LOGGER.debug("report Participant fault"); participantStatusCounter.setFault(id); participant.setParticipantState(ParticipantState.OFF_LINE); - participantProvider.saveParticipant(participant); + participantProvider.updateParticipant(participant); } } @@ -139,7 +140,7 @@ public class SupervisionScanner { } private void scanAutomationComposition(final AutomationComposition automationComposition, - ToscaServiceTemplate toscaServiceTemplate, boolean counterCheck) { + ToscaServiceTemplate toscaServiceTemplate, boolean counterCheck) { LOGGER.debug("scanning automation composition {} . . .", automationComposition.getInstanceId()); if (automationComposition.getState().equals(automationComposition.getOrderedState().asState())) { @@ -157,7 +158,7 @@ public class SupervisionScanner { var defaultMax = 0; // max startPhase for (var element : automationComposition.getElements().values()) { var toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates() - .get(element.getDefinition().getName()); + .get(element.getDefinition().getName()); int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()); defaultMin = Math.min(defaultMin, startPhase); defaultMax = Math.max(defaultMax, startPhase); @@ -170,7 +171,7 @@ public class SupervisionScanner { if (completed) { LOGGER.debug("automation composition scan: transition from state {} to {} completed", - automationComposition.getState(), automationComposition.getOrderedState()); + automationComposition.getState(), automationComposition.getOrderedState()); automationComposition.setState(automationComposition.getOrderedState().asState()); automationCompositionProvider.updateAutomationComposition(automationComposition); @@ -179,19 +180,19 @@ public class SupervisionScanner { clearFaultAndCounter(automationComposition); } else { LOGGER.debug("automation composition scan: transition from state {} to {} not completed", - automationComposition.getState(), automationComposition.getOrderedState()); + automationComposition.getState(), automationComposition.getOrderedState()); var nextSpNotCompleted = - AutomationCompositionState.UNINITIALISED2PASSIVE.equals(automationComposition.getState()) - || AutomationCompositionState.PASSIVE2RUNNING.equals(automationComposition.getState()) - ? minSpNotCompleted - : maxSpNotCompleted; + AutomationCompositionState.UNINITIALISED2PASSIVE.equals(automationComposition.getState()) + || AutomationCompositionState.PASSIVE2RUNNING.equals(automationComposition.getState()) + ? minSpNotCompleted + : maxSpNotCompleted; var firstStartPhase = - AutomationCompositionState.UNINITIALISED2PASSIVE.equals(automationComposition.getState()) - || AutomationCompositionState.PASSIVE2RUNNING.equals(automationComposition.getState()) - ? defaultMin - : defaultMax; + AutomationCompositionState.UNINITIALISED2PASSIVE.equals(automationComposition.getState()) + || AutomationCompositionState.PASSIVE2RUNNING.equals(automationComposition.getState()) + ? defaultMin + : defaultMax; if (nextSpNotCompleted != phaseMap.getOrDefault(automationComposition.getInstanceId(), firstStartPhase)) { phaseMap.put(automationComposition.getInstanceId(), nextSpNotCompleted); diff --git a/runtime-acm/src/main/resources/openapi/openapi.yaml b/runtime-acm/src/main/resources/openapi/openapi.yaml index 655ce7eeb..f2692a900 100644 --- a/runtime-acm/src/main/resources/openapi/openapi.yaml +++ b/runtime-acm/src/main/resources/openapi/openapi.yaml @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2022 Nordix Foundation +# Copyright (C) 2022-2023 Nordix Foundation # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -65,7 +65,6 @@ paths: - name: X-onap-RequestId in: header description: RequestID for http transaction - required: true schema: type: string format: uuid @@ -138,7 +137,7 @@ paths: description: Requests all participants to immediately generate a heartbeat report with their information and status and the information and status of all their AC Element Types and Instances. The results are published on subsequent GET REST requests on the "participants" endpoint. - operationId: orderAllParticiantsReport + operationId: orderAllParticipantsReport parameters: - name: X-onap-RequestId in: header @@ -230,7 +229,6 @@ paths: - name: X-onap-RequestId in: header description: RequestID for http transaction - required: true schema: type: string format: uuid @@ -331,7 +329,6 @@ paths: format: uuid - name: X-onap-RequestId in: header - required: true description: RequestID for http transaction schema: type: string diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java new file mode 100644 index 000000000..e6f7118da --- /dev/null +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.runtime.participant; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.runtime.main.rest.ParticipantController; +import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.concepts.ParticipantInformation; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaParticipant; +import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; +import org.onap.policy.clamp.models.acm.persistence.provider.ProviderUtils; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.base.PfModelException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +/** + * Class to perform unit test of {@link ParticipantController}. + * + */ + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles({ "test", "default" }) +public class ParticipantControllerTest extends CommonRestController { + private static final String PARTICIPANTS_ENDPOINT = "participants"; + + @LocalServerPort + private int randomServerPort; + + private static final Coder CODER = new StandardCoder(); + private static final String PARTICIPANT_JSON = "src/test/resources/providers/TestParticipant.json"; + private static final String PARTICIPANT_JSON2 = "src/test/resources/providers/TestParticipant2.json"; + private static final String LIST_IS_NULL = ".*. is marked .*ull but is null"; + + private static final List inputParticipants = new ArrayList<>(); + private static List jpaParticipantList; + private static final String originalJson = ResourceUtils.getResourceAsString(PARTICIPANT_JSON); + private static final String originalJson2 = ResourceUtils.getResourceAsString(PARTICIPANT_JSON2); + + @Autowired + private ParticipantProvider participantProvider; + + /** + * Adds participants to the db from json file. + */ + @BeforeAll + public static void setUpBeforeClass() throws CoderException { + inputParticipants.add(CODER.decode(originalJson, Participant.class)); + inputParticipants.add(CODER.decode(originalJson2, Participant.class)); + jpaParticipantList = ProviderUtils.getJpaAndValidateList( + inputParticipants, JpaParticipant::new, "participant"); + } + + @BeforeEach + public void setUpPort() { + super.setHttpPrefix(randomServerPort); + } + + @Test + void testSwagger() { + super.testSwagger(PARTICIPANTS_ENDPOINT); + } + + @Test + void testUnauthorizedQuery() { + assertUnauthorizedGet(PARTICIPANTS_ENDPOINT); + } + + @Test + void testQueryParticipant() { + participantProvider.saveParticipant(inputParticipants.get(0)); + UUID participantId = participantProvider.getParticipants().get(0).getParticipantId(); + var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + "/" + participantId); + var response = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + var entityList = response.readEntity(ParticipantInformation.class); + assertNotNull(entityList); + } + + @Test + void testBadQueryParticipant() { + participantProvider.saveParticipant(inputParticipants.get(0)); + UUID participantId = participantProvider.getParticipants().get(0).getParticipantId(); + var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + "/" + UUID.randomUUID()); + var response = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + } + + @Test + void getAllParticipants() { + inputParticipants.forEach(p -> { + participantProvider.saveParticipant(p); + }); + var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT); + var response = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + List entityList = response.readEntity(new GenericType<>() {}); + assertThat(entityList.size() == inputParticipants.size()); + } + + @Test + void testOrderParticipantReport() throws PfModelException { + participantProvider.saveParticipant(inputParticipants.get(0)); + UUID participantId = participantProvider.getParticipants().get(0).getParticipantId(); + var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + + "/" + + participantId); + var response = invocationBuilder.header("Content-Length", 0).put(Entity.entity("" + + + "", MediaType.APPLICATION_JSON)); + assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus()); + } + + @Test + void testBadOrderParticipantReport() throws PfModelException { + var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + + "/" + + UUID.randomUUID()); + var response = invocationBuilder.header("Content-Length", 0).put(Entity.entity("" + + + "", MediaType.APPLICATION_JSON)); + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + } + + @Test + void testOrderAllParticipantReport() { + inputParticipants.forEach(p -> { + participantProvider.saveParticipant(p); + }); + var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT); + var response = invocationBuilder.header("Content-Length", 0).put(Entity.entity("" + + + "", MediaType.APPLICATION_JSON)); + assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus()); + } +} diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java index 9e35f2cf5..f7c18b67b 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java @@ -41,7 +41,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; class SupervisionParticipantHandlerTest { private static final ToscaConceptIdentifier PARTICIPANT_ID = new ToscaConceptIdentifier("ParticipantId", "1.0.0"); private static final ToscaConceptIdentifier PARTICIPANT_TYPE = - new ToscaConceptIdentifier("ParticipantType", "1.0.0"); + new ToscaConceptIdentifier("ParticipantType", "1.0.0"); @Test void testHandleParticipantDeregister() { @@ -59,11 +59,11 @@ class SupervisionParticipantHandlerTest { participantDeregisterMessage.setParticipantType(PARTICIPANT_TYPE); var participantDeregisterAckPublisher = mock(ParticipantDeregisterAckPublisher.class); var handler = new SupervisionParticipantHandler(participantProvider, - mock(ParticipantRegisterAckPublisher.class), participantDeregisterAckPublisher); + mock(ParticipantRegisterAckPublisher.class), participantDeregisterAckPublisher); handler.handleParticipantMessage(participantDeregisterMessage); - verify(participantProvider).saveParticipant(any()); + verify(participantProvider).updateParticipant(any()); verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId()); } @@ -81,13 +81,13 @@ class SupervisionParticipantHandlerTest { var participantProvider = mock(ParticipantProvider.class); var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class); var handler = new SupervisionParticipantHandler(participantProvider, participantRegisterAckPublisher, - mock(ParticipantDeregisterAckPublisher.class)); + mock(ParticipantDeregisterAckPublisher.class)); handler.handleParticipantMessage(participantRegisterMessage); verify(participantProvider).saveParticipant(any()); verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(), PARTICIPANT_ID, - PARTICIPANT_TYPE); + PARTICIPANT_TYPE); } @Test @@ -99,7 +99,7 @@ class SupervisionParticipantHandlerTest { var participantProvider = mock(ParticipantProvider.class); var handler = new SupervisionParticipantHandler(participantProvider, - mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class)); + mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class)); handler.handleParticipantMessage(participantStatusMessage); verify(participantProvider).saveParticipant(any()); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java index 0142f294c..1e07ec9cf 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java @@ -61,7 +61,7 @@ class SupervisionScannerTest { private static UUID compositionId; private static final ToscaConceptIdentifier PARTICIPANT_TYPE = - new ToscaConceptIdentifier("org.onap.policy.clamp.acm.PolicyParticipant", PARTICIPANT_VERSION); + new ToscaConceptIdentifier("org.onap.policy.clamp.acm.PolicyParticipant", PARTICIPANT_VERSION); @BeforeAll public static void setUpBeforeAll() { @@ -83,11 +83,11 @@ class SupervisionScannerTest { var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId)) - .thenReturn(List.of(automationComposition)); + .thenReturn(List.of(automationComposition)); var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider, - automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, - acRuntimeParameterGroup); + automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, + acRuntimeParameterGroup); supervisionScanner.run(false); verify(automationCompositionProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class)); @@ -100,7 +100,7 @@ class SupervisionScannerTest { automationComposition.setOrderedState(AutomationCompositionOrderedState.UNINITIALISED); var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId)) - .thenReturn(List.of(automationComposition)); + .thenReturn(List.of(automationComposition)); var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class); var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); @@ -108,8 +108,8 @@ class SupervisionScannerTest { var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider, - automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, - acRuntimeParameterGroup); + automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, + acRuntimeParameterGroup); supervisionScanner.run(false); verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class)); @@ -120,7 +120,7 @@ class SupervisionScannerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var automationComposition = new AutomationComposition(); when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId)) - .thenReturn(List.of(automationComposition)); + .thenReturn(List.of(automationComposition)); var participantProvider = mock(ParticipantProvider.class); var participant = new Participant(); @@ -133,8 +133,8 @@ class SupervisionScannerTest { var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider, - automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, - acRuntimeParameterGroup); + automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, + acRuntimeParameterGroup); supervisionScanner.handleParticipantStatus(participant.getKey().asIdentifier()); supervisionScanner.run(true); @@ -148,7 +148,7 @@ class SupervisionScannerTest { automationComposition.setOrderedState(AutomationCompositionOrderedState.PASSIVE); for (var element : automationComposition.getElements().values()) { if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement" - .equals(element.getDefinition().getName())) { + .equals(element.getDefinition().getName())) { element.setOrderedState(AutomationCompositionOrderedState.PASSIVE); element.setState(AutomationCompositionState.UNINITIALISED); } else { @@ -159,7 +159,7 @@ class SupervisionScannerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId)) - .thenReturn(List.of(automationComposition)); + .thenReturn(List.of(automationComposition)); var participantProvider = mock(ParticipantProvider.class); var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class); @@ -167,8 +167,8 @@ class SupervisionScannerTest { var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider, - automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, - acRuntimeParameterGroup); + automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, + acRuntimeParameterGroup); supervisionScanner.run(false); @@ -180,7 +180,7 @@ class SupervisionScannerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var automationComposition = new AutomationComposition(); when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId)) - .thenReturn(List.of(automationComposition)); + .thenReturn(List.of(automationComposition)); var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanParticipant"); acRuntimeParameterGroup.getParticipantParameters().getUpdateParameters().setMaxWaitMs(-1); @@ -199,14 +199,14 @@ class SupervisionScannerTest { var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider, - automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, - acRuntimeParameterGroup); + automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider, + acRuntimeParameterGroup); supervisionScanner.handleParticipantStatus(participant.getKey().asIdentifier()); supervisionScanner.run(true); - verify(participantProvider, times(0)).saveParticipant(any()); + verify(participantProvider, times(0)).updateParticipant(any()); supervisionScanner.run(true); - verify(participantProvider, times(1)).saveParticipant(any()); + verify(participantProvider, times(1)).updateParticipant(any()); } } diff --git a/runtime-acm/src/test/resources/providers/TestParticipant.json b/runtime-acm/src/test/resources/providers/TestParticipant.json new file mode 100644 index 000000000..fe06ba091 --- /dev/null +++ b/runtime-acm/src/test/resources/providers/TestParticipant.json @@ -0,0 +1,15 @@ +{ + "name": "dummy_participant1", + "version": "1.0.1", + "definition": { + "name": "org.onap.domain.pmsh.PMSHAutomationCompositionDefinition", + "version": "1.0.0" + }, + "participantState": "ON_LINE", + "description": "A dummy PMSH participant1", + "participantId": "82fd8ef9-1d1e-4343-9b28-7f9564ee3de6", + "participantType": { + "name": "org.onap.domain.pmsh.PolicyAutomationCompositionDefinition", + "version": "1.0.0" + } +} diff --git a/runtime-acm/src/test/resources/providers/TestParticipant2.json b/runtime-acm/src/test/resources/providers/TestParticipant2.json new file mode 100644 index 000000000..9a341844a --- /dev/null +++ b/runtime-acm/src/test/resources/providers/TestParticipant2.json @@ -0,0 +1,15 @@ +{ + "name": "dummy_participant2", + "version": "1.0.1", + "definition": { + "name": "org.onap.domain.pmsh.PMSHAutomationCompositionDefinition2", + "version": "1.0.0" + }, + "participantState": "ON_LINE", + "description": "A dummy PMSH participant2", + "participantId": "cac01d0a-7ba8-4dda-b9be-6983c46c0546", + "participantType": { + "name": "org.onap.domain.pmsh.PolicyAutomationCompositionDefinition2", + "version": "1.0.0" + } +} -- cgit 1.2.3-korg