Implement restful call to xacml pdp guard 57/13557/10
authorTemoc Rodriguez <cr056n@att.com>
Tue, 19 Sep 2017 18:13:34 +0000 (11:13 -0700)
committerAli Hockla <ah999m@att.com>
Thu, 21 Sep 2017 14:59:48 +0000 (14:59 +0000)
Removed the embedded guard decision and replace with restful call to
xacml pdp to restore guard functionality. Set guard URL with PolicyEngine env properties. Modified templates accordingly.

Issue-Id: POLICY-260
Change-Id: Ic1558a6ebdd5f6d1b74a748f69433f6213dbf984
Signed-off-by: Temoc Rodriguez <cr056n@att.com>
Signed-off-by: Hockla, Ali (ah999m) <ah999m@att.com>
controlloop/common/guard/pom.xml
controlloop/common/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java
controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java
controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl
controlloop/templates/template.demo/pom.xml
controlloop/templates/template.demo/src/main/resources/ControlLoop_Template_xacml_guard.drl
controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/ControlLoopXacmlGuardTest.java
controlloop/templates/template.demo/src/test/resources/META-INF/persistence.xml

index e028358..0fe442e 100644 (file)
             <version>2.7.0</version>
                        <scope>provided</scope>
         </dependency>
+        <dependency>
+               <groupId>org.onap.policy.drools-pdp</groupId>
+               <artifactId>policy-management</artifactId>
+               <version>1.1.0-SNAPSHOT</version>
+               <scope>provided</scope>
+        </dependency>
   </dependencies>
 </project>
index 6b311bf..8ea4ec1 100644 (file)
 
 package org.onap.policy.guard;
 
-import com.att.research.xacml.api.DataTypeException;
-import com.att.research.xacml.api.pdp.PDPEngine;
-import com.att.research.xacml.std.annotations.RequestParser;
-
 import java.util.UUID;
 
 import org.drools.core.WorkingMemory;
