Policy 1707 commit to LF
[policy/engine.git] / ECOMP-PDP / src / main / java / org / openecomp / policy / xacml / action / FindAction.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-PDP
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
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 package org.openecomp.policy.xacml.action;
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.net.URL;
26 import java.net.URLConnection;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34 import javax.json.Json;
35 import javax.json.JsonReader;
36
37 import org.apache.http.HttpResponse;
38 import org.apache.http.client.ClientProtocolException;
39 import org.apache.http.client.methods.HttpGet;
40 import org.apache.http.client.methods.HttpPost;
41 import org.apache.http.client.methods.HttpPut;
42 import org.apache.http.entity.StringEntity;
43 import org.apache.http.impl.client.DefaultHttpClient;
44 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
45 import org.openecomp.policy.common.logging.flexlogger.Logger;
46 import org.openecomp.policy.rest.XACMLRestProperties;
47
48 import com.att.research.xacml.api.Advice;
49 import com.att.research.xacml.api.Attribute;
50 import com.att.research.xacml.api.AttributeAssignment;
51 import com.att.research.xacml.api.AttributeValue;
52 import com.att.research.xacml.api.Identifier;
53 import com.att.research.xacml.api.Obligation;
54 import com.att.research.xacml.api.Request;
55 import com.att.research.xacml.api.RequestAttributes;
56 import com.att.research.xacml.api.Result;
57 import com.att.research.xacml.std.IdentifierImpl;
58 import com.att.research.xacml.std.StdAdvice;
59 import com.att.research.xacml.std.StdAttributeAssignment;
60 import com.att.research.xacml.std.StdAttributeValue;
61 import com.att.research.xacml.std.StdMutableResponse;
62 import com.att.research.xacml.std.StdMutableResult;
63 import com.att.research.xacml.std.StdObligation;
64 import com.att.research.xacml.util.XACMLProperties;
65
66 public class FindAction {
67         private Logger LOGGER = FlexLogger.getLogger(this.getClass());
68         private Boolean changeIt = false;
69         private String configURL = null;
70         private StdMutableResponse newResponse = new StdMutableResponse();
71         private StdMutableResult addResult = new StdMutableResult();
72
73         public StdMutableResponse run(StdMutableResponse stdResponse, Request pepRequest) {
74                 int count = 0;
75                 boolean config = false;
76                 boolean decide = false; 
77                 Collection<RequestAttributes> requestAttributes =  pepRequest.getRequestAttributes();
78                 for(RequestAttributes requestAttribute : requestAttributes){
79                         Collection<Attribute> attributes = requestAttribute.getAttributes();
80                         for(Attribute attribute : attributes){
81                                 if(attribute.getAttributeId().stringValue().equals("urn:oasis:names:tc:xacml:1.0:action:action-id")){
82                                         for(AttributeValue<?> attributeValue : attribute.getValues()){
83                                                 if(attributeValue.getValue().toString().equalsIgnoreCase("ACCESS")){
84                                                         count++;
85                                                 }
86                                                 if(attributeValue.getValue().toString().equalsIgnoreCase("DECIDE")){
87                                                         decide = true;
88                                                 }
89                                         }
90                                 }
91                                 if(attribute.getAttributeId().stringValue().equals("urn:oasis:names:tc:xacml:1.0:resource:resource-id")){
92                                         for(AttributeValue<?> attributeValue : attribute.getValues()){
93                                                 if(attributeValue.getValue().toString().equalsIgnoreCase("Config")){
94                                                         count++;
95                                                 }
96                                         }
97                                 }
98                         }
99                 }
100                 if(count==2){
101                         config = true;
102                 }
103                 if(!config){
104                         search(stdResponse);
105                 }
106                 addResults(stdResponse, config , decide);
107                 LOGGER.info("Original Result is " + stdResponse.toString());
108                 LOGGER.info("Generated Result is " + addResult.toString());
109                 return newResponse;
110         }
111
112         private Collection<Obligation> obligations = new ArrayList<Obligation>();
113         private Map<String, String> matchValues = new HashMap<String, String>();
114         private Map<String, String> headers = new HashMap<String, String>();
115         private boolean header = false;
116
117         private void search(StdMutableResponse stdResponse) {
118                 for (Result result : stdResponse.getResults()) {
119                         if (!result.getObligations().isEmpty()) {
120                                 System.out.println("Obligation Received");
121                                 // Is there any action that PDP needs to take
122                                 for (Obligation obligation : result.getObligations()) {
123                                         int count = 0, uri = 0, PEP = 0;
124                                         header = false;
125                                         changeIt = false;
126                                         Collection<AttributeAssignment> afterRemoveAssignments = new ArrayList<AttributeAssignment>();
127                                         Identifier oblId = new IdentifierImpl(obligation.getId().stringValue());
128                                         StdAttributeAssignment attributeURI = null;
129                                         for (AttributeAssignment attribute : obligation.getAttributeAssignments()) {
130                                                 matchValues.put(attribute.getAttributeId().stringValue(), attribute.getAttributeValue().getValue().toString());
131                                                 if (attribute.getAttributeId().stringValue().equalsIgnoreCase("performer")) {
132                                                         if (attribute.getAttributeValue().getValue().toString().equalsIgnoreCase("PEPACTION")) {
133                                                                 PEP++;
134                                                         } else if (attribute.getAttributeValue().getValue().toString().equalsIgnoreCase("PDPACTION")) {
135                                                                 count++;
136                                                         }
137                                                 } else if (attribute.getAttributeId().stringValue().equalsIgnoreCase("URL")) {
138                                                         uri++;
139                                                         if (uri == 1) {
140                                                                 configURL = attribute.getAttributeValue().getValue().toString();
141                                                                 attributeURI = new StdAttributeAssignment(attribute);
142                                                         }
143                                                 } else if (attribute.getAttributeId().stringValue().startsWith("headers")) {
144                                                         LOGGER.info("Headers are : "+ attribute.getAttributeValue().getValue().toString());
145                                                         header = true;
146                                                         headers.put(attribute.getAttributeId().stringValue().replaceFirst("(headers).", ""),
147                                                                         attribute.getAttributeValue().getValue().toString());
148                                                         afterRemoveAssignments.add(attribute);
149                                                 } else if (attribute.getAttributeId().stringValue().equalsIgnoreCase("body")) { 
150                                                         String papPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
151                                                         papPath= papPath.replace("/pap", "");
152                                                         matchValues.put("body",attribute.getAttributeValue().getValue().toString().replace("$URL", papPath));
153                                                 } /*
154                                                  * else if (attribute.getAttributeId().stringValue().
155                                                  * equalsIgnoreCase("type")){ requestAction.put("Type",
156                                                  * attribute.getAttributeValue().getValue().toString());
157                                                  * afterRemoveAssignments.add(attribute); } else
158                                                  * if(attribute
159                                                  * .getAttributeId().stringValue().equalsIgnoreCase
160                                                  * ("method")) { requestAction.put("Method",
161                                                  * attribute.getAttributeValue().getValue().toString());
162                                                  * afterRemoveAssignments.add(attribute); } else
163                                                  * if(attribute
164                                                  * .getAttributeId().stringValue().equalsIgnoreCase
165                                                  * ("body")) { requestAction.put("Body",
166                                                  * attribute.getAttributeValue().getValue().toString());
167                                                  * afterRemoveAssignments.add(attribute); }
168                                                  */else {
169                                                         StdAttributeAssignment attributeObligation = new StdAttributeAssignment(attribute);
170                                                         afterRemoveAssignments.add(attributeObligation);
171                                                 }
172                                         }
173                                         if (count == 1 && uri == 1 && PEP == 0) {
174                                                 // Remove Obligation and add Advice
175                                                 changeIt = true;
176                                                 TakeAction(stdResponse, oblId, afterRemoveAssignments);
177                                         } else if (PEP == 1 && count == 0) {
178                                                 // Strip the PEPACTION if available
179                                                 if (uri == 1) {
180                                                         afterRemoveAssignments.add(attributeURI);
181                                                 }
182                                                 Obligation afterRemoveObligation = new StdObligation(
183                                                                 oblId, afterRemoveAssignments);
184                                                 obligations.add(afterRemoveObligation);
185                                         } else {
186                                                 obligations.add(obligation);
187                                         }
188                                 }
189                         }
190                 }
191         }
192
193         private void TakeAction(StdMutableResponse stdResponse, Identifier advId,
194                         Collection<AttributeAssignment> afterRemoveAssignments) {
195                 if (changeIt) {
196                         LOGGER.info("the URL is :" + configURL);
197                         // Calling Rest URL..
198                         callRest();
199                         // Including the Results in an Advice
200                         Identifier id = new IdentifierImpl(
201                                         "com:att:labs:ecomp:policy:pdp:reply");
202                         Identifier statId = new IdentifierImpl(
203                                         "com:att:labs:ecomp:policy:pdp:reply:status");
204                         Identifier statCategory = new IdentifierImpl(
205                                         "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject");
206                         Identifier strId = new IdentifierImpl(
207                                         "http://www.w3.org/2001/XMLSchema#string");
208                         Identifier resId = new IdentifierImpl(
209                                         "com:att:labs:ecomp:policy:pdp:reply:resource");
210                         Identifier resCategory = new IdentifierImpl(
211                                         "urn:oasis:names:tc:xacml:3.0:attribute-category:resource");
212                         Identifier urlId = new IdentifierImpl(
213                                         "http://www.w3.org/2001/XMLSchema#anyURI");
214                         // Collection<AttributeAssignment> attributes = new
215                         // ArrayList<AttributeAssignment>();
216                         AttributeValue<String> attributeStatusValue = new StdAttributeValue<String>(
217                                         strId, status + response);
218                         AttributeValue<String> attributeResourceValue = new StdAttributeValue<String>(
219                                         urlId, configURL);
220                         StdAttributeAssignment attributeStatus = new StdAttributeAssignment(
221                                         statCategory, statId, "PDP", attributeStatusValue);
222                         StdAttributeAssignment attributeResouce = new StdAttributeAssignment(
223                                         resCategory, resId, "PDP", attributeResourceValue);
224                         afterRemoveAssignments.add(attributeStatus);
225                         afterRemoveAssignments.add(attributeResouce);
226                         Advice advice = new StdAdvice(id, afterRemoveAssignments);
227                         addResult.addAdvice(advice);
228                 }
229         }
230
231         private void addResults(StdMutableResponse stdResponse, boolean config, boolean decide) {
232                 if(decide){
233                         newResponse = stdResponse;
234                         return;
235                 }
236                 for (Result result : stdResponse.getResults()) {
237                         if(config){
238                                 addResult.addAdvice(result.getAssociatedAdvice());
239                         }
240                         addResult.addAttributeCategories(result.getAttributes());
241                         addResult.addPolicyIdentifiers(result.getPolicyIdentifiers());
242                         addResult.addPolicySetIdentifiers(result.getPolicySetIdentifiers());
243                         addResult.setStatus(result.getStatus());
244                         addResult.setDecision(result.getDecision());
245                         if(!config){
246                                 addResult.addObligations(obligations);
247                         }
248                 }
249                 newResponse.add(addResult);
250         }
251
252         private int status;
253         private String response;
254         private DefaultHttpClient httpClient;
255
256         private void callRest() {
257                 // Finding the Macros in the URL..
258                 Pattern pattern = Pattern.compile("\\$([a-zA-Z0-9.:]*)");
259                 Matcher match = pattern.matcher(configURL);
260                 StringBuffer sb = new StringBuffer();
261                 while (match.find()) {
262                         LOGGER.info("Found Macro : " + match.group(1));
263                         String replaceValue = matchValues.get(match.group(1));
264                         LOGGER.info("Replacing with :" + replaceValue);
265                         match.appendReplacement(sb, replaceValue);
266                 }
267                 match.appendTail(sb);
268                 LOGGER.info("URL is : " + sb.toString());
269                 configURL = sb.toString();
270                 // Calling the Requested service. 
271                 if (matchValues.get("method").equalsIgnoreCase("GET")) {
272                         httpClient = new DefaultHttpClient();
273                         try {
274                                 HttpGet getRequest = new HttpGet(configURL);
275                                 // Adding Headers here
276                                 if (header) {
277                                         for (String key : headers.keySet()) {
278                                                 getRequest.addHeader(key, headers.get(key));
279                                         }
280                                 }
281                                 HttpResponse result = httpClient.execute(getRequest);
282                                 status = result.getStatusLine().getStatusCode();
283                                 BufferedReader br = new BufferedReader(new InputStreamReader(
284                                                 (result.getEntity().getContent())));
285                                 String output = " ";
286                                 String out;
287                                 while ((out = br.readLine()) != null) {
288                                         output = output + out;
289                                 }
290                                 response = output;
291                         } catch (ClientProtocolException e) {
292                                 LOGGER.error(e.getMessage());
293                                 response = e.getMessage();
294                         } catch (IOException e) {
295                                 LOGGER.error(e.getMessage());
296                                 response = e.getMessage();
297                         } finally {
298                                 httpClient.getConnectionManager().shutdown();
299                         }
300                 } else if(matchValues.get("method").equalsIgnoreCase("POST")) {
301                         httpClient = new DefaultHttpClient();
302                         try {
303                                 HttpPost postRequest = new HttpPost(configURL);
304                                 // Adding Headers here
305                                 if (header) {
306                                         for (String key : headers.keySet()) {
307                                                 postRequest.addHeader(key, headers.get(key));
308                                         }
309                                 }
310                                 // Adding the Body. 
311                                 URL configURL = new URL(matchValues.get("body"));
312                                 URLConnection connection = null;
313                                 connection = configURL.openConnection();
314                                 // InputStream in = connection.getInputStrem();
315                                 // LOGGER.info("The Body Content is : " + IOUtils.toString(in));
316                                 JsonReader jsonReader = Json.createReader(connection.getInputStream());
317                                 StringEntity input = new StringEntity(jsonReader.readObject().toString());
318                                 input.setContentType("application/json");
319                                 postRequest.setEntity(input);
320                                 // Executing the Request. 
321                                 HttpResponse result = httpClient.execute(postRequest);
322                                 LOGGER.info("Result Headers are : " + result.getAllHeaders());
323                                 status = result.getStatusLine().getStatusCode();
324                                 BufferedReader br = new BufferedReader(new InputStreamReader(
325                                                 (result.getEntity().getContent())));
326                                 String output = " ";
327                                 String out;
328                                 while ((out = br.readLine()) != null) {
329                                         output = output + out;
330                                 }
331                                 response = output;
332                         } catch (ClientProtocolException e) {
333                                 LOGGER.error(e.getMessage());
334                                 response = e.getMessage();
335                         } catch (IOException e) {
336                                 LOGGER.error(e.getMessage());
337                                 response = e.getMessage();
338                         } finally {
339                                 httpClient.getConnectionManager().shutdown();
340                         }
341                 } else if(matchValues.get("method").equalsIgnoreCase("PUT")) {
342                         httpClient = new DefaultHttpClient();
343                         try {
344                                 HttpPut putRequest = new HttpPut(configURL);
345                                 // Adding Headers here
346                                 if (header) {
347                                         for (String key : headers.keySet()) {
348                                                 putRequest.addHeader(key, headers.get(key));
349                                         }
350                                 }
351                                 // Adding the Body. 
352                                 URL configURL = new URL(matchValues.get("body"));
353                                 URLConnection connection = null;
354                                 connection = configURL.openConnection();
355                                 //InputStream in = connection.getInputStream();
356                                 //LOGGER.info("The Body Content is : " + IOUtils.toString(in));
357                                 JsonReader jsonReader = Json.createReader(connection.getInputStream());
358                                 StringEntity input = new StringEntity(jsonReader.readObject().toString());
359                                 input.setContentType("application/json");
360                                 putRequest.setEntity(input);
361                                 // Executing the Request. 
362                                 HttpResponse result = httpClient.execute(putRequest);
363                                 status = result.getStatusLine().getStatusCode();
364                                 BufferedReader br = new BufferedReader(new InputStreamReader(
365                                                 (result.getEntity().getContent())));
366                                 String output = " ";
367                                 String out;
368                                 while ((out = br.readLine()) != null) {
369                                         output = output + out;
370                                 }
371                                 response = output;
372                         } catch (ClientProtocolException e) {
373                                 LOGGER.error(e.getMessage());
374                                 response = e.getMessage();
375                         } catch (IOException e) {
376                                 LOGGER.error(e.getMessage());
377                                 response = e.getMessage();
378                         } finally {
379                                 httpClient.getConnectionManager().shutdown();
380                         }
381                 }
382         }
383 }