980ab6ec1f8d1518976f88829f012bb6437fac54
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.controlloop.participant.intermediary.handler;
22
23 import java.io.Closeable;
24 import java.util.Objects;
25 import lombok.Getter;
26 import lombok.Setter;
27 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
28 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus;
29 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
30 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
31 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantHealthCheck;
32 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessage;
33 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseDetails;
34 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseStatus;
35 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStateChange;
36 import org.onap.policy.clamp.controlloop.participant.intermediary.comm.MessageSender;
37 import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStatusPublisher;
38 import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * This class is responsible for managing the state of a participant.
45  */
46 @Getter
47 public class ParticipantHandler implements Closeable {
48     private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantHandler.class);
49
50     private final ToscaConceptIdentifier participantType;
51     private final ToscaConceptIdentifier participantId;
52     private final MessageSender sender;
53     private final ControlLoopHandler controlLoopHandler;
54     private final ParticipantStatistics participantStatistics;
55
56     @Setter
57     private ParticipantState state = ParticipantState.UNKNOWN;
58
59     @Setter
60     private ParticipantHealthStatus healthStatus = ParticipantHealthStatus.UNKNOWN;
61
62     /**
63      * Constructor, set the participant ID and sender.
64      *
65      * @param parameters the parameters of the participant
66      * @param publisher the publisher for sending responses to messages
67      */
68     public ParticipantHandler(ParticipantIntermediaryParameters parameters, ParticipantStatusPublisher publisher) {
69         this.participantType = parameters.getParticipantType();
70         this.participantId = parameters.getParticipantId();
71         this.sender = new MessageSender(this, publisher, parameters.getReportingTimeInterval());
72         this.controlLoopHandler = new ControlLoopHandler(parameters, sender);
73         this.participantStatistics = new ParticipantStatistics();
74     }
75
76     @Override
77     public void close() {
78         sender.close();
79         controlLoopHandler.close();
80     }
81
82     /**
83      * Method which handles a participant state change event from clamp.
84      *
85      * @param stateChangeMsg participant state change message
86      */
87     public void handleParticipantStateChange(final ParticipantStateChange stateChangeMsg) {
88
89         if (!stateChangeMsg.appliesTo(participantType, participantId)) {
90             return;
91         }
92
93         ParticipantResponseDetails response = new ParticipantResponseDetails(stateChangeMsg);
94
95         switch (stateChangeMsg.getState()) {
96             case PASSIVE:
97                 handlePassiveState(response);
98                 break;
99             case ACTIVE:
100                 handleActiveState(response);
101                 break;
102             case SAFE:
103                 handleSafeState(response);
104                 break;
105             case TEST:
106                 handleTestState(response);
107                 break;
108             case TERMINATED:
109                 handleTerminatedState(response);
110                 break;
111             default:
112                 LOGGER.debug("StateChange message has no state, state is null {}", stateChangeMsg.getParticipantId());
113                 response.setResponseStatus(ParticipantResponseStatus.FAIL);
114                 response.setResponseMessage("StateChange message has invalid state for participantId "
115                     + stateChangeMsg.getParticipantId());
116                 break;
117         }
118
119         sender.sendResponse(response);
120     }
121
122
123     /**
124      * Method which handles a participant health check event from clamp.
125      *
126      * @param healthCheckMsg participant health check message
127      */
128     public void handleParticipantHealthCheck(final ParticipantHealthCheck healthCheckMsg) {
129         ParticipantResponseDetails response = new ParticipantResponseDetails(healthCheckMsg);
130         response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
131         response.setResponseMessage(healthStatus.toString());
132
133         sender.sendResponse(response);
134     }
135
136     /**
137      * Method to handle when the new state from participant is active.
138      *
139      * @param response participant response
140      */
141     private void handleActiveState(final ParticipantResponseDetails response) {
142         handleStateChange(ParticipantState.ACTIVE, response);
143     }
144
145     /**
146      * Method to handle when the new state from participant is passive.
147      *
148      * @param response participant response
149      */
150     private void handlePassiveState(final ParticipantResponseDetails response) {
151         handleStateChange(ParticipantState.PASSIVE, response);
152     }
153
154     /**
155      * Method to handle when the new state from participant is safe.
156      *
157      * @param response participant response
158      */
159     private void handleSafeState(final ParticipantResponseDetails response) {
160         handleStateChange(ParticipantState.SAFE, response);
161     }
162
163     /**
164      * Method to handle when the new state from participant is TEST.
165      *
166      * @param response participant response
167      */
168     private void handleTestState(final ParticipantResponseDetails response) {
169         handleStateChange(ParticipantState.TEST, response);
170     }
171
172     /**
173      * Method to handle when the new state from participant is Terminated.
174      *
175      * @param response participant response
176      */
177     private void handleTerminatedState(final ParticipantResponseDetails response) {
178         handleStateChange(ParticipantState.TERMINATED, response);
179     }
180
181     private void handleStateChange(ParticipantState newParticipantState, ParticipantResponseDetails response) {
182         if (state.equals(newParticipantState)) {
183             response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
184             response.setResponseMessage("Participant already in state " + newParticipantState);
185         } else {
186             response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
187             response.setResponseMessage("Participant state changed from " + state + " to " + newParticipantState);
188             state = newParticipantState;
189         }
190     }
191
192     /**
193      * Method to update participant state.
194      *
195      * @param definition participant definition
196      * @param participantState participant state
197      */
198     public Participant updateParticipantState(ToscaConceptIdentifier definition,
199             ParticipantState participantState) {
200         if (!Objects.equals(definition, participantId)) {
201             LOGGER.debug("No participant with this ID {}", definition.getName());
202             return null;
203         }
204         ParticipantResponseDetails response = new ParticipantResponseDetails();
205         handleStateChange(participantState, response);
206         sender.sendResponse(response);
207         return getParticipant(definition.getName(), definition.getVersion());
208     }
209
210     /**
211      * Get participants as a {@link Participant} class.
212      *
213      * @return the participant
214      */
215     public Participant getParticipant(String name, String version) {
216         if (participantId.getName().equals(name)) {
217             Participant participant = new Participant();
218             participant.setDefinition(participantId);
219             participant.setParticipantState(state);
220             participant.setHealthStatus(healthStatus);
221             return participant;
222         }
223         return null;
224     }
225
226     /**
227      * Check if a participant message applies to this participant handler.
228      *
229      * @param partipantMsg the message to check
230      * @return true if it applies, false otherwise
231      */
232     public boolean canHandle(ParticipantMessage partipantMsg) {
233         return partipantMsg.appliesTo(participantType, participantId);
234     }
235 }