Add tutorial example for multi-decisions
[policy/xacml-pdp.git] / tutorials / tutorial-xacml-application / src / main / java / org / onap / policy / tutorial / tutorial / TutorialRequest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ============LICENSE_END=========================================================
17  */
18
19 package org.onap.policy.tutorial.tutorial;
20
21 import com.att.research.xacml.api.DataTypeException;
22 import com.att.research.xacml.api.Identifier;
23 import com.att.research.xacml.api.Request;
24 import com.att.research.xacml.api.XACML3;
25 import com.att.research.xacml.std.IdentifierImpl;
26 import com.att.research.xacml.std.StdAttributeValue;
27 import com.att.research.xacml.std.StdMutableAttribute;
28 import com.att.research.xacml.std.StdMutableRequest;
29 import com.att.research.xacml.std.StdMutableRequestAttributes;
30 import com.att.research.xacml.std.StdMutableRequestReference;
31 import com.att.research.xacml.std.StdRequestAttributesReference;
32 import com.att.research.xacml.std.annotations.RequestParser;
33 import com.att.research.xacml.std.annotations.XACMLAction;
34 import com.att.research.xacml.std.annotations.XACMLRequest;
35 import com.att.research.xacml.std.annotations.XACMLResource;
36 import com.att.research.xacml.std.annotations.XACMLSubject;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Map.Entry;
40 import lombok.Getter;
41 import lombok.Setter;
42 import lombok.ToString;
43 import org.onap.policy.models.decisions.concepts.DecisionRequest;
44
45 @Getter
46 @Setter
47 @ToString
48 @XACMLRequest(ReturnPolicyIdList = true)
49 public class TutorialRequest {
50     public static final Identifier ATTRIBUTE_ID_MULTIID = new IdentifierImpl("urn:org:onap:tutorial-multi-id");
51     public static final Identifier ATTRIBUTE_ID_USER = new IdentifierImpl("urn:org:onap:tutorial-user");
52     public static final Identifier ATTRIBUTE_ID_ENTITY = new IdentifierImpl("urn:org:onap:tutorial-entity");
53     public static final Identifier ATTRIBUTE_ID_PERMISSION = new IdentifierImpl("urn:org:onap:tutorial-permission");
54     //
55     // For use with a multi request
56     //
57     private static final StdRequestAttributesReference refSubjects = new StdRequestAttributesReference("subjects1");
58     private static final StdRequestAttributesReference refActions = new StdRequestAttributesReference("actions1");
59     //
60     // Excluding from results to demonstrate control as to which attributes can be returned.
61     //
62     @XACMLSubject(includeInResults = false)
63     private String onapName;
64
65     @XACMLSubject(attributeId = "urn:org:onap:onap-component", includeInResults = false)
66     private String onapComponent;
67
68     @XACMLSubject(attributeId = "urn:org:onap:onap-instance", includeInResults = false)
69     private String onapInstance;
70
71     @XACMLAction
72     private String action;
73
74     //
75     // Including in results to demonstrate control as to which attributes can be returned.
76     //
77     @XACMLResource(attributeId = "urn:org:onap:tutorial-user", includeInResults = true)
78     private String user;
79
80     @XACMLResource(attributeId = "urn:org:onap:tutorial-entity", includeInResults = true)
81     private String entity;
82
83     @XACMLResource(attributeId = "urn:org:onap:tutorial-permission", includeInResults = true)
84     private String permission;
85
86     /**
87      * createRequest.
88      *
89      * @param decisionRequest Incoming
90      * @return Request XACML Request object
91      * @throws DataTypeException DataTypeException
92      * @throws IllegalAccessException IllegalAccessException
93      */
94     @SuppressWarnings("unchecked")
95     public static Request createRequest(DecisionRequest decisionRequest)
96             throws IllegalAccessException, DataTypeException {
97         //
98         // Create our object
99         //
100         var request = new TutorialRequest();
101         //
102         // Add the subject attributes
103         //
104         request.onapName = decisionRequest.getOnapName();
105         request.onapComponent = decisionRequest.getOnapComponent();
106         request.onapInstance = decisionRequest.getOnapInstance();
107         //
108         // Add the action attribute
109         //
110         request.action = decisionRequest.getAction();
111         //
112         // Add the resource attributes
113         //
114         Map<String, Object> resources = decisionRequest.getResource();
115         //
116         // Check if this is a multi-request
117         //
118         if (resources.containsKey("users")) {
119             //
120             // Setup the multi-request
121             //
122             return buildMultiRequest(request, (List<Object>) resources.get("users"));
123         }
124         //
125         // Continue as a single request
126         //
127         for (Entry<String, Object> entrySet : resources.entrySet()) {
128             if ("user".equals(entrySet.getKey())) {
129                 request.user = entrySet.getValue().toString();
130             }
131             if ("entity".equals(entrySet.getKey())) {
132                 request.entity = entrySet.getValue().toString();
133             }
134             if ("permission".equals(entrySet.getKey())) {
135                 request.permission = entrySet.getValue().toString();
136             }
137         }
138
139         return RequestParser.parseRequest(request);
140     }
141
142     @SuppressWarnings("unchecked")
143     protected static Request buildMultiRequest(TutorialRequest existingRequest, List<Object> users)
144             throws IllegalAccessException, DataTypeException {
145         //
146         // Create a single request absorbing the existing attributes, we will copy
147         // them over and assign them an ID.
148         //
149         StdMutableRequest singleRequest = new StdMutableRequest(RequestParser.parseRequest(existingRequest));
150         //
151         // Copy the attributes and assign ID's
152         //
153         StdMutableRequest multiRequest = addMultiRequestIds(singleRequest);
154         //
155         // Iterate and add in the requests
156         //
157         users.forEach(user -> addUser(multiRequest, (Map<String, Object>) user));
158         //
159         // Done
160         //
161         return multiRequest;
162     }
163
164     protected static StdMutableRequest addMultiRequestIds(StdMutableRequest singleRequest) {
165         StdMutableRequest multiRequest = new StdMutableRequest();
166         singleRequest.getRequestAttributes().forEach(attributes -> {
167             StdMutableRequestAttributes newAttributes = new StdMutableRequestAttributes();
168             if (attributes.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
169                 newAttributes.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT);
170                 newAttributes.setXmlId(refSubjects.getReferenceId());
171             } else if (attributes.getCategory().equals(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION)) {
172                 newAttributes.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);
173                 newAttributes.setXmlId(refActions.getReferenceId());
174             }
175             attributes.getAttributes().forEach(newAttributes::add);
176             multiRequest.add(newAttributes);
177         });
178         return multiRequest;
179     }
180
181     protected static void addUser(StdMutableRequest multiRequest, Map<String, Object> user) {
182         StdMutableRequestAttributes attributes = new StdMutableRequestAttributes();
183         attributes.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
184         for (Entry<String, Object> entrySet : user.entrySet()) {
185             StdAttributeValue<String> value =
186                     new StdAttributeValue<>(XACML3.ID_DATATYPE_STRING, entrySet.getValue().toString());
187             StdMutableAttribute attribute = new StdMutableAttribute();
188             attribute.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
189             attribute.setIncludeInResults(true);
190             attribute.addValue(value);
191             if ("multiId".equals(entrySet.getKey())) {
192                 attributes.setXmlId(entrySet.getValue().toString());
193                 attribute.setAttributeId(ATTRIBUTE_ID_MULTIID);
194             } else if ("user".equals(entrySet.getKey())) {
195                 attribute.setAttributeId(ATTRIBUTE_ID_USER);
196             } else if ("entity".equals(entrySet.getKey())) {
197                 attribute.setAttributeId(ATTRIBUTE_ID_ENTITY);
198             } else if ("permission".equals(entrySet.getKey())) {
199                 attribute.setAttributeId(ATTRIBUTE_ID_PERMISSION);
200             } else {
201                 throw new IllegalArgumentException("Unknown request attribute given");
202             }
203             attributes.add(attribute);
204         }
205         //
206         // Add the attributes to the Multi-Request
207         //
208         multiRequest.add(attributes);
209         //
210         // Create the references
211         //
212         StdRequestAttributesReference attributesReference = new StdRequestAttributesReference(attributes.getXmlId());
213         StdMutableRequestReference reference = new StdMutableRequestReference();
214         reference.add(refSubjects);
215         reference.add(refActions);
216         reference.add(attributesReference);
217         //
218         // Add the reference to this request
219         //
220         multiRequest.add(reference);
221     }
222 }