Update XACML Tutorial
[policy/parent.git] / docs / xacml / xacml-tutorial.rst
1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2
3 .. _xacmltutorial-label:
4
5 Policy XACML - Custom Application Tutorial
6 ##########################################
7
8 .. toctree::
9    :maxdepth: 3
10
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.
13
14
15 Design a Policy Type
16 ********************
17 Follow :ref:`TOSCA Policy Primer <tosca-label>` for more information. For the tutorial, we will use
18 this example Policy Type in which an ONAP PEP client would like to enforce an action **authorize**
19 for a *user* to execute a *permission* on an *entity*.
20
21 .. literalinclude:: tutorial/app/src/test/resources/tutorial-policy-type.yaml
22   :language: yaml
23   :caption: Example Tutorial Policy Type
24   :linenos:
25
26 We would expect then to be able to create the following policies to allow the demo user to Read/Write
27 an entity called foo, while the audit user can only read the entity called foo. Neither user has Delete
28 permission.
29
30 .. literalinclude:: tutorial/app/src/test/resources/tutorial-policies.yaml
31   :language: yaml
32   :caption: Example Policies Derived From Tutorial Policy Type
33   :linenos:
34
35 Design Decision Request and expected Decision Response
36 ******************************************************
37 For the PEP (Policy Enforcement Point) client applications that call the Decision API, you need
38 to design how the Decision API Request resource fields will be sent via the PEP.
39
40 .. literalinclude:: tutorial/app/src/test/resources/tutorial-decision-request.json
41   :language: JSON
42   :caption: Example Decision Request
43   :linenos:
44
45 For simplicity, this tutorial expects only a *Permit* or *Deny* in the Decision Response. However, one could
46 customize the Decision Response object and send back whatever information is desired.
47
48 .. literalinclude:: tutorial/tutorial-decision-response.json
49   :language: JSON
50   :caption: Example Decision Response
51   :linenos:
52
53 Create A Maven Project
54 **********************
55 This part of the tutorial assumes you understand how to use Eclipse to create a Maven
56 project. Please follow any examples for the Eclipse installation you have to create
57 an empty application. For the tutorial, use groupId *org.onap.policy.tutorial* and artifactId
58 *tutorial*. If you wish to go directly to the source code, please see the
59 :ref:`Download Tutorial Application Example` below to download it.
60
61 .. image:: tutorial/images/eclipse-create-maven.png
62
63 .. image:: tutorial/images/eclipse-maven-project.png
64
65 Be sure to import the policy/xacml-pdp project into Eclipse.
66
67 .. image:: tutorial/images/eclipse-import.png
68
69 Add Dependencies Into Application pom.xml
70 *****************************************
71
72 Here we import the XACML PDP Application common dependency which has the interfaces we need to implement. In addition,
73 we are importing a testing dependency that has common code for producing a JUnit test.
74
75 .. code-block:: java
76   :caption: pom.xml dependencies
77
78     <dependency>
79       <groupId>org.onap.policy.xacml-pdp.applications</groupId>
80       <artifactId>common</artifactId>
81       <version>2.2.2</version>
82     </dependency>
83     <dependency>
84       <groupId>org.onap.policy.xacml-pdp</groupId>
85       <artifactId>xacml-test</artifactId>
86       <version>2.2.2</version>
87       <scope>test</scope>
88     </dependency>
89
90 Create META-INF to expose Java Service
91 **************************************
92 The ONAP XACML PDP Engine will not be able to find the tutorial application unless it has
93 a property file located in src/main/resources/META-INF/services that contains a property file
94 declaring the class that implements the service.
95
96 The name of the file must match **org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider**
97 and the contents of the file is one line **org.onap.policy.tutorial.tutorial.TutorialApplication**.
98
99 .. image:: tutorial/images/eclipse-meta-inf.png
100
101 Create A Java Class That Extends **StdXacmlApplicationServiceProvider**
102 ***********************************************************************
103 You could implement **XacmlApplicationServiceProvider** if you wish, but
104 for simplicity if you just extend **StdXacmlApplicationServiceProvider** you
105 will get a lot of implementation done for your application up front. All
106 that needs to be implemented is providing a custom translator.
107
108 .. image:: tutorial/images/eclipse-inherit-app.png
109
110 .. code-block:: java
111   :caption: Custom Tutorial Application Service Provider
112   :emphasize-lines: 6
113
114   package org.onap.policy.tutorial.tutorial;
115
116   import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
117   import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
118
119   public class TutorialApplication extends StdXacmlApplicationServiceProvider {
120
121         @Override
122         protected ToscaPolicyTranslator getTranslator(String type) {
123                 // TODO Auto-generated method stub
124                 return null;
125         }
126
127   }
128
129 Override Methods for Tutorial
130 *****************************
131 Override these methods to differentiate Tutorial from other applications so that the XACML PDP
132 Engine can determine how to route policy types and policies to the application.
133
134 .. code-block:: java
135   :caption: Custom Tutorial Application Service Provider
136
137   package org.onap.policy.tutorial.tutorial;
138
139   import java.util.Arrays;
140   import java.util.List;
141
142   import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
143   import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
144   import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
145
146   public class TutorialApplication extends StdXacmlApplicationServiceProvider {
147         
148     private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier();
149
150     @Override
151     public String applicationName() {
152         return "tutorial";
153     }
154
155     @Override
156     public List<String> actionDecisionsSupported() {
157         return Arrays.asList("authorize");
158     }
159
160     @Override
161     public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
162         return Arrays.asList(supportedPolicyType);
163     }
164
165     @Override
166     public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
167         return supportedPolicyType.equals(policyTypeId);
168     }
169
170     @Override
171         protected ToscaPolicyTranslator getTranslator(String type) {
172         // TODO Auto-generated method stub
173         return null;
174     }
175
176   }
177
178 Create A Translation Class that extends the ToscaPolicyTranslator Class
179 ***********************************************************************
180 Please be sure to review the existing translators in the policy/xacml-pdp repo to see if they could
181 be re-used for your policy type. For the tutorial, we will create our own translator.
182
183 The custom translator is not only responsible for translating Policies derived from the Tutorial
184 Policy Type, but also for translating Decision API Requests/Responses to/from the appropriate XACML
185 requests/response objects the XACML engine understands.  
186
187 .. code-block:: java
188   :caption: Custom Tutorial Translator Class
189
190   package org.onap.policy.tutorial.tutorial;
191
192   import org.onap.policy.models.decisions.concepts.DecisionRequest;
193   import org.onap.policy.models.decisions.concepts.DecisionResponse;
194   import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
195   import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
196   import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
197
198   import com.att.research.xacml.api.Request;
199   import com.att.research.xacml.api.Response;
200
201   import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
202
203   public class TutorialTranslator implements ToscaPolicyTranslator {
204
205     public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
206         // TODO Auto-generated method stub
207         return null;
208     }
209
210     public Request convertRequest(DecisionRequest request) {
211         // TODO Auto-generated method stub
212         return null;
213     }
214
215     public DecisionResponse convertResponse(Response xacmlResponse) {
216         // TODO Auto-generated method stub
217         return null;
218     }
219
220   }
221
222 Implement the TutorialTranslator Methods
223 ****************************************
224 This is the part where knowledge of the XACML OASIS 3.0 specification is required. Please refer to
225 that specification on the many ways to design a XACML Policy.
226
227 For the tutorial, we will build code that translates the TOSCA Policy into one XACML Policy that matches
228 on the user and action. It will then have one or more rules for each entity and permission combination. The
229 default combining algorithm for the XACML Rules are to "Deny Unless Permit".
230
231 .. Note::
232   There are many ways to build the policy based on the attributes. How to do so is a matter of experience and
233   fine tuning using the many options for combining algorithms, target and/or condition matching and the rich set of
234   functions available.
235
236 Here is one implementation example:
237
238 .. literalinclude:: tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialTranslator.java
239   :caption: Example Translator Implementation
240   :linenos:
241
242 Use the TutorialTranslator in the TutorialApplication
243 *****************************************************
244 Be sure to go back to the TutorialApplication and create an instance of the translator to return to the
245 StdXacmlApplicationServiceProvider. The StdXacmlApplicationServiceProvider uses the translator to convert
246 a policy when a new policy is deployed to the ONAP XACML PDP Engine.
247
248 .. code-block:: java
249   :caption: Final TutorialApplication Class
250   :linenos:
251   :emphasize-lines: 37
252
253   package org.onap.policy.tutorial.tutorial;
254
255   import java.util.Arrays;
256   import java.util.List;
257
258   import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
259   import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
260   import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
261
262   public class TutorialApplication extends StdXacmlApplicationServiceProvider {
263         
264     private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier();
265     private final TutorialTranslator translator = new TutorialTranslator();
266
267     @Override
268     public String applicationName() {
269         return "tutorial";
270     }
271
272     @Override
273     public List<String> actionDecisionsSupported() {
274         return Arrays.asList("authorize");
275     }
276
277     @Override
278     public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
279         return Arrays.asList(supportedPolicyType);
280     }
281
282     @Override
283     public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
284         return supportedPolicyType.equals(policyTypeId);
285     }
286
287     @Override
288     protected ToscaPolicyTranslator getTranslator(String type) {
289         return translator;
290      }
291
292   }
293
294 Create a XACML Request from ONAP Decision Request
295 *************************************************
296 The easiest way to do this is to use the annotations feature from XACML PDP library to create an example XACML
297 request. Then create an instance and simply populate it from an incoming ONAP Decision Request.
298
299 .. image: tutorial/images/eclipse-create-request.png
300
301 .. literalinclude:: tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialRequest.java
302   :caption: Example Decision Request to Decision Response Implementation
303   :linenos:
304
305
306 Create xacml.properties for the XACML PDP engine to use
307 *******************************************************
308 In the applications *src/test/resources* directory, create a xacml.properties file that will be used by the embedded
309 XACML PDP Engine when loading.
310
311 .. literalinclude:: tutorial/app/src/test/resources/xacml.properties
312   :caption: Example xacml.properties file
313   :linenos:
314   :emphasize-lines: 20, 25
315
316 Create a JUnit and use the TestUtils.java class in xacml-test dependency
317 ************************************************************************
318 Using Eclipse, create a JUnit and be sure to add a setup() method stub. Here you will be utilizing a TestUtils.java
319 class from the policy/xamcl-pdp repo's xacml-test submodule to use some utility methods for building the JUnit test.
320
321 .. image: tutorial/images/eclipse-junit-create.png
322
323 Copy the TOSCA Policy Type :download:`link <tutorial/app/src/test/resources/tutorial-policy-type.yaml>` and the TOSCA Policies :download:`link <tutorial/app/src/test/resources/tutorial-policies.yaml>`
324 into the src/test/resources directory.
325
326 We will create a temporary folder which is used by the **StdXacmlApplicationServiceProvider** to store working copies of policies as they are loaded
327 into the application.
328
329 .. literalinclude:: tutorial/app/src/test/java/org/onap/policy/tutorial/tutorial/TutorialApplicationTest.java
330   :caption: Example Translator Implementation
331   :linenos:
332
333 Run the JUnit test. Its easiest to run it via a terminal command line using maven commands.
334
335
336 .. code-block:: bash
337    :caption: Running Maven Commands
338    :linenos:
339
340    > mvn clean install
341
342 Building Docker Image
343 *********************
344 Once you have created enough JUnit tests that test the TutorialTranslator.java and TutorialRequest.java classes, you are ready to now make your
345 application build a docker image that incorporates your application with the XACML PDP Engine. The XACML PDP Engine
346 must be able to *find* your Java.Service in the classpath. This is easy to do, just create a jar file for your application
347 and copy into the same directory used to startup the XACML PDP.
348
349 Here is a Dockerfile as an example:
350
351 .. literalinclude:: tutorial/app/src/main/docker/Dockerfile
352   :caption: Dockerfile
353   :linenos:
354
355 Download Tutorial Application Example
356 *************************************
357
358 If you don't wish to use Eclipse, or go through the steps outlined above. The tutorial is
359 available for download:
360
361 :download:`Download tutorial tar <tutorial/tutorial.tar>`
362
363 After you tar xf tutorial.jar, you can import it into Eclipse or your favorite editor. Or simply
364 use a terminal command line to build, test and run the tutorial.
365
366 In addition, there is a POSTMAN collection available for setting up and running tests against a
367 running instance of ONAP Policy Components (api, pap, dmaap-simulator, tutorial-xacml-pdp).
368
369 :download:`Download tutorial POSTMAN Collection <tutorial/PolicyApplicationTutorial.postman_collection.json>`
370