2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.xacml.pdp.application.optimization;
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;
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;
50 public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvider {
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 private static final String RESOURCE_POLICYTYPE = "policy-type";
56 private static final String RESOURCE_SCOPE = "scope";
58 public static final String POLICYTYPE_AFFINITY = "onap.policies.optimization.resource.AffinityPolicy";
59 public static final String POLICYTYPE_SUBSCRIBER = "onap.policies.optimization.service.SubscriberPolicy";
60 public static final String POLICYTYPE_DISTANCE = "onap.policies.optimization.resource.DistancePolicy";
61 public static final String POLICYTYPE_HPA = "onap.policies.optimization.resource.HpaPolicy";
62 public static final String POLICYTYPE_OPTIMIZATION = "onap.policies.optimization.resource.OptimizationPolicy";
63 public static final String POLICYTYPE_PCI = "onap.policies.optimization.resource.PciPolicy";
64 public static final String POLICYTYPE_QUERY = "onap.policies.optimization.service.QueryPolicy";
65 public static final String POLICYTYPE_VIMFIT = "onap.policies.optimization.resource.Vim_fit";
66 public static final String POLICYTYPE_VNF = "onap.policies.optimization.resource.VnfPolicy";
68 private OptimizationPdpApplicationTranslator translator = new OptimizationPdpApplicationTranslator();
69 private List<ToscaPolicyTypeIdentifier> supportedPolicyTypes = new ArrayList<>();
74 public OptimizationPdpApplication() {
75 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_AFFINITY, STRING_VERSION100));
76 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_DISTANCE, STRING_VERSION100));
77 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_HPA, STRING_VERSION100));
78 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_OPTIMIZATION, STRING_VERSION100));
79 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_PCI, STRING_VERSION100));
80 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_QUERY, STRING_VERSION100));
81 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_SUBSCRIBER, STRING_VERSION100));
82 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_VIMFIT, STRING_VERSION100));
83 this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_VNF, STRING_VERSION100));
87 public String applicationName() {
88 return "optimization";
92 public List<String> actionDecisionsSupported() {
93 return Arrays.asList("optimize");
97 public void initialize(Path pathForData, RestServerParameters policyApiParameters)
98 throws XacmlApplicationException {
100 // Store our API parameters and path for translator so it
101 // can go get Policy Types
103 this.translator.setPathForData(pathForData);
104 this.translator.setApiRestParameters(policyApiParameters);
106 // Let our super class do its thing
108 super.initialize(pathForData, policyApiParameters);
112 public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
113 return Collections.unmodifiableList(supportedPolicyTypes);
117 public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
119 // For the time being, restrict this if the version isn't known.
120 // Could be too difficult to support changing of versions dynamically.
123 // For the time being, restrict this if the version isn't known.
124 // Could be too difficult to support changing of versions dynamically.
126 for (ToscaPolicyTypeIdentifier supported : this.supportedPolicyTypes) {
127 if (policyTypeId.equals(supported)) {
128 LOGGER.info("optimization can support {}", supported);
136 public Pair<DecisionResponse, Response> makeDecision(DecisionRequest request,
137 Map<String, String[]> requestQueryParams) {
139 // In case we have a subcriber policy
141 Response xacmlSubscriberResponse = null;
143 // Check if there are subject attributes for subscriber
145 if (hasSubscriberAttributes(request)) {
147 // We must do an initial request to pull subscriber attributes
149 LOGGER.info("Request Subscriber attributes");
151 // Convert the request
153 DecisionRequest subscriberRequest = new DecisionRequest(request);
155 // Override the PolicyType to ensure we are only looking at Subscriber Policies
157 if (subscriberRequest.getResource().containsKey(RESOURCE_POLICYTYPE)) {
158 subscriberRequest.getResource().remove(RESOURCE_POLICYTYPE);
160 subscriberRequest.getResource().put(RESOURCE_POLICYTYPE, POLICYTYPE_SUBSCRIBER);
162 // Convert to a XacmlRequest and get a decision
165 xacmlSubscriberResponse =
166 this.xacmlDecision(OptimizationSubscriberRequest.createInstance(subscriberRequest));
167 } catch (XacmlApplicationException e) {
168 LOGGER.error("Could not create subscriberName request {}", e);
171 // Check the response for subscriber attributes and add them
172 // to the initial request.
174 if (xacmlSubscriberResponse != null && ! addSubscriberAttributes(xacmlSubscriberResponse, request)) {
175 LOGGER.error("Failed to get subscriber role attributes");
177 // Convert to a DecisionResponse
179 return Pair.of(this.getTranslator().convertResponse(xacmlSubscriberResponse), xacmlSubscriberResponse);
183 // Convert to a XacmlRequest
185 Request xacmlRequest = this.getTranslator().convertRequest(request);
187 // Now get a decision
189 Response xacmlResponse = this.xacmlDecision(xacmlRequest);
191 // Convert to a DecisionResponse
193 Pair<DecisionResponse, Response> returnPair = Pair.of(this.getTranslator().convertResponse(xacmlResponse),
196 // Add back in advice from subscriber
198 if (xacmlSubscriberResponse != null) {
199 addSubscriberAdvice(xacmlSubscriberResponse, returnPair.getLeft());
205 protected ToscaPolicyTranslator getTranslator(String type) {
212 @SuppressWarnings("unchecked")
213 private boolean hasSubscriberAttributes(DecisionRequest request) {
214 return request.getContext() != null
215 && request.getContext().containsKey(RESOURCE_SUBSCRIBERNAME)
216 && request.getContext().get(RESOURCE_SUBSCRIBERNAME) instanceof List
217 && ! ((List<String>) request.getContext().get(RESOURCE_SUBSCRIBERNAME)).isEmpty();
220 private boolean addSubscriberAttributes(Response xacmlResponse, DecisionRequest initialRequest) {
222 // This has multiple results right now because of how the attributes were added to the
223 // request. That will have to be fixed in the future, for now find the Permit result
224 // and add the role attributes as they will be used in the next request.
226 for (Result result : xacmlResponse.getResults()) {
230 if (result.getStatus().isOk() && result.getDecision().equals(Decision.PERMIT)) {
232 // Pull out the advice which has attributes
234 scanAdvice(result.getAssociatedAdvice(), initialRequest);
236 // PLD this is an assumption that all is good
240 LOGGER.error("XACML result not ok {} or Permit {}", result.getStatus(), result.getDecision());
246 private void addSubscriberAdvice(Response xacmlResponse, DecisionResponse response) {
248 // Again find the Permit result
250 for (Result result : xacmlResponse.getResults()) {
254 if (result.getStatus().isOk() && Decision.PERMIT.equals(result.getDecision())) {
255 this.translator.scanAdvice(result.getAssociatedAdvice(), response);
261 @SuppressWarnings("unchecked")
262 private void scanAdvice(Collection<Advice> adviceCollection, DecisionRequest initialRequest) {
264 // There really should only be one advice object
266 for (Advice advice : adviceCollection) {
268 // Look for the optimization specific advice
270 if (! ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.equals(advice.getId())) {
271 LOGGER.error("Unsupported advice id {}", advice.getId());
275 // Get the attributes and add them
277 for (AttributeAssignment attribute : advice.getAttributeAssignments()) {
279 // If this is subscriber role
281 if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.equals(attribute.getAttributeId())) {
282 ((List<String>) initialRequest.getResource().get(RESOURCE_SCOPE))
283 .add(attribute.getAttributeValue().getValue().toString());