aboutsummaryrefslogtreecommitdiffstats
path: root/ECOMP-REST/src/main/java/org/openecomp/policy/rest/XACMLRest.java
blob: 7e535cbcfb22f45b7851ee57c1b1c42fb61d6f82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*-
 * ============LICENSE_START=======================================================
 * ECOMP-REST
 * ================================================================================
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============LICENSE_END=========================================================
 */

package org.openecomp.policy.rest;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openecomp.policy.common.logging.eelf.MessageCodes;
import org.openecomp.policy.common.logging.eelf.PolicyLogger;

import org.openecomp.policy.xacml.api.XACMLErrorConstants;
import com.att.research.xacml.util.XACMLProperties;


/**
 * This static class is used by both the PDP and PAP servlet's. It contains some common
 * static functions and objects used by both the servlet's.
 * 
 *
 */
public class XACMLRest {
	private static final Log logger	= LogFactory.getLog(XACMLRest.class);
	private static Properties restProperties = new Properties();
	
	/**
	 * This must be called during servlet initialization. It sets up the xacml.?.properties
	 * file as a system property. If the System property is already set, then it does not
	 * do anything. This allows the developer to specify their own xacml.properties file to be
	 * used. They can 1) modify the default properties that comes with the project, or 2) change
	 * the WebInitParam annotation, or 3) specify an alternative path in the web.xml, or 4) set
	 * the Java System property to point to their xacml.properties file.
	 * 
	 * The recommended way of overriding the default xacml.properties file is using a Java System
	 * property:
	 * 
	 * -Dxacml.properties=/opt/app/xacml/etc/xacml.admin.properties
	 * 
	 * This way one does not change any actual code or files in the project and can leave the 
	 * defaults alone.
	 * 
	 * @param config - The servlet config file passed from the javax servlet init() function
	 */
	public static void xacmlInit(ServletConfig config) {
		//
		// Get the XACML Properties File parameter first
		//
		String propFile = config.getInitParameter("XACML_PROPERTIES_NAME");
		if (propFile != null) {
			//
			// Look for system override
			//
			String xacmlPropertiesName = System.getProperty(XACMLProperties.XACML_PROPERTIES_NAME);
			if (xacmlPropertiesName == null) {
				//
				// Set it to our servlet default
				//
				if (logger.isDebugEnabled()) {
					logger.debug("Using Servlet Config Property for XACML_PROPERTIES_NAME:" + propFile);
				}
				System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, propFile);
			} else {
				if (logger.isDebugEnabled()) {
					logger.debug("Using System Property for XACML_PROPERTIES_NAME:" + xacmlPropertiesName);
				}
			}
		}
		//
		// Setup the remaining properties
		//
		Enumeration<String> params = config.getInitParameterNames();
		while (params.hasMoreElements()) {
			String param = params.nextElement();
			if (! param.equals("XACML_PROPERTIES_NAME")) {
				String value = config.getInitParameter(param);
				//logger.info(param + "=" + config.getInitParameter(param));
				PolicyLogger.info(param + "=" + config.getInitParameter(param));
				restProperties.setProperty(param, value);
			}
		}
	}
	
	/**
	 * Reset's the XACMLProperties internal properties object so we start
	 * in a fresh environment. Then adds back in our Servlet init properties that were
	 * passed in the javax Servlet init() call.
	 * 
	 * This function is primarily used when a new configuration is passed in and the
	 * PDP servlet needs to load a new PDP engine instance.
	 * 
	 * @param pipProperties - PIP configuration properties
	 * @param policyProperties  - Policy configuration properties
	 */
	public static void loadXacmlProperties(Properties policyProperties, Properties pipProperties) {
		try {
			//
			// Start fresh
			//
			XACMLProperties.reloadProperties();
			//
			// Now load our init properties
			//
			XACMLProperties.getProperties().putAll(XACMLRest.restProperties);
			//
			// Load our policy properties
			//
			if (policyProperties != null) {
				XACMLProperties.getProperties().putAll(policyProperties);
			}
			//
			// Load our pip config properties
			//
			if (pipProperties != null) {
				XACMLProperties.getProperties().putAll(pipProperties);
			}
		} catch (IOException e) {
			//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to put init properties into Xacml properties", e);
			// TODO:EELF Cleanup - Remove logger
			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Failed to put init properties into Xacml properties");
		}
		//
		// Dump them
		//
		if (logger.isDebugEnabled()) {
			try {
				logger.debug(XACMLProperties.getProperties().toString());				
			} catch (IOException e) {
				//logger.error( XACMLErrorConstants.ERROR_PROCESS_FLOW + "Cannot dump properties", e);
				// TODO:EELF Cleanup - Remove logger
				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Cannot dump properties");
			}
		}
	}
	
	/**
	 * Helper routine to dump the HTTP servlet request being serviced. Primarily for debugging.
	 * 
	 * @param request - Servlet request (from a POST/GET/PUT/etc.)
	 */
	public static void dumpRequest(HttpServletRequest request) {
		if (logger.isDebugEnabled()) {
			// special-case for receiving heartbeat - don't need to repeatedly output all of the information in multiple lines
			if (request.getMethod().equals("GET") && "hb".equals(request.getParameter("type"))  ) {
				//logger.debug("GET type=hb : heartbeat received");
				PolicyLogger.debug("GET type=hb : heartbeat received");
				return;				
			}
			logger.debug(request.getMethod() + ":" + request.getRemoteAddr() + " " + request.getRemoteHost() + " " + request.getRemotePort());
			logger.debug(request.getLocalAddr() + " " + request.getLocalName() + " " + request.getLocalPort());
			Enumeration<String> en = request.getHeaderNames();
			logger.debug("Headers:");
			while (en.hasMoreElements()) {
				String element = en.nextElement();
				Enumeration<String> values = request.getHeaders(element);
				while (values.hasMoreElements()) {
					String value = values.nextElement();
					logger.debug(element + ":" + value);
				}
			}
			logger.debug("Attributes:");
			en = request.getAttributeNames();
			while (en.hasMoreElements()) {
				String element = en.nextElement();
				logger.debug(element + ":" + request.getAttribute(element));
			}
			logger.debug("ContextPath: " + request.getContextPath());
			if (request.getMethod().equals("PUT") || request.getMethod().equals("POST")) {
				// POST and PUT are allowed to have parameters in the content, but in our usage the parameters are always in the Query string.
				// More importantly, there are cases where the POST and PUT content is NOT parameters (e.g. it might contain a Policy file).
				// Unfortunately the request.getParameterMap method reads the content to see if there are any parameters,
				// and once the content is read it cannot be read again.
				// Thus for PUT and POST we must avoid reading the content here so that the main code can read it.
				logger.debug("Query String:" + request.getQueryString());
				try {
					if (request.getInputStream() == null) {
						logger.debug("Content: No content inputStream");
					} else {
						logger.debug("Content available: " + request.getInputStream().available());
					}
				} catch (Exception e) {
					logger.debug("Content: inputStream exception: " + e.getMessage() + ";  (May not be relevant)");
				}
			} else {
				logger.debug("Parameters:");
				Map<String, String[]> params = request.getParameterMap();
				Set<String> keys = params.keySet();
				for (String key : keys) {
					String[] values = params.get(key);
					logger.debug(key + "(" + values.length + "): " + (values.length > 0 ? values[0] : ""));
				}
			}
			logger.debug("Request URL:" + request.getRequestURL());
		}
	}
}