Fix documentation add tutorial 09/89709/15
authorPamela Dragosh <pdragosh@research.att.com>
Tue, 11 Jun 2019 14:55:04 +0000 (10:55 -0400)
committerPamela Dragosh <pdragosh@research.att.com>
Wed, 12 Jun 2019 09:54:15 +0000 (05:54 -0400)
Fixed some headings that made index's look strange.

Added xacml tutorial.

Issue-ID: POLICY-1842
Change-Id: Id6ab56e5d5d2a6b2fe37c8df5d3d70aa04776878
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
27 files changed:
docs/api/api.rst
docs/development/development.rst
docs/installation/installation.rst
docs/xacml/tutorial/app/pom.xml [new file with mode: 0644]
docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialApplication.java [new file with mode: 0644]
docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialRequest.java [new file with mode: 0644]
docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialTranslator.java [new file with mode: 0644]
docs/xacml/tutorial/app/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider [new file with mode: 0644]
docs/xacml/tutorial/app/src/test/java/org/onap/policy/tutorial/tutorial/TutorialApplicationTest.java [new file with mode: 0644]
docs/xacml/tutorial/app/src/test/resources/tutorial-decision-request.json [new file with mode: 0644]
docs/xacml/tutorial/app/src/test/resources/tutorial-policies.yaml [new file with mode: 0644]
docs/xacml/tutorial/app/src/test/resources/tutorial-policy-type.yaml [new file with mode: 0644]
docs/xacml/tutorial/app/src/test/resources/xacml.properties [new file with mode: 0644]
docs/xacml/tutorial/images/eclipse-create-junit.png [new file with mode: 0644]
docs/xacml/tutorial/images/eclipse-create-maven.png [new file with mode: 0644]
docs/xacml/tutorial/images/eclipse-create-request.png [new file with mode: 0644]
docs/xacml/tutorial/images/eclipse-import.png [new file with mode: 0644]
docs/xacml/tutorial/images/eclipse-inherit-app.png [new file with mode: 0644]
docs/xacml/tutorial/images/eclipse-maven-project.png [new file with mode: 0644]
docs/xacml/tutorial/images/eclipse-meta-inf.png [new file with mode: 0644]
docs/xacml/tutorial/tutorial-decision-request.json [new file with mode: 0644]
docs/xacml/tutorial/tutorial-decision-response.json [new file with mode: 0644]
docs/xacml/tutorial/tutorial-policies.yaml [new file with mode: 0644]
docs/xacml/tutorial/tutorial-policy-type.yaml [new file with mode: 0644]
docs/xacml/tutorial/tutorial-xacml.properties [new file with mode: 0644]
docs/xacml/xacml-tutorial.rst [new file with mode: 0644]
docs/xacml/xacml.rst

index fae3a07..caa91f8 100644 (file)
@@ -5,7 +5,7 @@
 .. _api-label:
 
 Policy Life Cycle API
-----------------------
+#####################
 .. toctree::
    :maxdepth: 2 
 
@@ -169,4 +169,4 @@ Get vFirewall Operational Policy::
 Delete vFirewall Operational Policy::
   curl --user 'healthcheck:zb!XztG34' -X DELETE "http://{ip}:{port}/policy/api/v1/policytypes/onap.policies.controlloop.Operational/versions/1.0.0/policies/operational.modifyconfig/versions/1" -H "Accept: application/json" -H "Content-Type: application/json"
 
-  
\ No newline at end of file
+  
index 82ff7e3..252e10d 100644 (file)
@@ -4,7 +4,7 @@
 
 
 Policy Platform Development
----------------------------
+###########################
 
 .. contents::
     :depth: 2
@@ -23,7 +23,7 @@ This article assumes that:
 The procedure documented in this article has been verified to work on a MacBook laptop running macOS Yosemite Version 10.10,5, Sierra Version 10.12.6, a HP Z600 desktop running Ubuntu 16.04.3 LTS, and an Unbuntu 16.04 VM.
 
 Cloning All The Policy Repositories
------------------------------------
+***********************************
 
 Run a script such as the script below to clone the required modules from the `ONAP git repository <https://gerrit.onap.org/r/#/admin/projects/?filter=policy>`_. This script clones all the ONAP Policy Framework repositories.
 
@@ -155,7 +155,7 @@ Execution of the script above results in the following directory hierarchy in yo
 
 
 Building ONAP Policy Framework Components
------------------------------------------
+*****************************************
 
 **Step 1:** Optionally, for a completely clean build, remove the ONAP built modules from your local repository.
 
@@ -218,7 +218,7 @@ If the developer is only interested in working with the new architecture compone
 
 
 Building the ONAP Policy Framework Docker Images
-------------------------------------------------
+************************************************
 The instructions here are based on the instructions in the file *~/git/onap/policy/docker/README.md*.
 
 **Step 1:** Build the Policy API Docker image
