Fix optimization bug add coverage plus
[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-2020 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.Setter;
47 import lombok.ToString;
48 import org.onap.policy.models.decisions.concepts.DecisionRequest;
49 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
50 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 @Getter
55 @Setter
56 @ToString
57 @XACMLRequest(ReturnPolicyIdList = true)
58 public class StdMatchablePolicyRequest {
59
60     private static final Logger LOGGER = LoggerFactory.getLogger(StdMatchablePolicyRequest.class);
61
62     public static final String POLICY_TYPE_KEY = "policy-type";
63
64     @XACMLSubject(includeInResults = true)
65     private String onapName;
66
67     @XACMLSubject(attributeId = "urn:org:onap:onap-component", includeInResults = true)
68     private String onapComponent;
69
70     @XACMLSubject(attributeId = "urn:org:onap:onap-instance",  includeInResults = true)
71     private String onapInstance;
72
73     @XACMLAction()
74     private String action;
75
76     protected static DataTypeFactory dataTypeFactory        = null;
77
78     public StdMatchablePolicyRequest() {
79         super();
80     }
81
82     protected static synchronized DataTypeFactory getDataTypeFactory() {
83         try {
84             if (dataTypeFactory != null) {
85                 return dataTypeFactory;
86             }
87             dataTypeFactory = DataTypeFactory.newInstance();
88         } catch (FactoryException e) {
89             LOGGER.error("Can't get Data type Factory: {}", e);
90         }
91         return dataTypeFactory;
92     }
93
94     /**
95      * Parses the DecisionRequest into a XAML request.
96      *
97      * @param decisionRequest Input DecisionRequest
98      * @return Request XACML Request object
99      * @throws XacmlApplicationException Exception occurred parsing or creating request
100      */
101     @SuppressWarnings({"rawtypes", "unchecked"})
102     public static Request createInstance(DecisionRequest decisionRequest) throws XacmlApplicationException {
103         //
104         // Create our request object
105         //
106         StdMatchablePolicyRequest request = new StdMatchablePolicyRequest();
107         //
108         // Add the subject attributes
109         //
110         request.onapName = decisionRequest.getOnapName();
111         request.onapComponent = decisionRequest.getOnapComponent();
112         request.onapInstance = decisionRequest.getOnapInstance();
113         //
114         // Add the action attribute
115         //
116         request.action = decisionRequest.getAction();
117         //
118         // Parse the request - we use the annotations to create a
119         // basic XACML request.
120         //
121         Request xacmlRequest;
122         try {
123             xacmlRequest = RequestParser.parseRequest(request);
124         } catch (IllegalAccessException | DataTypeException e) {
125             throw new XacmlApplicationException("Could not parse request ", e);
126         }
127         //
128         // Create an object we can add to
129         //
130         StdMutableRequest mutableRequest = new StdMutableRequest(xacmlRequest);
131         StdMutableRequestAttributes resourceAttributes = new StdMutableRequestAttributes();
132         resourceAttributes.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
133         //
134         // Add the resource attributes
135         //
136         Map<String, Object> resources = decisionRequest.getResource();
137         for (Entry<String, Object> entrySet : resources.entrySet()) {
138             //
139             // Check for special policy-type
140             //
141             String attributeId;
142             if (POLICY_TYPE_KEY.equals(entrySet.getKey())) {
143                 attributeId = ToscaDictionary.ID_RESOURCE_POLICY_TYPE.stringValue();
144             } else {
145                 attributeId = ToscaDictionary.ID_RESOURCE_MATCHABLE + entrySet.getKey();
146             }
147             //
148             // Making an assumption that these fields are matchable.
149             // Its possible we may have to load the policy type model
150             // and use that to validate the fields that are matchable.
151             //
152             try {
153                 if (entrySet.getValue() instanceof Collection) {
154                     addResources(resourceAttributes, (Collection) entrySet.getValue(), attributeId);
155                 } else {
156                     addResources(resourceAttributes, Arrays.asList(entrySet.getValue().toString()), attributeId);
157                 }
158             } catch (DataTypeException e) {
159                 throw new XacmlApplicationException("Failed to add resource ", e);
160             }
161         }
162         mutableRequest.add(resourceAttributes);
163         return mutableRequest;
164     }
165
166     protected static StdMutableRequestAttributes addResources(StdMutableRequestAttributes attributes,
167             Collection<Object> values, String id) throws DataTypeException {
168
169         DataTypeFactory factory = getDataTypeFactory();
170         if (factory == null) {
171             return null;
172         }
173         for (Object value : values) {
174             StdMutableAttribute mutableAttribute    = new StdMutableAttribute();
175             mutableAttribute.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
176             mutableAttribute.setAttributeId(new IdentifierImpl(id));
177             mutableAttribute.setIncludeInResults(true);
178
179             DataType<?> dataTypeExtended    = factory.getDataType(XACML3.ID_DATATYPE_STRING);
180             AttributeValue<?> attributeValue = dataTypeExtended.createAttributeValue(value);
181             Collection<AttributeValue<?>> attributeValues = new ArrayList<>();
182             attributeValues.add(attributeValue);
183             mutableAttribute.setValues(attributeValues);
184
185             attributes.add(mutableAttribute);
186         }
187         return attributes;
188     }
189 }