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