2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.openecomp.policy.pdp.rest;
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.net.HttpURLConnection;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.file.Files;
33 import java.util.Base64;
34 import java.util.Properties;
35 import java.util.UUID;
37 import org.apache.commons.io.IOUtils;
38 import org.openecomp.policy.pdp.rest.XACMLPdpServlet.PutRequest;
39 import org.openecomp.policy.rest.XACMLRestProperties;
41 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
42 import com.att.research.xacml.util.XACMLProperties;
44 import org.openecomp.policy.common.logging.ECOMPLoggingContext;
45 import org.openecomp.policy.common.logging.eelf.PolicyLogger;
46 import org.openecomp.policy.common.logging.flexlogger.*;
48 public class XACMLPdpRegisterThread implements Runnable {
49 private static final Logger logger = FlexLogger.getLogger(XACMLPdpRegisterThread.class);
50 private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
51 private ECOMPLoggingContext baseLoggingContext = null;
55 public volatile boolean isRunning = false;
57 public XACMLPdpRegisterThread(ECOMPLoggingContext baseLoggingContext) {
58 this.baseLoggingContext = baseLoggingContext;
61 public synchronized boolean isRunning() {
62 return this.isRunning;
65 public synchronized void terminate() {
66 this.isRunning = false;
71 * This is our thread that runs on startup to tell the PAP server we are up-and-running.
77 this.isRunning = true;
79 // get a new logging context for the thread
80 ECOMPLoggingContext loggingContext = new ECOMPLoggingContext(baseLoggingContext);
81 loggingContext.setServiceName("PDP:PAP.register");
82 //are we registered with at least one
83 boolean registered = false;
84 boolean interrupted = false;
88 seconds = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_SLEEP));
89 } catch (NumberFormatException e) {
90 logger.error( XACMLErrorConstants.ERROR_SYSTEM_ERROR +"REGISTER_SLEEP: ", e);
98 retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_RETRIES));
99 } catch (NumberFormatException e) {
100 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR +" REGISTER_SLEEP: ", e);
104 PapUrlResolver papUrls = PapUrlResolver.getInstance();
105 //while (! registered && ! interrupted && this.isRunning()) {
106 String tempRootPoliciesProperty = XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
107 String tempReferencedPoliciesProperty = XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
108 Properties tempPipConfigProperties = new Properties();
109 try(InputStream pipFile = Files.newInputStream(XACMLPdpLoader.getPIPConfig())){
110 tempPipConfigProperties.load(pipFile);
111 } catch(Exception e){
112 logger.error("Failed to open PIP property file", e);
113 // TODO:EELF Cleanup - Remove logger
114 //PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPdpRegisterThread", "Failed to open PIP property file");
116 while(papUrls.hasMoreUrls()){
117 String papID = papUrls.getUserId();
118 String papPass = papUrls.getPass();
119 Base64.Encoder encoder = Base64.getEncoder();
120 String encoding = encoder.encodeToString((papID+":"+papPass).getBytes(StandardCharsets.UTF_8));
121 HttpURLConnection connection = null;
123 // get a new transaction (request) ID and update the logging context.
124 // each time through the outer loop is considered a new transaction.
125 // each time through the inner loop (which handles redirects) is a
126 // continuation of the same transaction.
127 UUID requestID = UUID.randomUUID();
128 loggingContext.setRequestID(requestID.toString());
129 //PolicyLogger.info("Request Id generated in XACMLPdpRegisterThread under XACML-PDP-REST");
130 loggingContext.transactionStarted();
132 // Get the list of PAP Servlet URLs from the property file
134 //String papUrlList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
135 //String[] papUrls = papUrlList.split(",");
136 //PapUrlResolver.setPapUrls(papUrls);
137 URL url = new URL(papUrls.getUrl());
138 logger.info("Registering with " + url.toString());
139 //PolicyLogger.info("new transaction (request) ID and update to logging context in XACMLPdpRegisterThread");
140 boolean finished = false;
143 // Open up the connection
145 connection = (HttpURLConnection)url.openConnection();
147 // Setup our method and headers
149 connection.setRequestMethod("POST");
150 connection.setRequestProperty("Authorization", "Basic " + encoding);
151 connection.setRequestProperty("Accept", "text/x-java-properties");
152 connection.setRequestProperty("Content-Type", "text/x-java-properties");
153 connection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID));
154 connection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_JMX_PORT, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_JMX_PORT));
155 connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
156 connection.setUseCaches(false);
158 // Adding this in. It seems the HttpUrlConnection class does NOT
159 // properly forward our headers for POST re-direction. It does so
160 // for a GET re-direction.
162 // So we need to handle this ourselves.
164 connection.setInstanceFollowRedirects(false);
165 connection.setDoOutput(true);
166 connection.setDoInput(true);
169 // Send our current policy configuration
171 String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + tempRootPoliciesProperty;
172 lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + tempReferencedPoliciesProperty + "\n";
173 try (InputStream listsInputStream = new ByteArrayInputStream(lists.getBytes());
174 OutputStream os = connection.getOutputStream()) {
175 IOUtils.copy(listsInputStream, os);
178 // Send our current PIP configuration
180 //IOUtils.copy(pipInputStream, os);
181 tempPipConfigProperties.store(os, "");
183 } catch (Exception e) {
184 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"Failed to send property file", e);
185 // TODO:EELF Cleanup - Remove logger
186 //PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to send property file");
191 connection.connect();
192 if (connection.getResponseCode() == 204) {
193 logger.info("Success. We are configured correctly.");
194 // TODO:EELF Cleanup - Remove logger
195 //PolicyLogger.info("Success. We are configured correctly.");
196 loggingContext.transactionEnded();
197 // auditLogger.info("Success. We are configured correctly.");
198 // TODO:EELF Cleanup - Remove logger
199 PolicyLogger.audit("Success. We are configured correctly.");
200 papUrls.registered();
203 } else if (connection.getResponseCode() == 200) {
204 logger.info("Success. We have a new configuration.");
205 // TODO:EELF Cleanup - Remove logger
206 //PolicyLogger.info("Success. We have a new configuration.");
207 loggingContext.transactionEnded();
208 // TODO:EELF Cleanup - Remove logger
209 //auditLogger.info("Success. We have a new configuration.");
210 PolicyLogger.audit("Success. We have a new configuration.");
211 papUrls.registered();
212 Properties properties = new Properties();
213 properties.load(connection.getInputStream());
214 logger.info("New properties: " + properties.toString());
218 // The incoming properties does NOT include urls
219 //FIXME: problem here is that we need the properties to be filled in BEFORE this thread continues and registers with another pap
220 Properties returnedPolicyProperties = XACMLProperties.getPolicyProperties(properties, false);
221 tempRootPoliciesProperty = new String(returnedPolicyProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES));
222 tempReferencedPoliciesProperty = new String(returnedPolicyProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES));
223 Properties returnedPipProperties = XACMLProperties.getPipProperties(properties);
224 Properties threadSafeReturnedPipProperties = new Properties();
225 ByteArrayOutputStream threadSafeReturnedPipPropertiesOs = new ByteArrayOutputStream();
226 returnedPipProperties.store(threadSafeReturnedPipPropertiesOs, "");
227 InputStream threadSafeReturnedPipPropertiesIs = new ByteArrayInputStream(threadSafeReturnedPipPropertiesOs.toByteArray());
228 threadSafeReturnedPipProperties.load(threadSafeReturnedPipPropertiesIs);
229 tempPipConfigProperties = threadSafeReturnedPipProperties;
230 //FIXME: how will pipproperties respond to threading?
232 PutRequest req = new PutRequest(returnedPolicyProperties,returnedPipProperties);
233 XACMLPdpServlet.queue.offer(req);
235 // We are now registered
239 } else if (connection.getResponseCode() >= 300 && connection.getResponseCode() <= 399) {
243 String newLocation = connection.getHeaderField("Location");
244 if (newLocation == null || newLocation.isEmpty()) {
245 logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"Did not receive a valid re-direction location");
246 // TODO:EELF Cleanup - Remove logger
247 //PolicyLogger.warn(MessageCodes.ERROR_SYSTEM_ERROR, "Did not receive a valid re-direction location");
248 loggingContext.transactionEnded();
249 auditLogger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"Did not receive a valid re-direction location");
250 // TODO:EELF Cleanup - Remove logger
251 PolicyLogger.audit("Transaction Failed - See Error.log");
254 //FIXME: how to handle this
255 logger.info("New Location: " + newLocation);
256 // TODO:EELF Cleanup - Remove logger
257 //PolicyLogger.info("New Location: " + newLocation);
258 url = new URL(newLocation);
261 logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
262 // TODO:EELF Cleanup - Remove logger
263 //PolicyLogger.warn(MessageCodes.ERROR_SYSTEM_ERROR, "Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
264 loggingContext.transactionEnded();
265 auditLogger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
266 // TODO:EELF Cleanup - Remove logger
267 PolicyLogger.audit("Transaction Failed - See Error.log");
272 } catch (Exception e) {
273 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
274 // TODO:EELF Cleanup - Remove logger
275 //PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
276 PolicyLogger.audit("Transaction Failed - See Error.log");
277 loggingContext.transactionEnded();
278 // TODO:EELF look at this error going to audit. decide what to do.
279 //auditLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
280 // TODO:EELF Cleanup - Remove logger
283 // cleanup the connection
284 if (connection != null) {
286 // For some reason trying to get the inputStream from the connection
287 // throws an exception rather than returning null when the InputStream does not exist.
288 InputStream is = null;
290 is = connection.getInputStream();
291 } catch (Exception e1) {
298 } catch (IOException ex) {
299 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to close connection: " + ex, ex);
300 // TODO:EELF Cleanup - Remove logger
301 //PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, ex, "Failed to close connection");
303 connection.disconnect();
307 // Wait a little while to try again
311 if (registered == false) {
314 } else if (retries == 0) {
317 Thread.sleep(seconds * 1000);
319 } catch (InterruptedException e) {
324 //end of hasMoreUrls while loop
328 this.isRunning = false;
330 logger.info("Thread exiting...(registered=" + registered + ", interrupted=" + interrupted + ", isRunning=" + this.isRunning() + ", retries=" + "0" + ")");