d807dc50ed6764177a23fc871d97d97380dd5d13
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 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.apex.services.onappf.handler;
22
23 import java.util.List;
24 import org.onap.policy.apex.services.onappf.ApexStarterConstants;
25 import org.onap.policy.apex.services.onappf.comm.PdpStatusPublisher;
26 import org.onap.policy.apex.services.onappf.exception.ApexStarterException;
27 import org.onap.policy.common.endpoints.event.comm.TopicSink;
28 import org.onap.policy.common.utils.services.Registry;
29 import org.onap.policy.models.pdp.concepts.PdpResponseDetails;
30 import org.onap.policy.models.pdp.concepts.PdpStatus;
31 import org.onap.policy.models.pdp.concepts.PdpUpdate;
32 import org.onap.policy.models.pdp.enums.PdpResponseStatus;
33 import org.onap.policy.models.pdp.enums.PdpState;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * This class supports the handling of pdp update messages.
39  *
40  * @author Ajith Sreekumar (ajith.sreekumar@est.tech)
41  */
42 public class PdpUpdateMessageHandler {
43
44     private static final Logger LOGGER = LoggerFactory.getLogger(PdpUpdateMessageHandler.class);
45
46     /**
47      * Method which handles a pdp update event from PAP.
48      *
49      * @param pdpUpdateMsg pdp update message
50      */
51     public void handlePdpUpdateEvent(final PdpUpdate pdpUpdateMsg) {
52         final PdpMessageHandler pdpMessageHandler = new PdpMessageHandler();
53         final PdpStatus pdpStatusContext = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT, PdpStatus.class);
54         PdpResponseDetails pdpResponseDetails = null;
55         if (pdpUpdateMsg.appliesTo(pdpStatusContext.getName(), pdpStatusContext.getPdpGroup(),
56                 pdpStatusContext.getPdpSubgroup())) {
57             final PdpStatusPublisher pdpStatusPublisher = Registry.get(ApexStarterConstants.REG_PDP_STATUS_PUBLISHER);
58             if (checkIfAlreadyHandled(pdpUpdateMsg, pdpStatusContext)) {
59                 pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(),
60                         PdpResponseStatus.SUCCESS, "Pdp already updated");
61             } else {
62                 if (null != pdpUpdateMsg.getPdpHeartbeatIntervalMs() && pdpUpdateMsg.getPdpHeartbeatIntervalMs() > 0
63                         && pdpStatusPublisher.getInterval() != pdpUpdateMsg.getPdpHeartbeatIntervalMs()) {
64                     updateInterval(pdpUpdateMsg.getPdpHeartbeatIntervalMs());
65                 }
66                 pdpStatusContext.setPdpGroup(pdpUpdateMsg.getPdpGroup());
67                 pdpStatusContext.setPdpSubgroup(pdpUpdateMsg.getPdpSubgroup());
68                 pdpStatusContext
69                         .setPolicies(new PdpMessageHandler().getToscaPolicyIdentifiers(pdpUpdateMsg.getPolicies()));
70                 if (pdpStatusContext.getState().equals(PdpState.ACTIVE)) {
71                     pdpResponseDetails = startOrStopApexEngineBasedOnPolicies(pdpUpdateMsg, pdpMessageHandler);
72                 }
73                 Registry.registerOrReplace(ApexStarterConstants.REG_APEX_TOSCA_POLICY_LIST, pdpUpdateMsg.getPolicies());
74                 if (null == pdpResponseDetails) {
75                     pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(),
76                             PdpResponseStatus.SUCCESS, "Pdp update successful.");
77                 }
78             }
79             final PdpStatusPublisher pdpStatusPublisherTemp =
80                     Registry.get(ApexStarterConstants.REG_PDP_STATUS_PUBLISHER);
81             final PdpStatus pdpStatus = pdpMessageHandler.createPdpStatusFromContext();
82             pdpStatus.setResponse(pdpResponseDetails);
83             pdpStatus.setDescription("Pdp status response message for PdpUpdate");
84             pdpStatusPublisherTemp.send(pdpStatus);
85         }
86     }
87
88     /**
89      * Method to start or stop apex engine based on the list of policies received from pap. When current state is
90      * active, if PAP sends PdpUpdate with empty policies list, stop apex engine, or, if there is a change in policies,
91      * stop the current running policies and the deploy the new ones.
92      *
93      * @param pdpUpdateMsg the pdp update message from pap
94      * @param pdpMessageHandler pdp message handler
95      * @param pdpStatusContext the pdp status object in memory
96      * @return pdpResponseDetails the pdp response
97      */
98     private PdpResponseDetails startOrStopApexEngineBasedOnPolicies(final PdpUpdate pdpUpdateMsg,
99             final PdpMessageHandler pdpMessageHandler) {
100         PdpResponseDetails pdpResponseDetails = null;
101         ApexEngineHandler apexEngineHandler = null;
102         try {
103             apexEngineHandler = Registry.get(ApexStarterConstants.REG_APEX_ENGINE_HANDLER);
104         } catch (final IllegalArgumentException e) {
105             LOGGER.debug("ApenEngineHandler not in registry.", e);
106         }
107         if (pdpUpdateMsg.getPolicies().isEmpty()) {
108             pdpResponseDetails = stopApexEngineBasedOnPolicies(pdpUpdateMsg, pdpMessageHandler, apexEngineHandler);
109         } else {
110             pdpResponseDetails = startApexEngineBasedOnPolicies(pdpUpdateMsg, pdpMessageHandler, apexEngineHandler);
111         }
112         return pdpResponseDetails;
113     }
114
115     private PdpResponseDetails stopApexEngineBasedOnPolicies(final PdpUpdate pdpUpdateMsg,
116         final PdpMessageHandler pdpMessageHandler, ApexEngineHandler apexEngineHandler) {
117         PdpResponseDetails pdpResponseDetails = null;
118         if (null != apexEngineHandler && apexEngineHandler.isApexEngineRunning()) {
119             try {
120                 apexEngineHandler.shutdown();
121             } catch (final ApexStarterException e) {
122                 LOGGER.error("Pdp update failed as the policies couldn't be undeployed.", e);
123                 pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(),
124                         PdpResponseStatus.FAIL, "Pdp update failed as the policies couldn't be undeployed.");
125             }
126         }
127         return pdpResponseDetails;
128     }
129
130     private PdpResponseDetails startApexEngineBasedOnPolicies(final PdpUpdate pdpUpdateMsg,
131         final PdpMessageHandler pdpMessageHandler, ApexEngineHandler apexEngineHandler) {
132         PdpResponseDetails pdpResponseDetails = null;
133         try {
134             if (null != apexEngineHandler && apexEngineHandler.isApexEngineRunning()) {
135                 apexEngineHandler.shutdown();
136             }
137             apexEngineHandler =
138                     new ApexEngineHandler(pdpUpdateMsg.getPolicies().get(0).getProperties().get("content"));
139             Registry.registerOrReplace(ApexStarterConstants.REG_APEX_ENGINE_HANDLER, apexEngineHandler);
140             if (apexEngineHandler.isApexEngineRunning()) {
141                 pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(),
142                     PdpResponseStatus.SUCCESS, "Apex engine started and policies are running.");
143             } else {
144                 pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(),
145                     PdpResponseStatus.FAIL, "Apex engine failed to start.");
146             }
147         } catch (final ApexStarterException e) {
148             LOGGER.error("Apex engine service running failed. ", e);
149             pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(),
150                     PdpResponseStatus.FAIL, "Apex engine service running failed. " + e.getMessage());
151         }
152         return pdpResponseDetails;
153     }
154
155     /**
156      * Method checks if the Pdp update message is already handled by checking the values in the context.
157      *
158      * @param pdpUpdateMsg pdp update message received from pap
159      * @param pdpStatusContext values saved in context memory
160      * @return boolean flag which tells if the information is same or not
161      */
162     private boolean checkIfAlreadyHandled(final PdpUpdate pdpUpdateMsg, final PdpStatus pdpStatusContext) {
163         return null != pdpStatusContext.getPdpGroup()
164                 && pdpStatusContext.getPdpGroup().equals(pdpUpdateMsg.getPdpGroup())
165                 && null != pdpStatusContext.getPdpSubgroup()
166                 && pdpStatusContext.getPdpSubgroup().equals(pdpUpdateMsg.getPdpSubgroup())
167                 && null != pdpStatusContext.getPolicies() && new PdpMessageHandler()
168                         .getToscaPolicyIdentifiers(pdpUpdateMsg.getPolicies()).equals(pdpStatusContext.getPolicies());
169     }
170
171     /**
172      * Method to update the time interval used by the timer task.
173      *
174      * @param interval time interval received in the pdp update message from pap
175      */
176     public void updateInterval(final long interval) {
177         final PdpStatusPublisher pdpStatusPublisher = Registry.get(ApexStarterConstants.REG_PDP_STATUS_PUBLISHER);
178         pdpStatusPublisher.terminate();
179         final List<TopicSink> topicSinks = Registry.get(ApexStarterConstants.REG_APEX_PDP_TOPIC_SINKS);
180         Registry.registerOrReplace(ApexStarterConstants.REG_PDP_STATUS_PUBLISHER,
181                 new PdpStatusPublisher(topicSinks, interval));
182     }
183 }