1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
3 .. _xacmltutorial-label:
5 Policy XACML - Custom Application Tutorial
6 ##########################################
11 This tutorial shows how to build a XACML application for a Policy Type. Please be sure to clone the
12 policy repositories before going through the tutorial. See :ref:`policy-development-tools-label` for details.
16 Follow :ref:`TOSCA Policy Primer <tosca-label>` for more information. For the tutorial, we will use
17 this example Policy Type in which an ONAP PEP client would like to enforce an action **authorize**
18 for a *user* to execute a *permission* on an *entity*. `See here for latest Tutorial Policy Type <https://github.com/onap/policy-xacml-pdp/blob/master/tutorials/tutorial-xacml-application/src/test/resources/tutorial-policy-type.yaml>`_.
20 .. literalinclude:: tutorial/tutorial-policy-type.yaml
22 :caption: Example Tutorial Policy Type
25 We would expect then to be able to create the following policies to allow the demo user to Read/Write
26 an entity called foo, while the audit user can only read the entity called foo. Neither user has Delete
27 permission. `See here for latest Tutorial Policies <https://github.com/onap/policy-xacml-pdp/blob/master/tutorials/tutorial-xacml-application/src/test/resources/tutorial-policies.yaml>`_.
29 .. literalinclude:: tutorial/tutorial-policies.yaml
31 :caption: Example Policies Derived From Tutorial Policy Type
34 Design Decision Request and expected Decision Response
35 ******************************************************
36 For the PEP (Policy Enforcement Point) client applications that call the Decision API, you need
37 to design how the Decision API Request resource fields will be sent via the PEP.
39 .. literalinclude:: tutorial/tutorial-decision-request.json
41 :caption: Example Decision Request
44 For simplicity, this tutorial expects only a *Permit* or *Deny* in the Decision Response. However, one could
45 customize the Decision Response object and send back whatever information is desired.
47 .. literalinclude:: tutorial/tutorial-decision-response.json
49 :caption: Example Decision Response
52 Create A Maven Project
53 **********************
54 Use whatever tool or environment to create your application project. This tutorial assumes you use Maven to build it.
56 Add Dependencies Into Application pom.xml
57 *****************************************
59 Here we import the XACML PDP Application common dependency which has the interfaces we need to implement. In addition,
60 we are importing a testing dependency that has common code for producing a JUnit test.
63 :caption: pom.xml dependencies
66 <groupId>org.onap.policy.xacml-pdp.applications</groupId>
67 <artifactId>common</artifactId>
68 <version>2.3.3</version>
71 <groupId>org.onap.policy.xacml-pdp</groupId>
72 <artifactId>xacml-test</artifactId>
73 <version>2.3.3</version>
77 Create META-INF to expose Java Service
78 **************************************
79 The ONAP XACML PDP Engine will not be able to find the tutorial application unless it has
80 a property file located in src/main/resources/META-INF/services that contains a property file
81 declaring the class that implements the service.
83 The name of the file must match **org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider**
84 and the contents of the file is one line **org.onap.policy.tutorial.tutorial.TutorialApplication**.
87 :caption: META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider
89 org.onap.policy.tutorial.tutorial.TutorialApplication
92 Create A Java Class That Extends **StdXacmlApplicationServiceProvider**
93 ***********************************************************************
94 You could implement **XacmlApplicationServiceProvider** if you wish, but
95 for simplicity if you just extend **StdXacmlApplicationServiceProvider** you
96 will get a lot of implementation done for your application up front. All
97 that needs to be implemented is providing a custom translator.
100 :caption: Custom Tutorial Application Service Provider
103 package org.onap.policy.tutorial.tutorial;
105 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
106 import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
108 public class TutorialApplication extends StdXacmlApplicationServiceProvider {
111 protected ToscaPolicyTranslator getTranslator(String type) {
112 // TODO Auto-generated method stub
118 Override Methods for Tutorial
119 *****************************
120 Override these methods to differentiate Tutorial from other applications so that the XACML PDP
121 Engine can determine how to route policy types and policies to the application.
124 :caption: Custom Tutorial Application Service Provider
126 package org.onap.policy.tutorial.tutorial;
128 import java.util.Arrays;
129 import java.util.List;
131 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
132 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
133 import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
135 public class TutorialApplication extends StdXacmlApplicationServiceProvider {
137 private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier();
140 public String applicationName() {
145 public List<String> actionDecisionsSupported() {
146 return Arrays.asList("authorize");
150 public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
151 return Arrays.asList(supportedPolicyType);
155 public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
156 return supportedPolicyType.equals(policyTypeId);
160 protected ToscaPolicyTranslator getTranslator(String type) {
161 // TODO Auto-generated method stub
167 Create A Translation Class that extends the ToscaPolicyTranslator Class
168 ***********************************************************************
169 Please be sure to review the existing translators in the policy/xacml-pdp repo to see if they could
170 be re-used for your policy type. For the tutorial, we will create our own translator.
172 The custom translator is not only responsible for translating Policies derived from the Tutorial
173 Policy Type, but also for translating Decision API Requests/Responses to/from the appropriate XACML
174 requests/response objects the XACML engine understands.
177 :caption: Custom Tutorial Translator Class
179 package org.onap.policy.tutorial.tutorial;
181 import org.onap.policy.models.decisions.concepts.DecisionRequest;
182 import org.onap.policy.models.decisions.concepts.DecisionResponse;
183 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
184 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
185 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
187 import com.att.research.xacml.api.Request;
188 import com.att.research.xacml.api.Response;
190 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
192 public class TutorialTranslator implements ToscaPolicyTranslator {
194 public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
195 // TODO Auto-generated method stub
199 public Request convertRequest(DecisionRequest request) {
200 // TODO Auto-generated method stub
204 public DecisionResponse convertResponse(Response xacmlResponse) {
205 // TODO Auto-generated method stub
211 Implement the TutorialTranslator Methods
212 ****************************************
213 This is the part where knowledge of the XACML OASIS 3.0 specification is required. Please refer to
214 that specification on the many ways to design a XACML Policy.
216 For the tutorial, we will build code that translates the TOSCA Policy into one XACML Policy that matches
217 on the user and action. It will then have one or more rules for each entity and permission combination. The
218 default combining algorithm for the XACML Rules are to "Deny Unless Permit".
220 `See the tutorial example for details on how the translator is implemented <https://github.com/onap/policy-xacml-pdp/blob/master/tutorials/tutorial-xacml-application/src/main/java/org/onap/policy/tutorial/tutorial/TutorialTranslator.java>`_. Note that in the Tutorial Translator, it also shows how a developer could extend the translator to return or act upon obligations, advice and attributes.
223 There are many ways to build the policy based on the attributes. How to do so is a matter of experience and
224 fine tuning using the many options for combining algorithms, target and/or condition matching and the rich set of
227 Use the TutorialTranslator in the TutorialApplication
228 *****************************************************
229 Be sure to go back to the TutorialApplication and create an instance of the translator to return to the
230 StdXacmlApplicationServiceProvider. The StdXacmlApplicationServiceProvider uses the translator to convert
231 a policy when a new policy is deployed to the ONAP XACML PDP Engine. `See the Tutorial Application Example <https://github.com/onap/policy-xacml-pdp/blob/master/tutorials/tutorial-xacml-application/src/main/java/org/onap/policy/tutorial/tutorial/TutorialApplication.java>`_.
234 :caption: Final TutorialApplication Class
238 package org.onap.policy.tutorial.tutorial;
240 import java.util.Arrays;
241 import java.util.List;
242 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
243 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
244 import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
246 public class TutorialApplication extends StdXacmlApplicationServiceProvider {
248 private final ToscaPolicyTypeIdentifier supportedPolicyType =
249 new ToscaPolicyTypeIdentifier("onap.policies.Authorization", "1.0.0");
250 private final TutorialTranslator translator = new TutorialTranslator();
253 public String applicationName() {
258 public List<String> actionDecisionsSupported() {
259 return Arrays.asList("authorize");
263 public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
264 return Arrays.asList(supportedPolicyType);
268 public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
269 return supportedPolicyType.equals(policyTypeId);
273 protected ToscaPolicyTranslator getTranslator(String type) {
279 Create a XACML Request from ONAP Decision Request
280 *************************************************
281 The easiest way to do this is to use the annotations feature from XACML PDP library to create an example XACML
282 request. Then create an instance and simply populate it from an incoming ONAP Decision Request.
285 :caption: Final TutorialApplication Class
287 import com.att.research.xacml.std.annotations.XACMLAction;
288 import com.att.research.xacml.std.annotations.XACMLRequest;
289 import com.att.research.xacml.std.annotations.XACMLResource;
290 import com.att.research.xacml.std.annotations.XACMLSubject;
291 import java.util.Map;
292 import java.util.Map.Entry;
293 import lombok.Getter;
294 import lombok.Setter;
295 import lombok.ToString;
296 import org.onap.policy.models.decisions.concepts.DecisionRequest;
301 @XACMLRequest(ReturnPolicyIdList = true)
302 public class TutorialRequest {
303 @XACMLSubject(includeInResults = true)
304 private String onapName;
306 @XACMLSubject(attributeId = "urn:org:onap:onap-component", includeInResults = true)
307 private String onapComponent;
309 @XACMLSubject(attributeId = "urn:org:onap:onap-instance", includeInResults = true)
310 private String onapInstance;
313 private String action;
315 @XACMLResource(attributeId = "urn:org:onap:tutorial-user", includeInResults = true)
318 @XACMLResource(attributeId = "urn:org:onap:tutorial-entity", includeInResults = true)
319 private String entity;
321 @XACMLResource(attributeId = "urn:org:onap:tutorial-permission", includeInResults = true)
322 private String permission;
327 * @param decisionRequest Incoming
328 * @return TutorialRequest object
330 public static TutorialRequest createRequest(DecisionRequest decisionRequest) {
334 TutorialRequest request = new TutorialRequest();
336 // Add the subject attributes
338 request.onapName = decisionRequest.getOnapName();
339 request.onapComponent = decisionRequest.getOnapComponent();
340 request.onapInstance = decisionRequest.getOnapInstance();
342 // Add the action attribute
344 request.action = decisionRequest.getAction();
346 // Add the resource attributes
348 Map<String, Object> resources = decisionRequest.getResource();
349 for (Entry<String, Object> entrySet : resources.entrySet()) {
350 if ("user".equals(entrySet.getKey())) {
351 request.user = entrySet.getValue().toString();
353 if ("entity".equals(entrySet.getKey())) {
354 request.entity = entrySet.getValue().toString();
356 if ("permission".equals(entrySet.getKey())) {
357 request.permission = entrySet.getValue().toString();
365 `See the Tutorial Request <https://github.com/onap/policy-xacml-pdp/blob/master/tutorials/tutorial-xacml-application/src/main/java/org/onap/policy/tutorial/tutorial/TutorialRequest.java>`_
367 Create a JUnit and use the TestUtils.java class in xacml-test dependency
368 ************************************************************************
369 Be sure to create a JUnit that will test your translator and application code. You can utilize a TestUtils.java
370 class from the policy/xamcl-pdp repo's xacml-test submodule to use some utility methods for building the JUnit test.
372 Build the code and run the JUnit test. Its easiest to run it via a terminal command line using maven commands.
375 :caption: Running Maven Commands
380 Building Docker Image
381 *********************
382 To build a docker image that incorporates your application with the XACML PDP Engine. The XACML PDP Engine
383 must be able to *find* your Java.Service in the classpath. This is easy to do, just create a jar file for your application
384 and copy into the same directory used to startup the XACML PDP.
386 Here is a Dockerfile as an example:
392 FROM onap/policy-xacml-pdp
394 ADD maven/${project.build.finalName}.jar /opt/app/policy/pdpx/lib/${project.build.finalName}.jar
396 RUN mkdir -p /opt/app/policy/pdpx/apps/tutorial
398 COPY --chown=policy:policy xacml.properties /opt/app/policy/pdpx/apps/tutorial
400 Download Tutorial Application Example
401 *************************************
403 If you clone the XACML-PDP repo, the tutorial is included for local testing without building your own.
405 `Tutorial code located in xacml-pdp repo <https://github.com/onap/policy-xacml-pdp/tree/master/tutorials/tutorial-xacml-application>`_
407 There is an example Docker compose script that you can use to run the Policy Framework components locally and test the tutorial out.
409 `Docker compose script <https://github.com/onap/policy-xacml-pdp/blob/master/tutorials/tutorial-xacml-application/src/main/docker/docker-compose.yml>`_
411 In addition, there is a POSTMAN collection available for setting up and running tests against a
412 running instance of ONAP Policy Components (api, pap, dmaap-simulator, tutorial-xacml-pdp).
414 `POSTMAN collection for testing <https://github.com/onap/policy-xacml-pdp/blob/master/tutorials/tutorial-xacml-application/postman/PolicyApplicationTutorial.postman_collection.json>`_