2 * ============LICENSE_START=======================================================
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
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";
56 private OptimizationPdpApplicationTranslator translator = new OptimizationPdpApplicationTranslator();
57 private List<ToscaPolicyTypeIdentifier> supportedPolicyTypes = new ArrayList<>();
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));
84 public String applicationName() {
85 return "optimization";
89 public List<String> actionDecisionsSupported() {
90 return Arrays.asList("optimize");
94 public void initialize(Path pathForData, RestServerParameters policyApiParameters)
95 throws XacmlApplicationException {
97 // Store our API parameters and path for translator so it
98 // can go get Policy Types
100 this.translator.setPathForData(pathForData);
101 this.translator.setApiRestParameters(policyApiParameters);
103 // Let our super class do its thing
105 super.initialize(pathForData, policyApiParameters);
109 public synchronized List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
110 return Collections.unmodifiableList(supportedPolicyTypes);
114 public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
116 // For the time being, restrict this if the version isn't known.
117 // Could be too difficult to support changing of versions dynamically.
120 // For the time being, restrict this if the version isn't known.
121 // Could be too difficult to support changing of versions dynamically.
123 for (ToscaPolicyTypeIdentifier supported : this.supportedPolicyTypes) {
124 if (policyTypeId.equals(supported)) {
125 LOGGER.info("optimization can support {}", supported);
133 public Pair<DecisionResponse, Response> makeDecision(DecisionRequest request,
134 Map<String, String[]> requestQueryParams) {
136 // Check if there are subject attributes for subscriber
138 if (hasSubscriberAttributes(request)) {
140 // We must do an initial request to pull subscriber attributes
142 LOGGER.info("Request Subscriber attributes");
144 // Convert the request
146 DecisionRequest subscriberRequest = new DecisionRequest(request);
148 // Override the PolicyType to ensure we are only looking at Subscriber Policies
150 if (subscriberRequest.getResource().containsKey("policy-type")) {
151 subscriberRequest.getResource().remove("policy-type");
153 subscriberRequest.getResource().put("policy-type", "onap.policies.optimization.service.SubscriberPolicy");
155 // Convert to a XacmlRequest and get a decision
157 Response xacmlResponse = null;
159 xacmlResponse = this.xacmlDecision(OptimizationSubscriberRequest.createInstance(subscriberRequest));
160 } catch (XacmlApplicationException e) {
161 LOGGER.error("Could not create subscriberName request {}", e);
164 // Check the response for subscriber attributes and add them
165 // to the initial request.
167 if (! addSubscriberAttributes(xacmlResponse, request)) {
168 LOGGER.error("Failed to get subscriber attributes");
170 // Convert to a DecisionResponse
172 return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse);
176 // Convert to a XacmlRequest
178 Request xacmlRequest = this.getTranslator().convertRequest(request);
180 // Now get a decision
182 Response xacmlResponse = this.xacmlDecision(xacmlRequest);
184 // Convert to a DecisionResponse
186 return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse);
190 protected ToscaPolicyTranslator getTranslator(String type) {
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();
205 private boolean addSubscriberAttributes(Response xacmlResponse, DecisionRequest initialRequest) {
207 // Should only be one result
209 for (Result result : xacmlResponse.getResults()) {
213 if (result.getStatus().isOk() && result.getDecision().equals(Decision.PERMIT)) {
215 // Pull out the advice which has attributes
217 scanAdvice(result.getAssociatedAdvice(), initialRequest);
219 // PLD this is an assumption
223 LOGGER.error("XACML result not ok {} or Permit {}", result.getStatus(), result.getDecision());
229 @SuppressWarnings("unchecked")
230 private void scanAdvice(Collection<Advice> adviceCollection, DecisionRequest initialRequest) {
232 // There really should only be one advice object
234 for (Advice advice : adviceCollection) {
236 // Look for the optimization specific advice
238 if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.equals(advice.getId())) {
240 // Get the attributes and add them
241 for (AttributeAssignment attribute : advice.getAttributeAssignments()) {
243 // If this is subscriber role
245 if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.equals(attribute.getAttributeId())) {
246 ((List<String>) initialRequest.getResource().get("scope")).add(attribute.getAttributeValue()
247 .getValue().toString());
251 LOGGER.error("Unsupported advice id {}", advice.getId());