Make xacml pdpType configurable
[policy/xacml-pdp.git] / main / src / main / java / org / onap / policy / pdpx / main / XacmlState.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
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.pdpx.main;
22
23 import java.util.Collections;
24 import org.apache.commons.lang3.StringUtils;
25 import org.onap.policy.common.utils.network.NetworkUtil;
26 import org.onap.policy.models.pdp.concepts.PdpMessage;
27 import org.onap.policy.models.pdp.concepts.PdpResponseDetails;
28 import org.onap.policy.models.pdp.concepts.PdpStateChange;
29 import org.onap.policy.models.pdp.concepts.PdpStatus;
30 import org.onap.policy.models.pdp.concepts.PdpUpdate;
31 import org.onap.policy.models.pdp.enums.PdpHealthStatus;
32 import org.onap.policy.models.pdp.enums.PdpResponseStatus;
33 import org.onap.policy.models.pdp.enums.PdpState;
34 import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager;
35 import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Current state of this XACML PDP.
41  */
42 public class XacmlState {
43     // The logger for this class
44     private static final Logger LOGGER = LoggerFactory.getLogger(XacmlState.class);
45
46     /**
47      * The application manager.
48      */
49     private final XacmlPdpApplicationManager appManager;
50
51     /**
52      * Records the current state of this PDP.
53      */
54     private final PdpStatus status;
55
56     /**
57      * Constructs the object, initializing the state.
58      */
59     public XacmlState(XacmlPdpApplicationManager appManager, String pdpGroupName, String pdpType) {
60         this.appManager = appManager;
61
62         this.status = new PdpStatus();
63         this.status.setName(NetworkUtil.getHostname());
64         this.status.setPdpType(pdpType);
65         this.status.setState(PdpState.PASSIVE);
66         this.status.setPolicies(Collections.emptyList());
67         this.status.setPdpGroup(pdpGroupName);
68     }
69
70     /**
71      * Determines if this PDP should handle the given message.
72      *
73      * @param message message of interest
74      * @return {@code true} if this PDP should handle the message, {@code false} otherwise
75      */
76     public boolean shouldHandle(PdpMessage message) {
77         return message.appliesTo(status.getName(), status.getPdpGroup(), status.getPdpSubgroup());
78     }
79
80     /**
81      * Generates a new heart beat message.
82      *
83      * @return a new heart beat message
84      */
85     public PdpStatus genHeartbeat() {
86         // first, update status fields
87         status.setHealthy(XacmlPdpActivator.getCurrent().isAlive() ? PdpHealthStatus.HEALTHY
88                         : PdpHealthStatus.NOT_HEALTHY);
89
90         return new PdpStatus(status);
91     }
92
93     /**
94      * Updates the internal state based on the given message.
95      *
96      * @param message message from which to update the internal state
97      * @return a response to the message
98      */
99     public PdpStatus updateInternalState(PdpStateChange message) {
100         status.setState(message.getState());
101
102         /*
103          * NOTE: Do NOT update group & subgroup as state-change requests do not set those
104          * fields to indicate new values; they only set them to do broadcasts to all PDPs
105          * within a group/subgroup.
106          */
107
108         PdpStatus status2 = makeResponse(message, "");
109
110         // start/stop rest controller based on state change
111         handleXacmlRestController();
112
113         // these fields aren't needed in the response, so clear them out to avoid sending
114         status2.setPolicies(null);
115
116         return status2;
117     }
118
119     /**
120      * Updates the internal state based on the given message. Assumes that the policies
121      * have already been updated within the application manager.
122      *
123      * @param message message from which to update the internal state
124      * @return a response to the message
125      */
126     public PdpStatus updateInternalState(PdpUpdate message, String errMessage) {
127         status.setPdpSubgroup(message.getPdpSubgroup());
128         status.setPolicies(appManager.getToscaPolicyIdentifiers());
129
130         return makeResponse(message, errMessage);
131     }
132
133     /**
134      * Updates the internal state to Terminated.
135      *
136      * @return the current PdpStatus with Terminated state
137      */
138     public PdpStatus terminatePdpMessage() {
139         status.setState(PdpState.TERMINATED);
140         return new PdpStatus(status);
141     }
142
143     /**
144      * Makes a response to the given message, based on the current state.
145      *
146      * @param message message for which the response should be made
147      * @param errMessage the error message to be sent to PAP
148      * @return a new response
149      */
150     private PdpStatus makeResponse(PdpMessage message, String errMessage) {
151         PdpResponseDetails resp = new PdpResponseDetails();
152
153         if (StringUtils.isBlank(errMessage)) {
154             resp.setResponseStatus(PdpResponseStatus.SUCCESS);
155         } else {
156             resp.setResponseStatus(PdpResponseStatus.FAIL);
157             resp.setResponseMessage(errMessage);
158         }
159         resp.setResponseTo(message.getRequestId());
160
161         PdpStatus status2 = new PdpStatus(status);
162         status2.setResponse(resp);
163         return status2;
164     }
165
166     /**
167      * Manages the Xacml-Pdp rest controller based on the Xacml-Pdp State.
168      * Current supported states:
169      * ACTIVE  - rest service is running and handling requests
170      * PASSIVE - rest service is not running
171      */
172     private void handleXacmlRestController() {
173         if (status.getState() == PdpState.ACTIVE) {
174             LOGGER.info("State change: {} - Starting rest controller", status.getState());
175             XacmlPdpActivator.getCurrent().startXacmlRestController();
176         } else if (status.getState() == PdpState.PASSIVE) {
177             LOGGER.info("State change: {} - Stopping rest controller", status.getState());
178             XacmlPdpActivator.getCurrent().stopXacmlRestController();
179         } else {
180             // unsupported state
181             LOGGER.warn("Unsupported state: {}", status.getState());
182         }
183     }
184 }