Add tutorial example for multi-decisions
[policy/xacml-pdp.git] / tutorials / tutorial-xacml-application / src / main / java / org / onap / policy / tutorial / tutorial / TutorialRequest.java
index 356480b..cda1b43 100644 (file)
 
 package org.onap.policy.tutorial.tutorial;
 
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.StdMutableAttribute;
+import com.att.research.xacml.std.StdMutableRequest;
+import com.att.research.xacml.std.StdMutableRequestAttributes;
+import com.att.research.xacml.std.StdMutableRequestReference;
+import com.att.research.xacml.std.StdRequestAttributesReference;
+import com.att.research.xacml.std.annotations.RequestParser;
 import com.att.research.xacml.std.annotations.XACMLAction;
 import com.att.research.xacml.std.annotations.XACMLRequest;
 import com.att.research.xacml.std.annotations.XACMLResource;
 import com.att.research.xacml.std.annotations.XACMLSubject;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import lombok.Getter;
@@ -34,6 +47,15 @@ import org.onap.policy.models.decisions.concepts.DecisionRequest;
 @ToString
 @XACMLRequest(ReturnPolicyIdList = true)
 public class TutorialRequest {
+    public static final Identifier ATTRIBUTE_ID_MULTIID = new IdentifierImpl("urn:org:onap:tutorial-multi-id");
+    public static final Identifier ATTRIBUTE_ID_USER = new IdentifierImpl("urn:org:onap:tutorial-user");
+    public static final Identifier ATTRIBUTE_ID_ENTITY = new IdentifierImpl("urn:org:onap:tutorial-entity");
+    public static final Identifier ATTRIBUTE_ID_PERMISSION = new IdentifierImpl("urn:org:onap:tutorial-permission");
+    //
+    // For use with a multi request
+    //
+    private static final StdRequestAttributesReference refSubjects = new StdRequestAttributesReference("subjects1");
+    private static final StdRequestAttributesReference refActions = new StdRequestAttributesReference("actions1");
     //
     // Excluding from results to demonstrate control as to which attributes can be returned.
     //
@@ -46,7 +68,7 @@ public class TutorialRequest {
     @XACMLSubject(attributeId = "urn:org:onap:onap-instance", includeInResults = false)
     private String onapInstance;
 
-    @XACMLAction()
+    @XACMLAction
     private String action;
 
     //
@@ -65,9 +87,13 @@ public class TutorialRequest {
      * createRequest.
      *
      * @param decisionRequest Incoming
-     * @return TutorialRequest object
+     * @return Request XACML Request object
+     * @throws DataTypeException DataTypeException
+     * @throws IllegalAccessException IllegalAccessException
      */
-    public static TutorialRequest createRequest(DecisionRequest decisionRequest) {
+    @SuppressWarnings("unchecked")
+    public static Request createRequest(DecisionRequest decisionRequest)
+            throws IllegalAccessException, DataTypeException {
         //
         // Create our object
         //
@@ -86,6 +112,18 @@ public class TutorialRequest {
         // Add the resource attributes
         //
         Map<String, Object> resources = decisionRequest.getResource();
+        //
+        // Check if this is a multi-request
+        //
+        if (resources.containsKey("users")) {
+            //
+            // Setup the multi-request
+            //
+            return buildMultiRequest(request, (List<Object>) resources.get("users"));
+        }
+        //
+        // Continue as a single request
+        //
         for (Entry<String, Object> entrySet : resources.entrySet()) {
             if ("user".equals(entrySet.getKey())) {
                 request.user = entrySet.getValue().toString();
@@ -98,6 +136,87 @@ public class TutorialRequest {
             }
         }
 
-        return request;
+        return RequestParser.parseRequest(request);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static Request buildMultiRequest(TutorialRequest existingRequest, List<Object> users)
+            throws IllegalAccessException, DataTypeException {
+        //
+        // Create a single request absorbing the existing attributes, we will copy
+        // them over and assign them an ID.
+        //
+        StdMutableRequest singleRequest = new StdMutableRequest(RequestParser.parseRequest(existingRequest));
+        //
+        // Copy the attributes and assign ID's
+        //
+        StdMutableRequest multiRequest = addMultiRequestIds(singleRequest);
+        //
+        // Iterate and add in the requests
+        //
+        users.forEach(user -> addUser(multiRequest, (Map<String, Object>) user));
+        //
+        // Done
+        //
+        return multiRequest;
+    }
+
+    protected static StdMutableRequest addMultiRequestIds(StdMutableRequest singleRequest) {
+        StdMutableRequest multiRequest = new StdMutableRequest();
+        singleRequest.getRequestAttributes().forEach(attributes -> {
+            StdMutableRequestAttributes newAttributes = new StdMutableRequestAttributes();
+            if (attributes.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
+                newAttributes.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT);
+                newAttributes.setXmlId(refSubjects.getReferenceId());
+            } else if (attributes.getCategory().equals(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION)) {
+                newAttributes.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);
+                newAttributes.setXmlId(refActions.getReferenceId());
+            }
+            attributes.getAttributes().forEach(newAttributes::add);
+            multiRequest.add(newAttributes);
+        });
+        return multiRequest;
+    }
+
+    protected static void addUser(StdMutableRequest multiRequest, Map<String, Object> user) {
+        StdMutableRequestAttributes attributes = new StdMutableRequestAttributes();
+        attributes.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+        for (Entry<String, Object> entrySet : user.entrySet()) {
+            StdAttributeValue<String> value =
+                    new StdAttributeValue<>(XACML3.ID_DATATYPE_STRING, entrySet.getValue().toString());
+            StdMutableAttribute attribute = new StdMutableAttribute();
+            attribute.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+            attribute.setIncludeInResults(true);
+            attribute.addValue(value);
+            if ("multiId".equals(entrySet.getKey())) {
+                attributes.setXmlId(entrySet.getValue().toString());
+                attribute.setAttributeId(ATTRIBUTE_ID_MULTIID);
+            } else if ("user".equals(entrySet.getKey())) {
+                attribute.setAttributeId(ATTRIBUTE_ID_USER);
+            } else if ("entity".equals(entrySet.getKey())) {
+                attribute.setAttributeId(ATTRIBUTE_ID_ENTITY);
+            } else if ("permission".equals(entrySet.getKey())) {
+                attribute.setAttributeId(ATTRIBUTE_ID_PERMISSION);
+            } else {
+                throw new IllegalArgumentException("Unknown request attribute given");
+            }
+            attributes.add(attribute);
+        }
+        //
+        // Add the attributes to the Multi-Request
+        //
+        multiRequest.add(attributes);
+        //
+        // Create the references
+        //
+        StdRequestAttributesReference attributesReference = new StdRequestAttributesReference(attributes.getXmlId());
+        StdMutableRequestReference reference = new StdMutableRequestReference();
+        reference.add(refSubjects);
+        reference.add(refActions);
+        reference.add(attributesReference);
+        //
+        // Add the reference to this request
+        //
+        multiRequest.add(reference);
     }
 }