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.guard;
25 import com.att.research.xacml.api.DataTypeException;
26 import com.att.research.xacml.api.Decision;
27 import com.att.research.xacml.api.Identifier;
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 com.att.research.xacml.api.XACML3;
32 import com.att.research.xacml.std.annotations.RequestParser;
34 import java.util.Collection;
37 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
38 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
39 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
42 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
43 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
45 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
46 import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
53 import org.onap.policy.models.decisions.concepts.DecisionRequest;
54 import org.onap.policy.models.decisions.concepts.DecisionResponse;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
56 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
57 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
58 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
59 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
60 import org.onap.policy.pdp.xacml.application.common.operationshistory.CountRecentOperationsPip;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
64 public class LegacyGuardTranslator implements ToscaPolicyTranslator {
66 private static final Logger LOGGER = LoggerFactory.getLogger(LegacyGuardTranslator.class);
68 private static final String FIELD_GUARD_ACTIVE_START = "guardActiveStart";
69 private static final String FIELD_GUARD_ACTIVE_END = "guardActiveEnd";
70 private static final String FIELD_TARGET = "targets";
72 public LegacyGuardTranslator() {
77 public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
79 // Policy name should be at the root
81 String policyName = toscaPolicy.getMetadata().get("policy-id");
83 // Set it as the policy ID
85 PolicyType newPolicyType = new PolicyType();
86 newPolicyType.setPolicyId(policyName);
88 // Optional description
90 newPolicyType.setDescription(toscaPolicy.getDescription());
92 // There should be a metadata section
94 this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata());
96 // Set the combining rule
98 newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue());
100 // Generate the TargetType - add true if not blacklist
102 newPolicyType.setTarget(this.generateTargetType(toscaPolicy.getProperties(),
103 ! "onap.policies.controlloop.guard.Blacklist".equals(toscaPolicy.getType())));
105 // Now create the Permit Rule
107 RuleType rule = generatePermitRule(policyName, toscaPolicy.getType(), toscaPolicy.getProperties());
109 // Check if we were able to create the rule
112 LOGGER.error("Failed to create rule");
116 // Add the rule to the policy
118 newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
120 // Return our new policy
122 return newPolicyType;
126 public Request convertRequest(DecisionRequest request) {
127 LOGGER.info("Converting Request {}", request);
129 return RequestParser.parseRequest(LegacyGuardPolicyRequest.createInstance(request));
130 } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
131 LOGGER.error("Failed to convert DecisionRequest: {}", e);
134 // TODO throw exception
140 public DecisionResponse convertResponse(Response xacmlResponse) {
141 LOGGER.info("Converting Response {}", xacmlResponse);
142 DecisionResponse decisionResponse = new DecisionResponse();
144 // Iterate through all the results
146 for (Result xacmlResult : xacmlResponse.getResults()) {
150 if (xacmlResult.getDecision() == Decision.PERMIT) {
152 // Just simply return a Permit response
154 decisionResponse.setStatus(Decision.PERMIT.toString());
156 if (xacmlResult.getDecision() == Decision.DENY) {
158 // Just simply return a Deny response
160 decisionResponse.setStatus(Decision.DENY.toString());
162 if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) {
164 // There is no guard policy, so we return a permit
166 decisionResponse.setStatus(Decision.PERMIT.toString());
170 return decisionResponse;
174 * From the TOSCA metadata section, pull in values that are needed into the XACML policy.
176 * @param policy Policy Object to store the metadata
177 * @param map The Metadata TOSCA Map
178 * @return Same Policy Object
179 * @throws ToscaPolicyConversionException If there is something missing from the metadata
181 protected PolicyType fillMetadataSection(PolicyType policy,
182 Map<String, String> map) throws ToscaPolicyConversionException {
183 if (! map.containsKey("policy-id")) {
184 throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-id");
187 // Do nothing here - the XACML PolicyId is used from TOSCA Policy Name field
190 if (! map.containsKey("policy-version")) {
191 throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-version");
194 // Add in the Policy Version
196 policy.setVersion(map.get("policy-version").toString());
201 protected TargetType generateTargetType(Map<String, Object> properties, boolean addTargets) {
203 // Go through potential properties
205 AllOfType allOf = new AllOfType();
206 if (properties.containsKey("actor")) {
207 addMatch(allOf, properties.get("actor"), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR);
209 if (properties.containsKey("recipe")) {
210 addMatch(allOf, properties.get("recipe"), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE);
213 if (properties.containsKey("targets")) {
214 addMatch(allOf, properties.get("targets"), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
217 if (properties.containsKey("clname")) {
218 addMatch(allOf, properties.get("clname"), ToscaDictionary.ID_RESOURCE_GUARD_CLNAME);
223 TargetType target = new TargetType();
224 AnyOfType anyOf = new AnyOfType();
225 anyOf.getAllOf().add(allOf);
226 target.getAnyOf().add(anyOf);
230 private static AllOfType addMatch(AllOfType allOf, Object value, Identifier attributeId) {
231 if (value instanceof String) {
232 if (".*".equals(value.toString())) {
234 // There's no point to even have a match
241 MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
242 XACML3.ID_FUNCTION_STRING_EQUAL,
244 XACML3.ID_DATATYPE_STRING,
246 XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
248 allOf.getMatch().add(match);
252 if (value instanceof Collection) {
254 // TODO support a collection of that attribute
260 private static RuleType generatePermitRule(String policyName, String policyType, Map<String, Object> properties)
261 throws ToscaPolicyConversionException {
263 // Now determine which policy type we are generating
265 if ("onap.policies.controlloop.guard.FrequencyLimiter".equals(policyType)) {
266 return generateFrequencyPermit(policyName, properties);
267 } else if ("onap.policies.controlloop.guard.MinMax".equals(policyType)) {
268 return generateMinMaxPermit(policyName, properties);
269 } else if ("onap.policies.controlloop.guard.Blacklist".equals(policyType)) {
270 return generateBlacklistPermit(policyName, properties);
272 LOGGER.error("Missing policy type in the policy");
276 private static RuleType generateFrequencyPermit(String policyName, Map<String, Object> properties)
277 throws ToscaPolicyConversionException {
279 // See if its possible to generate a count
281 Integer limit = parseInteger(properties.get("limit").toString());
283 LOGGER.error("Must have a limit value for frequency guard policy to be created");
287 // Get the properties that are common among guards
289 String timeWindow = null;
290 if (properties.containsKey("timeWindow")) {
291 Integer intTimeWindow = parseInteger(properties.get("timeWindow").toString());
292 if (intTimeWindow == null) {
293 throw new ToscaPolicyConversionException("timeWindow is not an integer");
295 timeWindow = intTimeWindow.toString();
297 String timeUnits = null;
298 if (properties.containsKey("timeUnits")) {
299 timeUnits = properties.get("timeUnits").toString();
301 String guardActiveStart = null;
302 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
303 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
305 String guardActiveEnd = null;
306 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
307 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
310 // Generate the time in range
312 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
316 final ApplyType countCheck = generateCountCheck(limit, timeWindow, timeUnits);
318 // Now combine into an And
320 ApplyType applyAnd = new ApplyType();
321 applyAnd.setDescription("return true if time range and count checks are true.");
322 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
323 applyAnd.getExpression().add(new ObjectFactory().createApply(timeRange));
324 applyAnd.getExpression().add(new ObjectFactory().createApply(countCheck));
327 // Create our condition
329 final ConditionType condition = new ConditionType();
330 condition.setExpression(new ObjectFactory().createApply(applyAnd));
333 // Now we can create our rule
335 RuleType permit = new RuleType();
336 permit.setDescription("Default is to PERMIT if the policy matches.");
337 permit.setRuleId(policyName + ":rule");
338 permit.setEffect(EffectType.PERMIT);
339 permit.setTarget(new TargetType());
343 permit.setCondition(condition);
345 // TODO Add the advice - Is the request id needed to be returned?
347 // permit.setAdviceExpressions(adviceExpressions);
354 private static RuleType generateMinMaxPermit(String policyName, Map<String, Object> properties) {
356 // Get the properties that are common among guards
358 String guardActiveStart = null;
359 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
360 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
362 String guardActiveEnd = null;
363 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
364 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
367 // Generate the time in range
369 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
371 // See if its possible to generate a count
374 if (properties.containsKey("min")) {
375 min = parseInteger(properties.get("min").toString());
378 if (properties.containsKey("max")) {
379 max = parseInteger(properties.get("max").toString());
381 final ApplyType minApply = generateMinCheck(min);
382 final ApplyType maxApply = generateMaxCheck(max);
384 // Make sure we have at least something to check here,
385 // otherwise there really is no point to this policy.
387 if (timeRange == null && minApply == null && maxApply == null) {
393 RuleType permit = new RuleType();
394 permit.setDescription("Default is to PERMIT if the policy matches.");
395 permit.setRuleId(policyName + ":rule");
396 permit.setEffect(EffectType.PERMIT);
397 permit.setTarget(new TargetType());
399 // Create our condition
401 final ConditionType condition = new ConditionType();
403 // Check if we have all the fields (this can be a little
404 // ugly) but the ultimate goal is to simplify the policy
405 // condition to only check for necessary attributes.
407 ObjectFactory factory = new ObjectFactory();
408 if (timeRange != null && minApply != null && maxApply != null) {
412 ApplyType applyAnd = new ApplyType();
413 applyAnd.setDescription("return true if all the apply's are true.");
414 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
415 applyAnd.getExpression().add(factory.createApply(timeRange));
416 applyAnd.getExpression().add(factory.createApply(minApply));
417 applyAnd.getExpression().add(factory.createApply(maxApply));
419 // Add into the condition
421 condition.setExpression(factory.createApply(applyAnd));
424 // At least one of these applies is null. We need at least
425 // two to require the And apply. Otherwise there is no need
426 // for an outer And apply as the single condition can work
429 if (timeRange != null && minApply == null && maxApply == null) {
431 // Only the time range check is necessary
433 condition.setExpression(factory.createApply(timeRange));
434 } else if (timeRange == null && minApply != null && maxApply == null) {
436 // Only the min check is necessary
438 condition.setExpression(factory.createApply(minApply));
439 } else if (timeRange == null && minApply == null) {
441 // Only the max check is necessary
443 condition.setExpression(factory.createApply(maxApply));
446 // Ok we will need an outer And and have at least the
447 // time range and either min or max check
449 ApplyType applyAnd = new ApplyType();
450 applyAnd.setDescription("return true if all the apply's are true.");
451 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
452 if (timeRange != null) {
453 applyAnd.getExpression().add(factory.createApply(timeRange));
455 if (minApply != null) {
456 applyAnd.getExpression().add(factory.createApply(minApply));
458 if (maxApply != null) {
459 applyAnd.getExpression().add(factory.createApply(maxApply));
462 // Add into the condition
464 condition.setExpression(factory.createApply(applyAnd));
470 permit.setCondition(condition);
472 // TODO Add the advice - Is the request id needed to be returned?
474 // permit.setAdviceExpressions(adviceExpressions);
481 private static RuleType generateBlacklistPermit(String policyName, Map<String, Object> properties) {
485 if (! properties.containsKey(FIELD_TARGET)) {
486 LOGGER.error("Missing target for blacklist policy");
489 final ApplyType targetApply = generateTargetApply(properties.get(FIELD_TARGET));
491 // Get the properties that are common among guards
493 String guardActiveStart = null;
494 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
495 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
497 String guardActiveEnd = null;
498 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
499 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
502 // Generate the time in range
504 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
508 RuleType permit = new RuleType();
509 permit.setDescription("Default is to PERMIT if the policy matches.");
510 permit.setRuleId(policyName + ":rule");
511 permit.setEffect(EffectType.PERMIT);
512 permit.setTarget(new TargetType());
514 // Create our condition
516 ObjectFactory factory = new ObjectFactory();
517 ApplyType innerApply;
518 if (timeRange != null) {
519 ApplyType applyAnd = new ApplyType();
520 applyAnd.setDescription("Combine the timeRange with target to create AND");
521 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
522 applyAnd.getExpression().add(factory.createApply(timeRange));
523 applyAnd.getExpression().add(factory.createApply(targetApply));
525 // Now we need to NOT this so the permit happens
527 ApplyType applyNot = new ApplyType();
528 applyNot.setDescription("This should be false for a permit.");
529 applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
530 applyNot.getExpression().add(factory.createApply(applyAnd));
531 innerApply = applyNot;
534 // Just the target is needed
536 ApplyType applyNot = new ApplyType();
537 applyNot.setDescription("This should be false for a permit.");
538 applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
539 applyNot.getExpression().add(factory.createApply(targetApply));
540 innerApply = applyNot;
543 // Create our condition
545 final ConditionType condition = new ConditionType();
547 // Add into the condition
549 condition.setExpression(factory.createApply(innerApply));
553 permit.setCondition(condition);
557 private static ApplyType generateTimeInRange(String start, String end) {
558 if (start == null || end == null) {
559 LOGGER.warn("Missing time range start {} end {}", start, end);
562 if (start.isEmpty() || end.isEmpty()) {
563 LOGGER.warn("Empty time range start {} end {}", start, end);
567 AttributeDesignatorType designator = new AttributeDesignatorType();
568 designator.setAttributeId(XACML3.ID_ENVIRONMENT_CURRENT_TIME.stringValue());
569 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT.stringValue());
570 designator.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
572 AttributeValueType valueStart = new AttributeValueType();
573 valueStart.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
574 valueStart.getContent().add(start);
576 AttributeValueType valueEnd = new AttributeValueType();
577 valueEnd.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
578 valueEnd.getContent().add(end);
580 ObjectFactory factory = new ObjectFactory();
582 ApplyType applyOneAndOnly = new ApplyType();
583 applyOneAndOnly.setDescription("Unbag the current time");
584 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY.stringValue());
585 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
587 ApplyType applyTimeInRange = new ApplyType();
588 applyTimeInRange.setDescription("return true if current time is in range.");
589 applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RANGE.stringValue());
590 applyTimeInRange.getExpression().add(factory.createApply(applyOneAndOnly));
591 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueStart));
592 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueEnd));
594 return applyTimeInRange;
597 private static ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) {
598 AttributeDesignatorType designator = new AttributeDesignatorType();
599 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT.stringValue());
600 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
601 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
605 String issuer = ToscaDictionary.GUARD_ISSUER_PREFIX
606 + CountRecentOperationsPip.ISSUER_NAME
607 + ":tw:" + timeWindow + ":" + timeUnits;
608 designator.setIssuer(issuer);
610 AttributeValueType valueLimit = new AttributeValueType();
611 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
613 // Yes really use toString(), the marshaller will
614 // throw an exception if this is an integer object
617 valueLimit.getContent().add(limit.toString());
619 ObjectFactory factory = new ObjectFactory();
621 ApplyType applyOneAndOnly = new ApplyType();
622 applyOneAndOnly.setDescription("Unbag the limit");
623 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
624 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
626 ApplyType applyLessThan = new ApplyType();
627 applyLessThan.setDescription("return true if current count is less than.");
628 applyLessThan.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN.stringValue());
629 applyLessThan.getExpression().add(factory.createApply(applyOneAndOnly));
630 applyLessThan.getExpression().add(factory.createAttributeValue(valueLimit));
632 return applyLessThan;
635 private static ApplyType generateMinCheck(Integer min) {
639 AttributeDesignatorType designator = new AttributeDesignatorType();
640 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
641 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
642 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
646 AttributeValueType valueLimit = new AttributeValueType();
647 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
649 // Yes really use toString(), the marshaller will
650 // throw an exception if this is an integer object
653 valueLimit.getContent().add(min.toString());
654 ObjectFactory factory = new ObjectFactory();
656 ApplyType applyOneAndOnly = new ApplyType();
657 applyOneAndOnly.setDescription("Unbag the min");
658 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
659 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
661 ApplyType applyGreaterThanEqual = new ApplyType();
662 applyGreaterThanEqual.setDescription("return true if current count is greater than or equal.");
663 applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue());
664 applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
665 applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
667 return applyGreaterThanEqual;
670 private static ApplyType generateMaxCheck(Integer max) {
674 AttributeDesignatorType designator = new AttributeDesignatorType();
675 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
676 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
677 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
681 AttributeValueType valueLimit = new AttributeValueType();
682 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
684 // Yes really use toString(), the marshaller will
685 // throw an exception if this is an integer object
688 valueLimit.getContent().add(max.toString());
689 ObjectFactory factory = new ObjectFactory();
691 ApplyType applyOneAndOnly = new ApplyType();
692 applyOneAndOnly.setDescription("Unbag the min");
693 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
694 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
696 ApplyType applyLessThanEqual = new ApplyType();
697 applyLessThanEqual.setDescription("return true if current count is less than or equal.");
698 applyLessThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL.stringValue());
699 applyLessThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
700 applyLessThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
702 return applyLessThanEqual;
705 @SuppressWarnings("unchecked")
706 private static ApplyType generateTargetApply(Object targetObject) {
707 ObjectFactory factory = new ObjectFactory();
709 // Create a bag of values
711 ApplyType applyStringBag = new ApplyType();
712 applyStringBag.setDescription("Bag the target values");
713 applyStringBag.setFunctionId(XACML3.ID_FUNCTION_STRING_BAG.stringValue());
714 if (targetObject instanceof Collection) {
715 for (Object target : ((Collection<Object>) targetObject)) {
716 if (! (target instanceof String)) {
717 LOGGER.error("Collection of unsupported objects {}", target.getClass());
720 AttributeValueType value = new AttributeValueType();
721 value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
722 value.getContent().add(target.toString());
723 applyStringBag.getExpression().add(factory.createAttributeValue(value));
725 } else if (targetObject instanceof String) {
726 AttributeValueType value = new AttributeValueType();
727 value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
728 value.getContent().add(targetObject.toString());
729 applyStringBag.getExpression().add(factory.createAttributeValue(value));
731 LOGGER.warn("Unsupported object for target {}", targetObject.getClass());
735 // Create our designator
737 AttributeDesignatorType designator = new AttributeDesignatorType();
738 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.stringValue());
739 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
740 designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
742 // Create apply for our AnyOf
744 ApplyType applyAnyOf = new ApplyType();
745 applyAnyOf.setDescription("Find designator as anyof the possible values");
746 applyAnyOf.setFunctionId(XACML3.ID_FUNCTION_ANY_OF.stringValue());
747 applyAnyOf.getExpression().add(factory.createAttributeDesignator(designator));
748 applyAnyOf.getExpression().add(factory.createApply(applyStringBag));
752 private static Integer parseInteger(String strInteger) {
753 Integer theInt = null;
755 theInt = Integer.parseInt(strInteger);
756 } catch (NumberFormatException e) {
757 LOGGER.warn("Expecting an integer", e);
759 Double dblLimit = Double.parseDouble(strInteger);
760 theInt = dblLimit.intValue();
761 } catch (NumberFormatException e1) {
762 LOGGER.error("Failed to parse expected integer as a double", e);
769 @SuppressWarnings("unused")
770 private static AdviceExpressionsType generateRequestIdAdvice() {
771 AdviceExpressionType adviceExpression = new AdviceExpressionType();
772 adviceExpression.setAppliesTo(EffectType.PERMIT);
773 adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_GUARD.stringValue());
775 AttributeDesignatorType designator = new AttributeDesignatorType();
776 designator.setAttributeId(ToscaDictionary.ID_SUBJECT_GUARD_REQUESTID.stringValue());
777 designator.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
778 designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
780 AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType();
781 assignment.setAttributeId(ToscaDictionary.ID_ADVICE_GUARD_REQUESTID.stringValue());
782 assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
783 assignment.setExpression(new ObjectFactory().createAttributeDesignator(designator));
785 adviceExpression.getAttributeAssignmentExpression().add(assignment);
787 AdviceExpressionsType adviceExpressions = new AdviceExpressionsType();
788 adviceExpressions.getAdviceExpression().add(adviceExpression);
790 return adviceExpressions;