42e3d43e700c7c23f2a5adb14e48d6222c5482a7
[policy/xacml-pdp.git] / applications / common / src / main / java / org / onap / policy / pdp / xacml / application / common / std / StdMatchablePolicyRequest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.pdp.xacml.application.common.std;
24
25 import com.att.research.xacml.api.AttributeValue;
26 import com.att.research.xacml.api.DataType;
27 import com.att.research.xacml.api.DataTypeException;
28 import com.att.research.xacml.api.DataTypeFactory;
29 import com.att.research.xacml.api.Request;
30 import com.att.research.xacml.api.XACML3;
31 import com.att.research.xacml.std.IdentifierImpl;
32 import com.att.research.xacml.std.StdMutableAttribute;
33 import com.att.research.xacml.std.StdMutableRequest;
34 import com.att.research.xacml.std.StdMutableRequestAttributes;
35 import com.att.research.xacml.std.annotations.RequestParser;
36 import com.att.research.xacml.std.annotations.XACMLAction;
37 import com.att.research.xacml.std.annotations.XACMLRequest;
38 import com.att.research.xacml.std.annotations.XACMLSubject;
39 import com.att.research.xacml.util.FactoryException;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.Map;
44 import java.util.Map.Entry;
45 import lombok.Getter;
46 import lombok.NoArgsConstructor;
47 import lombok.Setter;
48 import lombok.ToString;
49 import org.onap.policy.models.decisions.concepts.DecisionRequest;
50 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
51 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 @Getter
56 @Setter
57 @ToString
58 @NoArgsConstructor
59 @XACMLRequest(ReturnPolicyIdList = true)
60 public class StdMatchablePolicyRequest {
61
62     private static final Logger LOGGER = LoggerFactory.getLogger(StdMatchablePolicyRequest.class);
63
64     public static final String POLICY_TYPE_KEY = "policy-type";
65
66     @XACMLSubject(includeInResults = true)
67     private String onapName;
68
69     @XACMLSubject(attributeId = "urn:org:onap:onap-component", includeInResults = true)
70     private String onapComponent;
71
72     @XACMLSubject(attributeId = "urn:org:onap:onap-instance",  includeInResults = true)
73     private String onapInstance;
74
75     @XACMLAction()
76     private String action;
77
78     protected static DataTypeFactory dataTypeFactory        = null;
79
80     protected static synchronized DataTypeFactory getDataTypeFactory() {
81         try {
82             if (dataTypeFactory != null) {
83                 return dataTypeFactory;
84             }
85             dataTypeFactory = DataTypeFactory.newInstance();
86         } catch (FactoryException e) {
87             LOGGER.error("Can't get Data type Factory", e);
88         }
89         return dataTypeFactory;
90     }
91
92     /**
93      * Parses the DecisionRequest into a XAML request.
94      *
95      * @param decisionRequest Input DecisionRequest
96      * @return Request XACML Request object
97      * @throws XacmlApplicationException Exception occurred parsing or creating request
98      */
99     @SuppressWarnings({"rawtypes", "unchecked"})
100     public static Request createInstance(DecisionRequest decisionRequest) throws XacmlApplicationException {
101         //
102         // Create our request object
103         //
104         var request = new StdMatchablePolicyRequest();
105         //
106         // Add the subject attributes
107         //
108         request.onapName = decisionRequest.getOnapName();
109         request.onapComponent = decisionRequest.getOnapComponent();
110         request.onapInstance = decisionRequest.getOnapInstance();
111         //
112         // Add the action attribute
113         //
114         request.action = decisionRequest.getAction();
115         //
116         // Parse the request - we use the annotations to create a
117         // basic XACML request.
118         //
119         Request xacmlRequest;
120         try {
121             xacmlRequest = RequestParser.parseRequest(request);
122         } catch (IllegalAccessException | DataTypeException e) {
123             throw new XacmlApplicationException("Could not parse request ", e);
124         }
125         //
126         // Create an object we can add to
127         //
128         var mutableRequest = new StdMutableRequest(xacmlRequest);
129         var resourceAttributes = new StdMutableRequestAttributes();
130         resourceAttributes.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
131         //
132         // Add the resource attributes
133         //
134         Map<String, Object> resources = decisionRequest.getResource();
135         for (Entry<String, Object> entrySet : resources.entrySet()) {
136             //
137             // Check for special policy-type
138             //
139             String attributeId;
140             if (POLICY_TYPE_KEY.equals(entrySet.getKey())) {
141                 attributeId = ToscaDictionary.ID_RESOURCE_POLICY_TYPE.stringValue();
142             } else {
143                 attributeId = ToscaDictionary.ID_RESOURCE_MATCHABLE + entrySet.getKey();
144             }
145             //
146             // Making an assumption that these fields are matchable.
147             // Its possible we may have to load the policy type model
148             // and use that to validate the fields that are matchable.
149             //
150             try {
151                 if (entrySet.getValue() instanceof Collection) {
152                     addResources(resourceAttributes, (Collection) entrySet.getValue(), attributeId);
153                 } else {
154                     addResources(resourceAttributes, Arrays.asList(entrySet.getValue().toString()), attributeId);
155                 }
156             } catch (DataTypeException e) {
157                 throw new XacmlApplicationException("Failed to add resource ", e);
158             }
159         }
160         mutableRequest.add(resourceAttributes);
161         return mutableRequest;
162     }
163
164     protected static StdMutableRequestAttributes addResources(StdMutableRequestAttributes attributes,
165             Collection<Object> values, String id) throws DataTypeException {
166
167         var factory = getDataTypeFactory();
168         if (factory == null) {
169             return null;
170         }
171         for (Object value : values) {
172             var mutableAttribute    = new StdMutableAttribute();
173             mutableAttribute.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
174             mutableAttribute.setAttributeId(new IdentifierImpl(id));
175             mutableAttribute.setIncludeInResults(true);
176
177             DataType<?> dataTypeExtended    = factory.getDataType(XACML3.ID_DATATYPE_STRING);
178             AttributeValue<?> attributeValue = dataTypeExtended.createAttributeValue(value);
179             Collection<AttributeValue<?>> attributeValues = new ArrayList<>();
180             attributeValues.add(attributeValue);
181             mutableAttribute.setValues(attributeValues);
182
183             attributes.add(mutableAttribute);
184         }
185         return attributes;
186     }
187 }