e921dce8ceea85f16fca8de17e2e9aa5d5ac6fe2
[policy/xacml-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2019 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.xacml.pdp.application.optimization;
24
25 import com.att.research.xacml.api.Advice;
26 import com.att.research.xacml.api.AttributeAssignment;
27 import com.att.research.xacml.api.Decision;
28 import com.att.research.xacml.api.Request;
29 import com.att.research.xacml.api.Response;
30 import com.att.research.xacml.api.Result;
31 import java.nio.file.Path;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.List;
37 import java.util.Map;
38 import org.apache.commons.lang3.tuple.Pair;
39 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
40 import org.onap.policy.models.decisions.concepts.DecisionRequest;
41 import org.onap.policy.models.decisions.concepts.DecisionResponse;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
43 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
44 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
45 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
46 import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvider {
51
52     private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplication.class);
53     private static final String STRING_VERSION100 = "1.0.0";
54     private static final String RESOURCE_SUBSCRIBERNAME = "subscriberName";
55
56     private OptimizationPdpApplicationTranslator translator = new OptimizationPdpApplicationTranslator();
57     private List<ToscaPolicyTypeIdentifier> supportedPolicyTypes = new ArrayList<>();
58
59     /**
60      * Constructor.
61      */
62     public OptimizationPdpApplication() {
63         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
64                 "onap.policies.optimization.resource.AffinityPolicy", STRING_VERSION100));
65         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
66                 "onap.policies.optimization.resource.DistancePolicy", STRING_VERSION100));
67         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
68                 "onap.policies.optimization.resource.HpaPolicy", STRING_VERSION100));
69         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
70                 "onap.policies.optimization.resource.OptimizationPolicy", STRING_VERSION100));
71         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
72                 "onap.policies.optimization.resource.PciPolicy", STRING_VERSION100));
73         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
74                 "onap.policies.optimization.service.QueryPolicy", STRING_VERSION100));
75         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
76                 "onap.policies.optimization.service.SubscriberPolicy", STRING_VERSION100));
77         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
78                 "onap.policies.optimization.resource.Vim_fit", STRING_VERSION100));
79         this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(
80                 "onap.policies.optimization.resource.VnfPolicy", STRING_VERSION100));
81     }
82
83     @Override
84     public String applicationName() {
85         return "optimization";
86     }
87
88     @Override
89     public List<String> actionDecisionsSupported() {
90         return Arrays.asList("optimize");
91     }
92
93     @Override
94     public void initialize(Path pathForData, RestServerParameters policyApiParameters)
95             throws XacmlApplicationException {
96         //
97         // Store our API parameters and path for translator so it
98         // can go get Policy Types
99         //
100         this.translator.setPathForData(pathForData);
101         this.translator.setApiRestParameters(policyApiParameters);
102         //
103         // Let our super class do its thing
104         //
105         super.initialize(pathForData, policyApiParameters);
106     }
107
108     @Override
109     public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
110         return Collections.unmodifiableList(supportedPolicyTypes);
111     }
112
113     @Override
114     public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
115         //
116         // For the time being, restrict this if the version isn't known.
117         // Could be too difficult to support changing of versions dynamically.
118         //
119         //
120         // For the time being, restrict this if the version isn't known.
121         // Could be too difficult to support changing of versions dynamically.
122         //
123         for (ToscaPolicyTypeIdentifier supported : this.supportedPolicyTypes) {
124             if (policyTypeId.equals(supported)) {
125                 LOGGER.info("optimization can support {}", supported);
126                 return true;
127             }
128         }
129         return false;
130     }
131
132     @Override
133     public Pair<DecisionResponse, Response> makeDecision(DecisionRequest request,
134             Map<String, String[]> requestQueryParams) {
135         //
136         // Check if there are subject attributes for subscriber
137         //
138         if (hasSubscriberAttributes(request)) {
139             //
140             // We must do an initial request to pull subscriber attributes
141             //
142             LOGGER.info("Request Subscriber attributes");
143             //
144             // Convert the request
145             //
146             DecisionRequest subscriberRequest = new DecisionRequest(request);
147             //
148             // Override the PolicyType to ensure we are only looking at Subscriber Policies
149             //
150             if (subscriberRequest.getResource().containsKey("policy-type")) {
151                 subscriberRequest.getResource().remove("policy-type");
152             }
153             subscriberRequest.getResource().put("policy-type", "onap.policies.optimization.service.SubscriberPolicy");
154             //
155             // Convert to a XacmlRequest and get a decision
156             //
157             Response xacmlResponse = null;
158             try {
159                 xacmlResponse = this.xacmlDecision(OptimizationSubscriberRequest.createInstance(subscriberRequest));
160             } catch (XacmlApplicationException e) {
161                 LOGGER.error("Could not create subscriberName request {}", e);
162             }
163             //
164             // Check the response for subscriber attributes and add them
165             // to the initial request.
166             //
167             if (! addSubscriberAttributes(xacmlResponse, request)) {
168                 LOGGER.error("Failed to get subscriber attributes");
169                 //
170                 // Convert to a DecisionResponse
171                 //
172                 return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse);
173             }
174         }
175         //
176         // Convert to a XacmlRequest
177         //
178         Request xacmlRequest = this.getTranslator().convertRequest(request);
179         //
180         // Now get a decision
181         //
182         Response xacmlResponse = this.xacmlDecision(xacmlRequest);
183         //
184         // Convert to a DecisionResponse
185         //
186         return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse);
187     }
188
189     @Override
190     protected ToscaPolicyTranslator getTranslator(String type) {
191         //
192         // Return translator
193         //
194         return translator;
195     }
196
197     @SuppressWarnings("unchecked")
198     private boolean hasSubscriberAttributes(DecisionRequest request) {
199         return request.getContext() != null
200                 && request.getContext().containsKey(RESOURCE_SUBSCRIBERNAME)
201                 && request.getContext().get(RESOURCE_SUBSCRIBERNAME) instanceof List
202                 && ! ((List<String>) request.getContext().get(RESOURCE_SUBSCRIBERNAME)).isEmpty();
203     }
204
205     private boolean addSubscriberAttributes(Response xacmlResponse, DecisionRequest initialRequest) {
206         //
207         // Should only be one result
208         //
209         for (Result result : xacmlResponse.getResults()) {
210             //
211             // Check the result
212             //
213             if (result.getStatus().isOk() && result.getDecision().equals(Decision.PERMIT)) {
214                 //
215                 // Pull out the advice which has attributes
216                 //
217                 scanAdvice(result.getAssociatedAdvice(), initialRequest);
218                 //
219                 // PLD this is an assumption
220                 //
221                 return true;
222             } else {
223                 LOGGER.error("XACML result not ok {} or Permit {}", result.getStatus(), result.getDecision());
224             }
225         }
226         return false;
227     }
228
229     @SuppressWarnings("unchecked")
230     private void scanAdvice(Collection<Advice> adviceCollection, DecisionRequest initialRequest) {
231         //
232         // There really should only be one advice object
233         //
234         for (Advice advice : adviceCollection) {
235             //
236             // Look for the optimization specific advice
237             //
238             if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.equals(advice.getId())) {
239                 //
240                 // Get the attributes and add them
241                 for (AttributeAssignment attribute : advice.getAttributeAssignments()) {
242                     //
243                     // If this is subscriber role
244                     //
245                     if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.equals(attribute.getAttributeId())) {
246                         ((List<String>) initialRequest.getResource().get("scope")).add(attribute.getAttributeValue()
247                                 .getValue().toString());
248                     }
249                 }
250             } else {
251                 LOGGER.error("Unsupported advice id {}", advice.getId());
252             }
253         }
254     }
255
256 }