@@ -284,7 +284,7 @@ This image has the drools use case application and the supporting software built
 
 
 Starting the ONAP Policy Framework Docker Images
-------------------------------------------------
+************************************************
 
 In order to run the containers, you can use *docker-compose*. This uses the *docker-compose.yml* yaml file to bring up the ONAP Policy Framework. This file is located in the policy/docker repository.
 
index 1c3cbd1..627ffd6 100644 (file)
@@ -6,13 +6,9 @@
 Policy Component Installation
 -----------------------------
 
-.. contents::
-    :depth: 2
+.. toctree::
+   :maxdepth: 1
 
-
-oom.rst
-docker.rst
-
-
-End of Document
+   oom.rst
+   docker.rst
 
diff --git a/docs/xacml/tutorial/app/pom.xml b/docs/xacml/tutorial/app/pom.xml
new file mode 100644 (file)
index 0000000..555f203
--- /dev/null
@@ -0,0 +1,28 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.onap.policy.tutorial</groupId>
+  <artifactId>tutorial</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+
+  <name>tutorial</name>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.onap.policy.xacml-pdp.applications</groupId>
+      <artifactId>common</artifactId>
+      <version>2.1.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialApplication.java b/docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialApplication.java
new file mode 100644 (file)
index 0000000..99cbdce
--- /dev/null
@@ -0,0 +1,40 @@
+package org.onap.policy.tutorial.tutorial;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
+import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
+
+public class TutorialApplication extends StdXacmlApplicationServiceProvider {
+       
+       private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier();
+       private final TutorialTranslator translator = new TutorialTranslator();
+
+    @Override
+    public String applicationName() {
+        return "tutorial";
+    }
+
+    @Override
+    public List<String> actionDecisionsSupported() {
+        return Arrays.asList("authorize");
+    }
+
+    @Override
+    public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
+        return Arrays.asList(supportedPolicyType);
+    }
+
+    @Override
+    public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+       return supportedPolicyType.equals(policyTypeId);
+    }
+
+    @Override
+       protected ToscaPolicyTranslator getTranslator(String type) {
+               return translator;
+       }
+
+}
diff --git a/docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialRequest.java b/docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialRequest.java
new file mode 100644 (file)
index 0000000..33442b2
--- /dev/null
@@ -0,0 +1,76 @@
+package org.onap.policy.tutorial.tutorial;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+
+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 lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString
+@XACMLRequest(ReturnPolicyIdList = true)
+public class TutorialRequest {
+    @XACMLSubject(includeInResults = true)
+    private String onapName;
+
+    @XACMLSubject(attributeId = "urn:org:onap:onap-component", includeInResults = true)
+    private String onapComponent;
+
+    @XACMLSubject(attributeId = "urn:org:onap:onap-instance",  includeInResults = true)
+    private String onapInstance;
+
+    @XACMLAction()
+    private String action;
+
+    @XACMLResource(attributeId = "urn:org:onap:tutorial-user", includeInResults = true)
+    private String user;
+
+    @XACMLResource(attributeId = "urn:org:onap:tutorial-entity", includeInResults = true)
+    private String entity;
+
+    @XACMLResource(attributeId = "urn:org:onap:tutorial-permission", includeInResults = true)
+    private String permission;
+
+    public static TutorialRequest createRequest(DecisionRequest decisionRequest) {
+       //
+       // Create our object
+       //
+       TutorialRequest request = new TutorialRequest();
+        //
+        // Add the subject attributes
+        //
+        request.onapName = decisionRequest.getOnapName();
+        request.onapComponent = decisionRequest.getOnapComponent();
+        request.onapInstance = decisionRequest.getOnapInstance();
+        //
+        // Add the action attribute
+        //
+        request.action = decisionRequest.getAction();
+        //
+        // Add the resource attributes
+        //
+        Map<String, Object> resources = decisionRequest.getResource();
+        for (Entry<String, Object> entrySet : resources.entrySet()) {
+            if ("user".equals(entrySet.getKey())) {
+               request.user = entrySet.getValue().toString();
+            }
+            if ("entity".equals(entrySet.getKey())) {
+               request.entity = entrySet.getValue().toString();
+            }
+            if ("permission".equals(entrySet.getKey())) {
+               request.permission = entrySet.getValue().toString();
+            }
+        }      
+       
+       return request;
+    }
+}
diff --git a/docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialTranslator.java b/docs/xacml/tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialTranslator.java
new file mode 100644 (file)
index 0000000..d118aab
--- /dev/null
@@ -0,0 +1,161 @@
+package org.onap.policy.tutorial.tutorial;
+
+import java.util.List;
+import java.util.Map;
+
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+import org.onap.policy.models.decisions.concepts.DecisionResponse;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
+
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.annotations.RequestParser;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+public class TutorialTranslator implements ToscaPolicyTranslator {
+       
+       private static final Identifier ID_TUTORIAL_USER =
+            new IdentifierImpl(ToscaDictionary.ID_URN_ONAP, "tutorial-user");
+       private static final Identifier ID_TUTORIAL_ENTITY =
+            new IdentifierImpl(ToscaDictionary.ID_URN_ONAP, "tutorial-entity");
+       private static final Identifier ID_TUTORIAL_PERM =
+            new IdentifierImpl(ToscaDictionary.ID_URN_ONAP, "tutorial-perm");
+
+       public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
+               //
+               // Here is our policy with a version and default combining algo
+               //
+        PolicyType newPolicyType = new PolicyType();
+        newPolicyType.setPolicyId(toscaPolicy.getMetadata().get("policy-id"));
+        newPolicyType.setVersion(toscaPolicy.getMetadata().get("policy-version"));
+        //
+        // When choosing the rule combining algorithm, be sure to be mindful of the
+        // setting xacml.att.policyFinderFactory.combineRootPolicies in the
+        // xacml.properties file. As that choice for ALL the policies together may have
+        // an impact on the decision rendered from each individual policy.
+        //
+        // In this case, we will only produce XACML rules for permissions. If no permission
+        // combo exists, then the default is to deny.
+        //
+        newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue());
+        //
+        // Create the target for the Policy.
+        //
+        // For simplicity, let's just match on the action "authorize" and the user
+        //
+        MatchType matchAction = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+                XACML3.ID_FUNCTION_STRING_EQUAL,
+                "authorize",
+                XACML3.ID_DATATYPE_STRING,
+                XACML3.ID_ACTION,
+                XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);
+        Map<String, Object> props = toscaPolicy.getProperties();
+        String user = props.get("user").toString();
+        MatchType matchUser = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+                XACML3.ID_FUNCTION_STRING_EQUAL,
+                user,
+                XACML3.ID_DATATYPE_STRING,
+                ID_TUTORIAL_USER,
+                XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+        AnyOfType anyOf = new AnyOfType();
+        //
+        // Create AllOf (AND) of just Policy Id
+        //
+        anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchAction));
+        anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchUser));
+        TargetType target = new TargetType();
+        target.getAnyOf().add(anyOf);
+        newPolicyType.setTarget(target);
+        //
+        // Now add the rule for each permission
+        //
+        List<Object> permissions = (List<Object>) props.get("permissions");
+               for (Object permission : permissions) {
+                       
+            MatchType matchEntity = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+                    XACML3.ID_FUNCTION_STRING_EQUAL,
+                    ((Map<String, String>) permission).get("entity"),
+                    XACML3.ID_DATATYPE_STRING,
+                    ID_TUTORIAL_ENTITY,
+                    XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+               
+            MatchType matchPermission = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+                    XACML3.ID_FUNCTION_STRING_EQUAL,
+                    ((Map<String, String>) permission).get("permission"),
+                    XACML3.ID_DATATYPE_STRING,
+                    ID_TUTORIAL_PERM,
+                    XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+            anyOf = new AnyOfType();
+            anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchEntity));
+            anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchPermission));
+            target = new TargetType();
+            target.getAnyOf().add(anyOf);
+            
+            RuleType rule = new RuleType();
+            rule.setDescription("Default is to PERMIT if the policy matches.");
+            rule.setRuleId(newPolicyType.getPolicyId() + ":rule");
+            rule.setEffect(EffectType.PERMIT);
+            rule.setTarget(target);
+            
+            newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+        }
+               return newPolicyType;
+       }
+
+       public Request convertRequest(DecisionRequest request) {
+        try {
+            return RequestParser.parseRequest(TutorialRequest.createRequest(request));
+        } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
+        }
+               return null;
+       }
+
+       public DecisionResponse convertResponse(Response xacmlResponse) {
+        DecisionResponse decisionResponse = new DecisionResponse();
+        //
+        // Iterate through all the results
+        //
+        for (Result xacmlResult : xacmlResponse.getResults()) {
+            //
+            // Check the result
+            //
+            if (xacmlResult.getDecision() == Decision.PERMIT) {
+                //
+                // Just simply return a Permit response
+                //
+                decisionResponse.setStatus(Decision.PERMIT.toString());
+            }
+            if (xacmlResult.getDecision() == Decision.DENY) {
+                //
+                // Just simply return a Deny response
+                //
+                decisionResponse.setStatus(Decision.DENY.toString());
+            }
+            if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) {
+                //
+                // There is no guard policy, so we return a permit
+                //
+                decisionResponse.setStatus(Decision.PERMIT.toString());
+            }
+        }
+
+        return decisionResponse;
+       }
+
+}
diff --git a/docs/xacml/tutorial/app/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider b/docs/xacml/tutorial/app/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider
new file mode 100644 (file)
index 0000000..942cc59
--- /dev/null
@@ -0,0 +1 @@
+org.onap.policy.tutorial.tutorial.TutorialApplication
\ No newline at end of file
diff --git a/docs/xacml/tutorial/app/src/test/java/org/onap/policy/tutorial/tutorial/TutorialApplicationTest.java b/docs/xacml/tutorial/app/src/test/java/org/onap/policy/tutorial/tutorial/TutorialApplicationTest.java
new file mode 100644 (file)
index 0000000..7a1c2f9
--- /dev/null
@@ -0,0 +1,93 @@
+package org.onap.policy.tutorial.tutorial;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.ServiceLoader;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+import org.onap.policy.models.decisions.concepts.DecisionResponse;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.onap.policy.pdp.xacml.application.common.TestUtils;
+import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
+import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
+import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.att.research.xacml.api.Response;
+
+public class TutorialApplicationTest {
+       private static final Logger LOGGER = LoggerFactory.getLogger(TutorialApplicationTest.class);
+    private static Properties properties = new Properties();
+    private static File propertiesFile;
+    private static XacmlApplicationServiceProvider service;
+    private static StandardCoder gson = new StandardCoder();
+
+    @ClassRule
+    public static final TemporaryFolder policyFolder = new TemporaryFolder();
+
+    @BeforeClass
+    public static void setup() throws Exception {
+        //
+        // Setup our temporary folder
+        //
+        XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
+        propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
+                properties, myCreator);
+        //
+        // Load XacmlApplicationServiceProvider service
+        //
+        ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
+                ServiceLoader.load(XacmlApplicationServiceProvider.class);
+        //
+        // Look for our class instance and save it
+        //
+        Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
+        while (iterator.hasNext()) {
+            XacmlApplicationServiceProvider application = iterator.next();
+            //
+            // Is it our service?
+            //
+            if (application instanceof TutorialApplication) {
+               service = application;
+            }
+        }
+        //
+        // Tell the application to initialize based on the properties file
+        // we just built for it.
+        //
+        service.initialize(propertiesFile.toPath().getParent());
+       }
+    
+    @Test
+    public void test() throws CoderException, XacmlApplicationException, IOException {
+        //
+        // Now load the tutorial policies.
+        //
+        TestUtils.loadPolicies("src/test/resources/tutorial-policies.yaml", service);
+        //
+        // Load a Decision request
+        //
+        DecisionRequest decisionRequest = gson.decode(
+                TextFileUtils
+                .getTextFileAsString("src/test/resources/tutorial-decision-request.json"),
+                DecisionRequest.class);
+       //
+        // Test a decision
+        //
+        Pair<DecisionResponse, Response> decision = service.makeDecision(decisionRequest);
+        LOGGER.info(decision.getLeft().toString());
+    }
+
+}
diff --git a/docs/xacml/tutorial/app/src/test/resources/tutorial-decision-request.json b/docs/xacml/tutorial/app/src/test/resources/tutorial-decision-request.json
new file mode 100644 (file)
index 0000000..8c1ec10
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "ONAPName": "TutorialPEP",
+  "ONAPComponent": "TutorialPEPComponent",
+  "ONAPInstance": "TutorialPEPInstance",
+  "requestId": "unique-request-id-tutorial",
+  "action": "authorize",
+  "resource": {
+    "user": "demo",
+    "entity": "foo",
+    "permission" : "read"
+  }
+}
diff --git a/docs/xacml/tutorial/app/src/test/resources/tutorial-policies.yaml b/docs/xacml/tutorial/app/src/test/resources/tutorial-policies.yaml
new file mode 100644 (file)
index 0000000..90a1f9e
--- /dev/null
@@ -0,0 +1,32 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+topology_template:
+    policies:
+        -
+            onap.policy.tutorial.demo:
+                type: onap.policies.Authorization
+                version: 1.0.0
+                metadata:
+                    policy-id: onap.policy.tutorial.demo
+                    policy-version: 1
+                properties:
+                    user: demo
+                    permissions:
+                        -
+                            entity: foo
+                            permission: read
+                        -
+                            entity: foo
+                            permission: write
+        -
+            onap.policy.tutorial.audit:
+                type: onap.policies.Authorization
+                version: 1.0.0
+                metadata:
+                    policy-id: onap.policy.tutorial.bar
+                    policy-version: 1
+                properties:
+                    user: audit
+                    permissions:
+                        -
+                            entity: foo
+                            permission: read
diff --git a/docs/xacml/tutorial/app/src/test/resources/tutorial-policy-type.yaml b/docs/xacml/tutorial/app/src/test/resources/tutorial-policy-type.yaml
new file mode 100644 (file)
index 0000000..181a73c
--- /dev/null
@@ -0,0 +1,34 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+policy_types:
+  -
+    onap.policies.Authorization:
+        derived_from: tosca.policies.Root
+        version: 1.0.0
+        description: Example tutorial policy type for doing user authorization
+        properties:
+            user:
+                type: string
+                required: true
+                description: The unique user name
+            permissions:
+                type: list
+                required: true
+                description: A list of resource permissions
+                entry_schema:
+                    type: onap.datatypes.Tutorial
+data_types:
+  -
+    onap.datatypes.Tutorial:
+    derived_from: tosca.datatypes.Root
+    version: 1.0.0
+    properties:
+        entity:
+            type: string
+            required: true
+            description: The resource
+        permission:
+            type: string
+            required: true
+            description: The permission level
+            constraints:
+                - valid_values: [read, write, delete]
diff --git a/docs/xacml/tutorial/app/src/test/resources/xacml.properties b/docs/xacml/tutorial/app/src/test/resources/xacml.properties
new file mode 100644 (file)
index 0000000..277b098
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Properties that the embedded PDP engine uses to configure and load
+#
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+#
+# ONAP PDP Implementation Factories
+#
+xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapPolicyFinderFactory
+
+#
+# Use a root combining algorithm
+#
+xacml.att.policyFinderFactory.combineRootPolicies=urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides
+
+#
+# Policies to load
+#
+xacml.rootPolicies=
+xacml.referencedPolicies=
\ No newline at end of file
diff --git a/docs/xacml/tutorial/images/eclipse-create-junit.png b/docs/xacml/tutorial/images/eclipse-create-junit.png
new file mode 100644 (file)
index 0000000..63dc0ab
Binary files /dev/null and b/docs/xacml/tutorial/images/eclipse-create-junit.png differ
diff --git a/docs/xacml/tutorial/images/eclipse-create-maven.png b/docs/xacml/tutorial/images/eclipse-create-maven.png
new file mode 100644 (file)
index 0000000..4272f06
Binary files /dev/null and b/docs/xacml/tutorial/images/eclipse-create-maven.png differ
diff --git a/docs/xacml/tutorial/images/eclipse-create-request.png b/docs/xacml/tutorial/images/eclipse-create-request.png
new file mode 100644 (file)
index 0000000..c8ef534
Binary files /dev/null and b/docs/xacml/tutorial/images/eclipse-create-request.png differ
diff --git a/docs/xacml/tutorial/images/eclipse-import.png b/docs/xacml/tutorial/images/eclipse-import.png
new file mode 100644 (file)
index 0000000..7c8c538
Binary files /dev/null and b/docs/xacml/tutorial/images/eclipse-import.png differ
diff --git a/docs/xacml/tutorial/images/eclipse-inherit-app.png b/docs/xacml/tutorial/images/eclipse-inherit-app.png
new file mode 100644 (file)
index 0000000..637cf49
Binary files /dev/null and b/docs/xacml/tutorial/images/eclipse-inherit-app.png differ
diff --git a/docs/xacml/tutorial/images/eclipse-maven-project.png b/docs/xacml/tutorial/images/eclipse-maven-project.png
new file mode 100644 (file)
index 0000000..5e6860f
Binary files /dev/null and b/docs/xacml/tutorial/images/eclipse-maven-project.png differ
diff --git a/docs/xacml/tutorial/images/eclipse-meta-inf.png b/docs/xacml/tutorial/images/eclipse-meta-inf.png
new file mode 100644 (file)
index 0000000..254349b
Binary files /dev/null and b/docs/xacml/tutorial/images/eclipse-meta-inf.png differ
diff --git a/docs/xacml/tutorial/tutorial-decision-request.json b/docs/xacml/tutorial/tutorial-decision-request.json
new file mode 100644 (file)
index 0000000..8c1ec10
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "ONAPName": "TutorialPEP",
+  "ONAPComponent": "TutorialPEPComponent",
+  "ONAPInstance": "TutorialPEPInstance",
+  "requestId": "unique-request-id-tutorial",
+  "action": "authorize",
+  "resource": {
+    "user": "demo",
+    "entity": "foo",
+    "permission" : "read"
+  }
+}
diff --git a/docs/xacml/tutorial/tutorial-decision-response.json b/docs/xacml/tutorial/tutorial-decision-response.json
new file mode 100644 (file)
index 0000000..7a87b4c
--- /dev/null
@@ -0,0 +1,3 @@
+{
+    "status":"Permit"
+}
diff --git a/docs/xacml/tutorial/tutorial-policies.yaml b/docs/xacml/tutorial/tutorial-policies.yaml
new file mode 100644 (file)
index 0000000..45769ea
--- /dev/null
@@ -0,0 +1,30 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+topology_template:
+    policies:
+        -
+            onap.policy.tutorial.demo:
+                type: onap.policies.Authorization
+                version: 1.0.0
+                metadata:
+                    policy-id: onap.policy.tutorial.demo
+                properties:
+                    user: demo
+                    permissions:
+                        -
+                            entity: foo
+                            permission: read
+                        -
+                            entity: foo
+                            permission: write
+        -
+            onap.policy.tutorial.audit:
+                type: onap.policies.Authorization
+                version: 1.0.0
+                metadata:
+                    policy-id: onap.policy.tutorial.bar
+                properties:
+                    user: audit
+                    permissions:
+                        -
+                            entity: foo
+                            permission: read
diff --git a/docs/xacml/tutorial/tutorial-policy-type.yaml b/docs/xacml/tutorial/tutorial-policy-type.yaml
new file mode 100644 (file)
index 0000000..181a73c
--- /dev/null
@@ -0,0 +1,34 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+policy_types:
+  -
+    onap.policies.Authorization:
+        derived_from: tosca.policies.Root
+        version: 1.0.0
+        description: Example tutorial policy type for doing user authorization
+        properties:
+            user:
+                type: string
+                required: true
+                description: The unique user name
+            permissions:
+                type: list
+                required: true
+                description: A list of resource permissions
+                entry_schema:
+                    type: onap.datatypes.Tutorial
+data_types:
+  -
+    onap.datatypes.Tutorial:
+    derived_from: tosca.datatypes.Root
+    version: 1.0.0
+    properties:
+        entity:
+            type: string
+            required: true
+            description: The resource
+        permission:
+            type: string
+            required: true
+            description: The permission level
+            constraints:
+                - valid_values: [read, write, delete]
diff --git a/docs/xacml/tutorial/tutorial-xacml.properties b/docs/xacml/tutorial/tutorial-xacml.properties
new file mode 100644 (file)
index 0000000..e10ad63
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Properties that the embedded PDP engine uses to configure and load
+#
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+#
+# ONAP PDP Implementation Factories
+#
+xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapPolicyFinderFactory
+
+#
+# Use a root combining algorithm
+#
+xacml.att.policyFinderFactory.combineRootPolicies=urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides
+
+#
+# Policies to load
+#
+xacml.rootPolicies=
+xacml.referencedPolicies=
diff --git a/docs/xacml/xacml-tutorial.rst b/docs/xacml/xacml-tutorial.rst
new file mode 100644 (file)
index 0000000..72271ad
--- /dev/null
@@ -0,0 +1,330 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+
+.. _xacmltutorial-label:
+
+Policy XACML - Custom Application Tutorial
+##########################################
+
+.. toctree::
+   :maxdepth: 3
+
+This tutorial shows how to build a XACML application for a Policy Type. Please be sure to clone the
+policy repositories before going through the tutorial. See :ref:`<policy-dev-label>` for details.
+
+
+Design a Policy Type
+********************
+Follow :ref:`TOSCA Policy Primer <tosca-label>` for more information. For the tutorial, we will use
+this example Policy Type in which an ONAP PEP client would like to enforce an action **authorize**
+for a *user* to execute a *permission* on an *entity*.
+
+.. literalinclude:: tutorial/tutorial-policy-type.yaml
+  :language: JSON
+  :caption: Example Tutorial Policy Type
+  :linenos:
+
+We would expect then to be able to create the following policies to allow the demo user to Read/Write
+a entity called foo. While the audit user can only read the entity called foo. No user has Delete
+permission.
+
+.. literalinclude:: tutorial/tutorial-policies.yaml
+  :language: JSON
+  :caption: Example Policies Derived From Tutorial Policy Type
+  :linenos:
+
+Design Decision Request and expected Decision Response
+******************************************************
+For the PEP (Policy Enforcement Point) client applications that call the Decision API, you need
+to design how the Decision API Request resource fields will be sent via the PEP.
+
+.. literalinclude:: tutorial/tutorial-decision-request.json
+  :language: JSON
+  :caption: Example Decision Request
+  :linenos:
+
+For simplicity, we expect only a *Permit* or *Deny* in the Decision Response.
+
+.. literalinclude:: tutorial/tutorial-decision-response.json
+  :language: JSON
+  :caption: Example Decision Response
+  :linenos:
+
+Create A Maven Project
+**********************
+This part of the tutorial assumes you understand how to use Eclipse to create a Maven
+project. Please follow any examples for the Eclipse installation you have to create
+an empty application. For the tutorial, use groupId *org.onap.policy.tutorial* and artifactId
+*tutorial*.
+
+.. image:: tutorial/images/eclipse-create-maven.png
+
+.. image:: tutorial/images/eclipse-maven-project.png
+
+Be sure to import the policy/xacml-pdp project into Eclipse.
+
+.. image:: tutorial/images/eclipse-import.png
+
+Add Dependencies Into Application pom.xml
+*****************************************
+
+.. code-block:: java
+  :caption: pom.xml dependencies
+
+    <dependency>
+      <groupId>org.onap.policy.xacml-pdp.applications</groupId>
+      <artifactId>common</artifactId>
+      <version>2.1.0-SNAPSHOT</version>
+    </dependency>
+
+Create META-INF to expose Java Service
+**************************************
+The ONAP XACML PDP Engine will not be able to find the tutorial application unless it has
+a property file located in src/main/resources/META-INF/services that contains a property file
+declaring the class that implements the service.
+
+The name of the file must match **org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider**
+and the contents of the file is one line **org.onap.policy.tutorial.tutorial.TutorialApplication**.
+
+.. image:: tutorial/images/eclipse-meta-inf.png
+
+Create A Java Class That Extends **StdXacmlApplicationServiceProvider**
+***********************************************************************
+You could implement **XacmlApplicationServiceProvider** if you wish, but
+for simplicity if you just extend **StdXacmlApplicationServiceProvider** you
+will get a lot of implementation done for your application up front. All
+that needs to be implemented is providing a custom translator.
+
+.. image:: tutorial/images/eclipse-inherit-app.png
+
+.. code-block:: java
+  :caption: Custom Tutorial Application Service Provider
+  :emphasize-lines: 6
+
+  package org.onap.policy.tutorial.tutorial;
+
+  import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
+  import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
+
+  public class TutorialApplication extends StdXacmlApplicationServiceProvider {
+
+       @Override
+       protected ToscaPolicyTranslator getTranslator(String type) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+  }
+
+Override Methods for Tutorial
+*****************************
+Override these methods to differentiate Tutorial from other applications so that the XACML PDP
+Engine can determine how to route policy types and policies to the application.
+
+.. code-block:: java
+  :caption: Custom Tutorial Application Service Provider
+
+  package org.onap.policy.tutorial.tutorial;
+
+  import java.util.Arrays;
+  import java.util.List;
+
+  import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+  import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
+  import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
+
+  public class TutorialApplication extends StdXacmlApplicationServiceProvider {
+       
+       private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier();
+
+    @Override
+    public String applicationName() {
+        return "tutorial";
+    }
+
+    @Override
+    public List<String> actionDecisionsSupported() {
+        return Arrays.asList("authorize");
+    }
+
+    @Override
+    public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
+        return Arrays.asList(supportedPolicyType);
+    }
+
+    @Override
+    public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+       return supportedPolicyType.equals(policyTypeId);
+    }
+
+    @Override
+       protected ToscaPolicyTranslator getTranslator(String type) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+  }
+
+Create A Translation Class that extends the ToscaPolicyTranslator Class
+***********************************************************************
+Please be sure to review the existing translators in the policy/xacml-pdp repo to see if they could
+be re-used for your policy type. For the tutorial, we will create our own translator.
+
+The custom translator is not only responsible for translating Policies derived from the Tutorial
+Policy Type, but also for translating Decision API Requests/Responses to/from the appropriate XACML
+requests/response objects the XACML engine understands.  
+
+.. code-block:: java
+  :caption: Custom Tutorial Translator Class
+
+  package org.onap.policy.tutorial.tutorial;
+
+  import org.onap.policy.models.decisions.concepts.DecisionRequest;
+  import org.onap.policy.models.decisions.concepts.DecisionResponse;
+  import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+  import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
+  import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
+
+  import com.att.research.xacml.api.Request;
+  import com.att.research.xacml.api.Response;
+
+  import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+
+  public class TutorialTranslator implements ToscaPolicyTranslator {
+
+       public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public Request convertRequest(DecisionRequest request) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public DecisionResponse convertResponse(Response xacmlResponse) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+  }
+
+Implement the TutorialTranslator Methods
+****************************************
+This is the part where knowledge of the XACML OASIS 3.0 specification is required. Please refer to
+that specification on the many ways to design a XACML Policy.
+
+For the tutorial, we will build code that translates the TOSCA Policy into one XACML Policy that matches
+on the user and action. It will then have one or more rules for each entity and permission combination. The
+default combining algorithm for the XACML Rules are to "Deny Unless Permit".
+
+.. Note::
+  There are many ways to build the policy based on the attributes. How to do so is a matter of experience and
+  fine tuning using the many options for combining algorithms, target and/or condition matching and the rich set of
+  functions available.
+
+Here is one implementation example:
+
+.. literalinclude:: tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialTranslator.java
+  :caption: Example Translator Implementation
+  :linenos:
+
+Use the TutorialTranslator in the TutorialApplication
+*****************************************************
+Be sure to go back to the TutorialApplication and create an instance of the translator to return to the
+StdXacmlApplicationServiceProvider. The StdXacmlApplicationServiceProvider uses the translator to convert
+a policy when a new policy is deployed to the ONAP XACML PDP Engine.
+
+.. code-block:: java
+  :caption: Final TutorialApplication Class
+  :linenos:
+  :emphasize-lines: 37
+
+  package org.onap.policy.tutorial.tutorial;
+
+  import java.util.Arrays;
+  import java.util.List;
+
+  import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+  import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
+  import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
+
+  public class TutorialApplication extends StdXacmlApplicationServiceProvider {
+       
+       private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier();
+       private final TutorialTranslator translator = new TutorialTranslator();
+
+    @Override
+    public String applicationName() {
+        return "tutorial";
+    }
+
+    @Override
+    public List<String> actionDecisionsSupported() {
+        return Arrays.asList("authorize");
+    }
+
+    @Override
+    public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
+        return Arrays.asList(supportedPolicyType);
+    }
+
+    @Override
+    public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+       return supportedPolicyType.equals(policyTypeId);
+    }
+
+    @Override
+       protected ToscaPolicyTranslator getTranslator(String type) {
+               return translator;
+       }
+
+  }
+
+Create a XACML Request from ONAP Decision Request
+*************************************************
+The easiest way to do this is to use the annotations feature from XACML PDP library to create an example XACML
+request. Then create an instance and simply populate it from an incoming ONAP Decision Request.
+
+.. image: tutorial/images/eclipse-create-request.png
+
+.. literalinclude:: tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialRequest.java
+  :caption: Example Decision Request to Decision Response Implementation
+  :linenos:
+
+
+Create xacml.properties for the XACML PDP engine to use
+*******************************************************
+In the applications *src/test/resources* directory, create a xacml.properties file that will be used by the embedded
+XACML PDP Engine when loading.
+
+.. literalinclude:: tutorial/tutorial-xacml.properties
+  :caption: Example xacml.properties file
+  :linenos:
+  :emphasize-lines: 20, 25
+
+Create a JUnit and use the TestUtils.java class in application/common
+*********************************************************************
+Using Eclipse, create a JUnit and be sure to add a setup() method stub. Here you will be utilizing a TestUtils.java
+class from the policy/xamcl-pdp repo's application/common submodule to use some utility methods for building the JUnit test.
+
+.. image: tutorial/images/eclipse-junit-create.png
+
+Copy the TOSCA Policy Type :download:`link <tutorial/tutorial-policy-type.yaml>` and the TOSCA Policies :download:`link <tutorial/tutorial-policies.yaml>`
+into the src/test/resources directory.
+
+We will create a temporary folder which is used by the **StdXacmlApplicationServiceProvider** to store working copies of policies as they are loaded
+into the application.
+
+.. literalinclude:: tutorial/app/src/test/java/org/onap/policy/tutorial/tutorial/TutorialApplicationTest.java
+  :caption: Example Translator Implementation
+  :linenos:
+
+Run the JUnit test!!
+
+Where To Go From Here
+*********************
+Once you have created enough JUnit tests that test the TutorialTranslator.java and TutorialRequest.java classes, you are ready to now make your
+application available to the ONAP XACML PDP Engine. These steps are covered in another tutorial.
+
+
+
index 58d887f..7187351 100644 (file)
@@ -92,11 +92,13 @@ This is an example Decision API payload made to retrieve a decision for an Optim
 
 Supporting Custom Policy Types
 ******************************
