Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 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-dev-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/tutorial-policy-type.yaml |
| 22 | :language: JSON |
| 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 |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 27 | an entity called foo, while the audit user can only read the entity called foo. Neither user has Delete |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 28 | permission. |
| 29 | |
| 30 | .. literalinclude:: tutorial/tutorial-policies.yaml |
| 31 | :language: JSON |
| 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/tutorial-decision-request.json |
| 41 | :language: JSON |
| 42 | :caption: Example Decision Request |
| 43 | :linenos: |
| 44 | |
| 45 | For simplicity, we expect only a *Permit* or *Deny* in the Decision Response. |
| 46 | |
| 47 | .. literalinclude:: tutorial/tutorial-decision-response.json |
| 48 | :language: JSON |
| 49 | :caption: Example Decision Response |
| 50 | :linenos: |
| 51 | |
| 52 | Create A Maven Project |
| 53 | ********************** |
| 54 | This part of the tutorial assumes you understand how to use Eclipse to create a Maven |
| 55 | project. Please follow any examples for the Eclipse installation you have to create |
| 56 | an empty application. For the tutorial, use groupId *org.onap.policy.tutorial* and artifactId |
| 57 | *tutorial*. |
| 58 | |
| 59 | .. image:: tutorial/images/eclipse-create-maven.png |
| 60 | |
| 61 | .. image:: tutorial/images/eclipse-maven-project.png |
| 62 | |
| 63 | Be sure to import the policy/xacml-pdp project into Eclipse. |
| 64 | |
| 65 | .. image:: tutorial/images/eclipse-import.png |
| 66 | |
| 67 | Add Dependencies Into Application pom.xml |
| 68 | ***************************************** |
| 69 | |
| 70 | .. code-block:: java |
| 71 | :caption: pom.xml dependencies |
| 72 | |
| 73 | <dependency> |
| 74 | <groupId>org.onap.policy.xacml-pdp.applications</groupId> |
| 75 | <artifactId>common</artifactId> |
| 76 | <version>2.1.0-SNAPSHOT</version> |
| 77 | </dependency> |
| 78 | |
| 79 | Create META-INF to expose Java Service |
| 80 | ************************************** |
| 81 | The ONAP XACML PDP Engine will not be able to find the tutorial application unless it has |
| 82 | a property file located in src/main/resources/META-INF/services that contains a property file |
| 83 | declaring the class that implements the service. |
| 84 | |
| 85 | The name of the file must match **org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider** |
| 86 | and the contents of the file is one line **org.onap.policy.tutorial.tutorial.TutorialApplication**. |
| 87 | |
| 88 | .. image:: tutorial/images/eclipse-meta-inf.png |
| 89 | |
| 90 | Create A Java Class That Extends **StdXacmlApplicationServiceProvider** |
| 91 | *********************************************************************** |
| 92 | You could implement **XacmlApplicationServiceProvider** if you wish, but |
| 93 | for simplicity if you just extend **StdXacmlApplicationServiceProvider** you |
| 94 | will get a lot of implementation done for your application up front. All |
| 95 | that needs to be implemented is providing a custom translator. |
| 96 | |
| 97 | .. image:: tutorial/images/eclipse-inherit-app.png |
| 98 | |
| 99 | .. code-block:: java |
| 100 | :caption: Custom Tutorial Application Service Provider |
| 101 | :emphasize-lines: 6 |
| 102 | |
| 103 | package org.onap.policy.tutorial.tutorial; |
| 104 | |
| 105 | import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; |
| 106 | import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider; |
| 107 | |
| 108 | public class TutorialApplication extends StdXacmlApplicationServiceProvider { |
| 109 | |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 110 | @Override |
| 111 | protected ToscaPolicyTranslator getTranslator(String type) { |
| 112 | // TODO Auto-generated method stub |
| 113 | return null; |
| 114 | } |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 115 | |
| 116 | } |
| 117 | |
| 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. |
| 122 | |
| 123 | .. code-block:: java |
| 124 | :caption: Custom Tutorial Application Service Provider |
| 125 | |
| 126 | package org.onap.policy.tutorial.tutorial; |
| 127 | |
| 128 | import java.util.Arrays; |
| 129 | import java.util.List; |
| 130 | |
| 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; |
| 134 | |
| 135 | public class TutorialApplication extends StdXacmlApplicationServiceProvider { |
| 136 | |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 137 | private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier(); |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 138 | |
| 139 | @Override |
| 140 | public String applicationName() { |
| 141 | return "tutorial"; |
| 142 | } |
| 143 | |
| 144 | @Override |
| 145 | public List<String> actionDecisionsSupported() { |
| 146 | return Arrays.asList("authorize"); |
| 147 | } |
| 148 | |
| 149 | @Override |
| 150 | public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() { |
| 151 | return Arrays.asList(supportedPolicyType); |
| 152 | } |
| 153 | |
| 154 | @Override |
| 155 | public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) { |
| 156 | return supportedPolicyType.equals(policyTypeId); |
| 157 | } |
| 158 | |
| 159 | @Override |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 160 | protected ToscaPolicyTranslator getTranslator(String type) { |
| 161 | // TODO Auto-generated method stub |
| 162 | return null; |
| 163 | } |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 164 | |
| 165 | } |
| 166 | |
| 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. |
| 171 | |
| 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. |
| 175 | |
| 176 | .. code-block:: java |
| 177 | :caption: Custom Tutorial Translator Class |
| 178 | |
| 179 | package org.onap.policy.tutorial.tutorial; |
| 180 | |
| 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; |
| 186 | |
| 187 | import com.att.research.xacml.api.Request; |
| 188 | import com.att.research.xacml.api.Response; |
| 189 | |
| 190 | import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; |
| 191 | |
| 192 | public class TutorialTranslator implements ToscaPolicyTranslator { |
| 193 | |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 194 | public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { |
| 195 | // TODO Auto-generated method stub |
| 196 | return null; |
| 197 | } |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 198 | |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 199 | public Request convertRequest(DecisionRequest request) { |
| 200 | // TODO Auto-generated method stub |
| 201 | return null; |
| 202 | } |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 203 | |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 204 | public DecisionResponse convertResponse(Response xacmlResponse) { |
| 205 | // TODO Auto-generated method stub |
| 206 | return null; |
| 207 | } |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 208 | |
| 209 | } |
| 210 | |
| 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. |
| 215 | |
| 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". |
| 219 | |
| 220 | .. Note:: |
| 221 | There are many ways to build the policy based on the attributes. How to do so is a matter of experience and |
| 222 | fine tuning using the many options for combining algorithms, target and/or condition matching and the rich set of |
| 223 | functions available. |
| 224 | |
| 225 | Here is one implementation example: |
| 226 | |
| 227 | .. literalinclude:: tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialTranslator.java |
| 228 | :caption: Example Translator Implementation |
| 229 | :linenos: |
| 230 | |
| 231 | Use the TutorialTranslator in the TutorialApplication |
| 232 | ***************************************************** |
| 233 | Be sure to go back to the TutorialApplication and create an instance of the translator to return to the |
| 234 | StdXacmlApplicationServiceProvider. The StdXacmlApplicationServiceProvider uses the translator to convert |
| 235 | a policy when a new policy is deployed to the ONAP XACML PDP Engine. |
| 236 | |
| 237 | .. code-block:: java |
| 238 | :caption: Final TutorialApplication Class |
| 239 | :linenos: |
| 240 | :emphasize-lines: 37 |
| 241 | |
| 242 | package org.onap.policy.tutorial.tutorial; |
| 243 | |
| 244 | import java.util.Arrays; |
| 245 | import java.util.List; |
| 246 | |
| 247 | import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; |
| 248 | import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; |
| 249 | import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider; |
| 250 | |
| 251 | public class TutorialApplication extends StdXacmlApplicationServiceProvider { |
| 252 | |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 253 | private final ToscaPolicyTypeIdentifier supportedPolicyType = new ToscaPolicyTypeIdentifier(); |
| 254 | private final TutorialTranslator translator = new TutorialTranslator(); |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 255 | |
| 256 | @Override |
| 257 | public String applicationName() { |
| 258 | return "tutorial"; |
| 259 | } |
| 260 | |
| 261 | @Override |
| 262 | public List<String> actionDecisionsSupported() { |
| 263 | return Arrays.asList("authorize"); |
| 264 | } |
| 265 | |
| 266 | @Override |
| 267 | public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() { |
| 268 | return Arrays.asList(supportedPolicyType); |
| 269 | } |
| 270 | |
| 271 | @Override |
| 272 | public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) { |
| 273 | return supportedPolicyType.equals(policyTypeId); |
| 274 | } |
| 275 | |
| 276 | @Override |
Pamela Dragosh | 0b3efb8 | 2019-06-18 12:29:38 -0400 | [diff] [blame] | 277 | protected ToscaPolicyTranslator getTranslator(String type) { |
| 278 | return translator; |
| 279 | } |
Pamela Dragosh | 0ac4c6a | 2019-06-11 10:55:04 -0400 | [diff] [blame] | 280 | |
| 281 | } |
| 282 | |
| 283 | Create a XACML Request from ONAP Decision Request |
| 284 | ************************************************* |
| 285 | The easiest way to do this is to use the annotations feature from XACML PDP library to create an example XACML |
| 286 | request. Then create an instance and simply populate it from an incoming ONAP Decision Request. |
| 287 | |
| 288 | .. image: tutorial/images/eclipse-create-request.png |
| 289 | |
| 290 | .. literalinclude:: tutorial/app/src/main/java/org/onap/policy/tutorial/tutorial/TutorialRequest.java |
| 291 | :caption: Example Decision Request to Decision Response Implementation |
| 292 | :linenos: |
| 293 | |
| 294 | |
| 295 | Create xacml.properties for the XACML PDP engine to use |
| 296 | ******************************************************* |
| 297 | In the applications *src/test/resources* directory, create a xacml.properties file that will be used by the embedded |
| 298 | XACML PDP Engine when loading. |
| 299 | |
| 300 | .. literalinclude:: tutorial/tutorial-xacml.properties |
| 301 | :caption: Example xacml.properties file |
| 302 | :linenos: |
| 303 | :emphasize-lines: 20, 25 |
| 304 | |
| 305 | Create a JUnit and use the TestUtils.java class in application/common |
| 306 | ********************************************************************* |
| 307 | Using Eclipse, create a JUnit and be sure to add a setup() method stub. Here you will be utilizing a TestUtils.java |
| 308 | class from the policy/xamcl-pdp repo's application/common submodule to use some utility methods for building the JUnit test. |
| 309 | |
| 310 | .. image: tutorial/images/eclipse-junit-create.png |
| 311 | |
| 312 | Copy the TOSCA Policy Type :download:`link <tutorial/tutorial-policy-type.yaml>` and the TOSCA Policies :download:`link <tutorial/tutorial-policies.yaml>` |
| 313 | into the src/test/resources directory. |
| 314 | |
| 315 | We will create a temporary folder which is used by the **StdXacmlApplicationServiceProvider** to store working copies of policies as they are loaded |
| 316 | into the application. |
| 317 | |
| 318 | .. literalinclude:: tutorial/app/src/test/java/org/onap/policy/tutorial/tutorial/TutorialApplicationTest.java |
| 319 | :caption: Example Translator Implementation |
| 320 | :linenos: |
| 321 | |
| 322 | Run the JUnit test!! |
| 323 | |
| 324 | Where To Go From Here |
| 325 | ********************* |
| 326 | Once you have created enough JUnit tests that test the TutorialTranslator.java and TutorialRequest.java classes, you are ready to now make your |
| 327 | application available to the ONAP XACML PDP Engine. These steps are covered in another tutorial. |
| 328 | |
| 329 | |
| 330 | |