Consolidate PolicyRestAdapter setup
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / UpdatePdpThread.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pap.xacml.rest;
22
23 import com.att.research.xacml.api.pap.PAPException;
24 import com.att.research.xacml.api.pap.PDPStatus;
25
26 import java.io.OutputStream;
27 import java.net.HttpURLConnection;
28 import java.net.URL;
29 import java.util.List;
30 import java.util.Properties;
31 import java.util.UUID;
32
33 import org.onap.policy.common.logging.OnapLoggingContext;
34 import org.onap.policy.common.logging.eelf.MessageCodes;
35 import org.onap.policy.common.logging.eelf.PolicyLogger;
36 import org.onap.policy.common.logging.flexlogger.FlexLogger;
37 import org.onap.policy.common.logging.flexlogger.Logger;
38 import org.onap.policy.pap.xacml.restAuth.CheckPDP;
39 import org.onap.policy.xacml.api.pap.OnapPDP;
40
41 public class UpdatePdpThread implements Runnable {
42
43     private static final Logger LOGGER = FlexLogger.getLogger(UpdatePdpThread.class);
44     private OnapLoggingContext baseLoggingContext = new XACMLPapServlet().getBaseLoggingContext();
45     private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
46     private static final String XACMLPAPSERVLET = "XACMLPapServlet";
47     private static final String MESSAGE = "  message: ";
48
49     private OnapPDP pdp;
50     private String requestId;
51     private OnapLoggingContext loggingContext;
52     private List<Properties> properties;
53
54     public UpdatePdpThread(OnapPDP pdp, List<Properties> properties) {
55         this.pdp = pdp;
56         this.properties = properties;
57     }
58
59     /**
60      * Instantiates a new update pdp thread.
61      *
62      * @param pdp the pdp
63      * @param loggingContext the logging context
64      * @param properties the properties
65      */
66     public UpdatePdpThread(OnapPDP pdp, OnapLoggingContext loggingContext, List<Properties> properties) {
67         this.pdp = pdp;
68         if (loggingContext != null
69                 && (loggingContext.getRequestId() != null || "".equals(loggingContext.getRequestId()))) {
70             this.requestId = loggingContext.getRequestId();
71         }
72         this.loggingContext = loggingContext;
73         this.properties = properties;
74     }
75
76     @Override
77     public void run() {
78         // send the current configuration to one PDP
79         HttpURLConnection connection = null;
80         // get a new logging context for the thread
81         try {
82             if (this.loggingContext == null) {
83                 loggingContext = new OnapLoggingContext(baseLoggingContext);
84             }
85         } catch (Exception e) {
86             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, XACMLPAPSERVLET,
87                     " Failed to send property file to " + pdp.getId());
88             // Since this is a server-side error, it probably does not
89             // reflect a problem on the client,
90             // so do not change the PDP status.
91             return;
92         }
93         try {
94             loggingContext.setServiceName("PAP:PDP.putConfig");
95             // If a requestId was provided, use it, otherwise generate one;
96             // post to loggingContext to be used later when calling PDP
97             if (requestId == null || "".equals(requestId)) {
98                 UUID requestId = UUID.randomUUID();
99                 loggingContext.setRequestId(requestId.toString());
100                 PolicyLogger
101                         .info("requestID not provided in call to XACMLPapSrvlet (UpdatePDPThread) so we generated one: "
102                                 + loggingContext.getRequestId());
103             } else {
104                 loggingContext.setRequestId(requestId);
105                 PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (UpdatePDPThread):  "
106                         + loggingContext.getRequestId());
107             }
108             loggingContext.transactionStarted();
109             // the Id of the PDP is its URL
110             if (LOGGER.isDebugEnabled()) {
111                 LOGGER.debug("creating url for id '" + pdp.getId() + "'");
112             }
113             URL url = new URL(pdp.getId() + "?cache=all");
114             // Open up the connection
115             connection = (HttpURLConnection) url.openConnection();
116             // Setup our method and headers
117             connection.setRequestMethod("PUT");
118             // Authentication
119             String encoding = CheckPDP.getEncoding(pdp.getId());
120             if (encoding != null) {
121                 connection.setRequestProperty("Authorization", "Basic " + encoding);
122             }
123             connection.setRequestProperty("Content-Type", "text/x-java-properties");
124             connection.setRequestProperty("X-ECOMP-RequestID", loggingContext.getRequestId());
125             connection.setInstanceFollowRedirects(true);
126             connection.setDoOutput(true);
127             if (!writePropertiesToStream(connection)) {
128                 return;
129             }
130             // Do the connect
131             loggingContext.metricStarted();
132             connection.connect();
133             loggingContext.metricEnded();
134             PolicyLogger.metrics("XACMLPapServlet UpdatePDPThread connection connect");
135             if (connection.getResponseCode() == 204) {
136                 LOGGER.info("Success. We are configured correctly - " + pdp.getId());
137                 loggingContext.transactionEnded();
138                 auditLogger.info("Success. PDP is configured correctly.");
139                 PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
140                 getPapInstance().setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
141             } else if (connection.getResponseCode() == 200) {
142                 LOGGER.info("Success. PDP needs to update its configuration - " + pdp.getId());
143                 loggingContext.transactionEnded();
144                 auditLogger.info("Success. PDP needs to update its configuration.");
145                 PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
146                 getPapInstance().setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
147             } else {
148                 LOGGER.warn("Failed: " + connection.getResponseCode() + MESSAGE + connection.getResponseMessage()
149                         + pdp.getId());
150                 loggingContext.transactionEnded();
151                 auditLogger.warn("Failed: " + connection.getResponseCode() + MESSAGE + connection.getResponseMessage());
152                 PolicyLogger.audit("Transaction Failed: " + connection.getResponseCode() + MESSAGE
153                         + connection.getResponseMessage());
154                 getPapInstance().setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
155             }
156         } catch (Exception e) {
157             LOGGER.debug(e);
158             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, XACMLPAPSERVLET,
159                     " Unable to sync config with PDP '" + pdp.getId() + "'");
160             loggingContext.transactionEnded();
161             PolicyLogger.audit("Transaction Failed: Unable to sync config with PDP '" + pdp.getId() + "': " + e);
162             LOGGER.info("Transaction Failed: Unable to sync config with PDP '" + pdp.getId() + "': " + e);
163             try {
164                 getPapInstance().setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
165             } catch (PAPException e1) {
166                 LOGGER.debug(e1);
167                 PolicyLogger
168                         .audit("Transaction Failed: Unable to set status of PDP " + pdp.getId() + " to UNKNOWN: " + e);
169                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, XACMLPAPSERVLET,
170                         " Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN");
171             }
172         } finally {
173             // cleanup the connection
174             if (connection != null) {
175                 connection.disconnect();
176             }
177         }
178     }
179
180     private boolean writePropertiesToStream(HttpURLConnection connection) {
181         try (OutputStream os = connection.getOutputStream()) {
182             // Policy Properties
183             properties.get(0).store(os, "");
184             // Pip Properties
185             properties.get(1).store(os, "");
186             // Policy Locations
187             if (properties.size() == 3) {
188                 properties.get(2).store(os, "");
189             }
190         } catch (Exception e) {
191             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, XACMLPAPSERVLET,
192                     " Failed to send property file to " + pdp.getId());
193             // Since this is a server-side error, it probably does not
194             // reflect a problem on the client,
195             // so do not change the PDP status.
196             return false;
197         }
198         return true;
199     }
200
201     private XACMLPapServlet getPapInstance() {
202         return new XACMLPapServlet();
203     }
204
205 }