+import org.onap.policy.drools.system.PolicyEngine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.std.annotations.RequestParser;
+
 
 public class CallGuardTask implements Runnable {
        
        private static final Logger logger = LoggerFactory.getLogger(CallGuardTask.class);
        WorkingMemory workingMemory;
-       PDPEngine embeddedPdpEngine;
        String restfulPdpUrl;
        String clname;
        String actor;
@@ -43,10 +42,9 @@ public class CallGuardTask implements Runnable {
        String target;
        String requestId;
        
-    public CallGuardTask(PDPEngine engine, String url, WorkingMemory wm, String cl, String act, String rec, String tar, String reqId) { 
+    public CallGuardTask(String guardUrl, WorkingMemory wm, String cl, String act, String rec, String tar, String reqId) { 
     
-       embeddedPdpEngine = engine; 
-       restfulPdpUrl = url;
+       restfulPdpUrl = guardUrl;
        workingMemory = wm;
        clname = cl;
        actor = act;
@@ -71,13 +69,30 @@ public class CallGuardTask implements Runnable {
                logger.debug("{}", request);
                logger.debug("********** XACML REQUEST END ********\n");
                
-               com.att.research.xacml.api.Response xacmlResponse = PolicyGuardXacmlHelper.callPDP(embeddedPdpEngine, "", request, false);
+               String guardUrl = PolicyEngine.manager.getEnvironmentProperty("guard.url");
+               String guardDecision = null;
                
+               //
+               // Check if guard url property exists
+               //
+               if(guardUrl != null){
+                       guardDecision = PolicyGuardXacmlHelper.callPDP(guardUrl, xacmlReq);
+               }
+
                logger.debug("\n********** XACML RESPONSE START ********");
-               logger.debug("{}", xacmlResponse);
+               logger.debug("{}", guardDecision);
                logger.debug("********** XACML RESPONSE END ********\n");
-                                               
-               PolicyGuardResponse guardResponse = PolicyGuardXacmlHelper.ParseXacmlPdpResponse(xacmlResponse);
+
+               //
+               // Check if the restful call was unsuccessful or property doesn't exist
+               //
+               if(guardDecision == null){
+                       logger.error("********** XACML FAILED TO CONNECT ********");
+                       guardDecision = "Indeterminate";
+               }
+
+               PolicyGuardResponse guardResponse = new PolicyGuardResponse(guardDecision, UUID.fromString(this.requestId), this.recipe);
+
                
                //
                //Create an artificial Guard response in case we didn't get a clear Permit or Deny
index 5ecb441..72c498d 100644 (file)
 
 package org.onap.policy.guard;
 
+import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -30,6 +32,7 @@ import java.util.UUID;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.http.entity.ContentType;
+import org.json.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -37,45 +40,40 @@ import com.att.research.xacml.api.Attribute;
 import com.att.research.xacml.api.AttributeCategory;
 import com.att.research.xacml.api.AttributeValue;
 import com.att.research.xacml.api.Result;
-import com.att.research.xacml.api.pdp.PDPEngine;
-import com.att.research.xacml.api.pdp.PDPException;
-import com.att.research.xacml.std.dom.DOMResponse;
-import com.att.research.xacml.std.json.JSONRequest;
-import com.att.research.xacml.std.json.JSONResponse;
 
 
 public class PolicyGuardXacmlHelper {
        
        private static final Logger logger = LoggerFactory.getLogger(PolicyGuardXacmlHelper.class);
 
-       public static com.att.research.xacml.api.Response callPDP(PDPEngine xacmlEmbeddedPdpEngine, String restfulPdpUrl, com.att.research.xacml.api.Request request, boolean isREST) {
+       public static String callPDP(String restfulPdpUrl, PolicyGuardXacmlRequestAttributes xacmlReq) {
                //
                // Send it to the PDP
                //
-               com.att.research.xacml.api.Response response = null;
-               if (isREST) {
-                       try {
-                               String jsonString = JSONRequest.toString((com.att.research.xacml.api.Request) request, false);
-                               //
-                               // Call RESTful PDP
-                               //
-                               response = (com.att.research.xacml.api.Response) callRESTfulPDP(new ByteArrayInputStream(jsonString.getBytes()), new URL(restfulPdpUrl/*"https://localhost:8443/pdp/"*/));
-                       } catch (Exception e) {
-                               logger.error("Error in sending RESTful request: ", e);
-                       }
-               } else if(xacmlEmbeddedPdpEngine != null){
+//             com.att.research.xacml.api.Response response = null;
+               String response = null;
+               
+               JSONObject attributes = new JSONObject();
+               attributes.put("actor", xacmlReq.getActor_id());
+               attributes.put("recipe", xacmlReq.getOperation_id());
+               attributes.put("target", xacmlReq.getTarget_id());
+               if (xacmlReq.getClname_id() != null){
+                       attributes.put("clname", xacmlReq.getClname_id());
+               }
+               JSONObject jsonReq = new JSONObject();
+               jsonReq.put("decisionAttributes", attributes);
+               jsonReq.put("onapName", "PDPD");
+               
+               try {
                        //
-                       // Embedded call to PDP
+                       // Call RESTful PDP
                        //
-                       long lTimeStart = System.currentTimeMillis();
-                       try {
-                               response = (com.att.research.xacml.api.Response) xacmlEmbeddedPdpEngine.decide((com.att.research.xacml.api.Request) request);
-                       } catch (PDPException e) {
-                               logger.error(e.getMessage(), e);
-                       }
-                       long lTimeEnd = System.currentTimeMillis();
-                       logger.debug("Elapsed Time: {} ms", (lTimeEnd - lTimeStart));
+                       response = callRESTfulPDP(new ByteArrayInputStream(jsonReq.toString().getBytes()), new URL(restfulPdpUrl/*"https://localhost:8443/pdp/"*/));
+               } catch (Exception e) {
+                       logger.error("Error in sending RESTful request: ", e);
                }
+               
+               
                return response;
        }
        
@@ -84,10 +82,12 @@ public class PolicyGuardXacmlHelper {
         * This makes an HTTP POST call to a running PDP RESTful servlet to get a decision.
         * 
         * @param file
-        * @return
+        * @return response from guard which contains "Permit" or "Deny"
         */
-       private static com.att.research.xacml.api.Response callRESTfulPDP(InputStream is, URL restURL) {
-               com.att.research.xacml.api.Response response = null;
+       private static String callRESTfulPDP(InputStream is, URL restURL) {
+//             com.att.research.xacml.api.Response response = null;
+               String response = null;
+               String rawDecision = null;
                HttpURLConnection connection = null;
                try {
 
@@ -130,28 +130,59 @@ public class PolicyGuardXacmlHelper {
                                contentType = ContentType.parse(connection.getContentType());
                                
                                if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
-                               response = (com.att.research.xacml.api.Response) JSONResponse.load(connection.getInputStream());
-                               } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
-                                               contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) {
-                               response = (com.att.research.xacml.api.Response) DOMResponse.load(connection.getInputStream());
+                                         InputStream iStream = connection.getInputStream();
+                                         int contentLength = connection.getContentLength();
+
+                                         // if content length is -1, respose is chunked, and
+                                         // TCP connection will be dropped at the end
+                                         byte[] buf =
+                                               new byte[contentLength < 0 ? 1024 : contentLength];
+                                         int offset = 0;
+                                         for ( ; ; )
+                                               {
+                                                 if (offset == contentLength)
+                                                       {
+                                                         // all expected bytes have been read
+                                                         response = new String(buf);
+                                                         break;
+                                                       }
+                                                 int size = iStream.read(buf, offset,
+                                                                                        buf.length - offset);
+                                                 if (size < 0)
+                                                       {
+                                                         if (contentLength > 0)
+                                                               {
+                                                                 logger.error("partial input stream");
+                                                               }
+                                                         else
+                                                               {
+                                                                 // chunked response --
+                                                                 // dropped connection is expected
+                                                                 response = new String(buf, 0, offset);
+                                                               }
+                                                         break;
+                                                       }
+                                                 offset += size;
+                                               }
                                } else {
-                                       logger.error("{}: unknown content-type: ", contentType);
+                                       logger.error("unknown content-type: " + contentType);
                        }
 
                 } catch (Exception e) {
-                               String message = "Parsing Content-Type: " + connection.getContentType() + ", error=" + e.getMessage();
-                               logger.error("{}: callRESTfulPDP threw: ", message, e);
+                                       String message = "Parsing Content-Type: " + connection.getContentType();
+                                       logger.error(message, e);
                        }
 
             } else {
-               logger.error("unknown content-type: {} {}", connection.getResponseCode(), connection.getResponseMessage() );
+               logger.error(connection.getResponseCode() + " " + connection.getResponseMessage());
             }
                } catch (Exception e) {
-                       
-                       logger.error("callRESTfulPDP threw: ", e);
+                       logger.error("Exception in 'PolicyGuardXacmlHelper.callRESTfulPDP'", e);
                }
+
+               rawDecision = new JSONObject(response).getString("decision");
                
-               return response;
+               return rawDecision;
        }
        
        
@@ -191,9 +222,6 @@ public class PolicyGuardXacmlHelper {
                }
                
                
-               
-               
-               
                return new PolicyGuardResponse(decision_from_xacml_response, req_id_from_xacml_response, operation_from_xacml_response);
                
        }
index 5e90f05..a2939a0 100644 (file)
@@ -627,7 +627,6 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
     if(guardEnabled){
     
         Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
-                                                        null, 
                                                         PolicyEngine.manager.getEnvironmentProperty("guard.url"), 
                                                         drools.getWorkingMemory(),
                                                         $event.closedLoopControlName,
@@ -667,7 +666,7 @@ rule "${policyName}.GUARD.RESPONSE"
         
         
     //we will permit the operation if there was no Guard for it
-    if($guardResponse.result == "Indeterminate"){
+    if("Indeterminate".equals($guardResponse.result)){
         $guardResponse.result = "Permit";
     }
     
@@ -685,7 +684,7 @@ rule "${policyName}.GUARD.RESPONSE"
     
     PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
     
-    if($guardResponse.result == "Permit"){
+    if("Permit".equals($guardResponse.result)){
     
         modify($operation){setGuardApprovalStatus($guardResponse.result)};
     }
index d3d3ef0..69c2da8 100644 (file)
                        <version>${project.version}</version>
                        <scope>test</scope>
                </dependency>
+               <dependency>
+               <groupId>org.onap.policy.drools-pdp</groupId>
+               <artifactId>policy-management</artifactId>
+               <version>1.1.0-SNAPSHOT</version>
+               <scope>provided</scope>
+        </dependency>
        </dependencies>
 </project>
index 82899f0..ff184b3 100644 (file)
@@ -589,7 +589,6 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
                if(guardEnabled){
                
                        Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
-                                                                                                               XacmlPdpEngine, 
                                                                                                                "", 
                                                                                                                drools.getWorkingMemory(),
                                                                                                                $event.closedLoopControlName,
@@ -636,7 +635,7 @@ rule "${policyName}.GUARD.RESPONSE"
                
                
                //we will permit the operation if there was no Guard for it
-               if($guardResponse.result == "Indeterminate"){
+               if("Indeterminate".equals($guardResponse.result)){
                        $guardResponse.result = "Permit";
                }
                
@@ -655,7 +654,7 @@ rule "${policyName}.GUARD.RESPONSE"
                
                
                
-               if($guardResponse.result == "Permit"){
+               if("Permit".equals($guardResponse.result)){
                
                        modify($operation){setGuardApprovalStatus($guardResponse.result)};
                }
index 64ad490..5fe2f62 100644 (file)
@@ -47,6 +47,7 @@ import org.onap.policy.controlloop.VirtualControlLoopEvent;
 import org.onap.policy.controlloop.VirtualControlLoopNotification;
 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
 import org.onap.policy.controlloop.policy.TargetType;
+import org.onap.policy.drools.system.PolicyEngine;
 import org.onap.policy.drools.http.server.HttpServletServer;
 import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
 import org.onap.policy.guard.PolicyGuard;
@@ -75,6 +76,7 @@ public class ControlLoopXacmlGuardTest {
        @BeforeClass
        public static void setPUProp(){
                System.setProperty(OPSHISTPUPROP, "TestOperationsHistoryPU");
+               PolicyEngine.manager.setEnvironmentProperty("guard.url", "http://127.0.0.1:8443/pdp");
        }
        @AfterClass
        public static void restorePUProp(){
@@ -171,7 +173,7 @@ public class ControlLoopXacmlGuardTest {
                                        assertTrue(obj instanceof VirtualControlLoopNotification);
                                        assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
 
-                                       Thread.sleep(4000);
+                                       Thread.sleep(2*4000);
                                        // "Response from Guard" notification
                                        obj = engine.subscribe("UEB", "POLICY-CL-MGT");
                                        assertNotNull(obj);
@@ -210,7 +212,7 @@ public class ControlLoopXacmlGuardTest {
                                                        assertTrue(obj instanceof VirtualControlLoopNotification);
                                                        assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
 
-                                                       Thread.sleep(4000);
+                                                       Thread.sleep(2*4000);
 
                                                        // "Response from Guard" notification
                                                        obj = engine.subscribe("UEB", "POLICY-CL-MGT");
@@ -238,7 +240,7 @@ public class ControlLoopXacmlGuardTest {
                                                assertTrue(obj instanceof VirtualControlLoopNotification);
                                                assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
 
-                                               Thread.sleep(1000);
+                                               Thread.sleep(2*1000);
 
                                                obj = engine.subscribe("UEB", "APPC-CL");
                                                assertNotNull(obj);
@@ -277,7 +279,7 @@ public class ControlLoopXacmlGuardTest {
                                                //
                                                // now wait for it to finish
                                                //
-                                               Thread.sleep(15000);
+                                               Thread.sleep(2*15000);
                                                //
                                                // Ensure they released the lock
                                                //
index c3740d0..8208741 100644 (file)
@@ -14,7 +14,7 @@
                        <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />\r
                        <property name="javax.persistence.jdbc.user" value="sa" />\r
                        <property name="javax.persistence.jdbc.password" value="" />\r
-                       <property name="eclipselink.logging.level" value="ALL" />\r
+                       <property name="eclipselink.logging.level" value="CONFIG" />\r
                </properties>\r
        </persistence-unit>\r
 \r