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