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