-In order to support your own custom Policy Type that the XACML PDP Engine can support, one needs to build a Java service application that extends the **XacmlApplicationServiceProvider** interface and expose it in the classpath used to load the XACML PDP Engine. First, ensure you define and create the TOSCA Policy Type according to these :ref:`Policy Design and Development <design-label>`. You should be able to load your custom Policy Type using the :ref:`Policy Lifecycle API <api-label>`. Once successful, you should be able to start creating policies from your custom Policy Type.
+In order to support your own custom Policy Type that the XACML PDP Engine can support, one needs to build a Java service application that extends the **XacmlApplicationServiceProvider** interface and implement a **ToscaTranslator** application. Your application should register itself as a Java service application and expose it in the classpath used to be loaded into the ONAP XACML PDP Engine. Ensure you define and create the TOSCA Policy Type according to these :ref:`Policy Design and Development <design-label>`. You should be able to load your custom Policy Type using the :ref:`Policy Lifecycle API <api-label>`. Once successful, you should be able to start creating policies from your custom Policy Type.
 
-See each of the ONAP Policy Type application implementations for examples on how to implement the methods for the **XacmlApplicationServiceProvider**. Consider re-using the standard implementations.
+See each of the ONAP Policy Type application implementations for for ONAP re-use the **StdXacmlApplicationServiceProvider** class. They give simple examples on how to use various implementations of **ToscaTranslator** applications.
 
-Once your application is developed and the XACML PDP Engine can find your application via setting the classpath appropriately, then use the :ref:`PAP REST API <pap-label>` to ensure the XACML PDP is loaded and registering your custom Policy Type. Once successful, then you should be able to start deploying the created policies to the XACML PDP Engine.
+The following tutorial can be helpful to get started: :ref:`xacmltutorial-label`
+
+Once your application is developed and the ONAP XACML PDP Engine can find your application via setting the classpath appropriately, then use the :ref:`PAP REST API <pap-label>` to ensure the ONAP XACML PDP is registering your custom Policy Type with the PAP. Once successful, then you should be able to start deploying the created policies to the XACML PDP Engine.
 
 Decision API
 ************