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";
71 private static final String DESC_DEFAULT = "Default is to PERMIT if the policy matches.";
72 private static final String ID_RULE = ":rule";
74 public LegacyGuardTranslator() {
79 public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
81 // Policy name should be at the root
83 String policyName = toscaPolicy.getMetadata().get("policy-id");
85 // Set it as the policy ID
87 PolicyType newPolicyType = new PolicyType();
88 newPolicyType.setPolicyId(policyName);
90 // Optional description
92 newPolicyType.setDescription(toscaPolicy.getDescription());
94 // There should be a metadata section
96 this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata());
98 // Set the combining rule
100 newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue());
102 // Generate the TargetType - add true if not blacklist
104 newPolicyType.setTarget(this.generateTargetType(toscaPolicy.getProperties(),
105 ! "onap.policies.controlloop.guard.Blacklist".equals(toscaPolicy.getType())));
107 // Now create the Permit Rule
109 RuleType rule = generatePermitRule(policyName, toscaPolicy.getType(), toscaPolicy.getProperties());
111 // Check if we were able to create the rule
114 LOGGER.error("Failed to create rule");
118 // Add the rule to the policy
120 newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
122 // Return our new policy
124 return newPolicyType;
128 public Request convertRequest(DecisionRequest request) {
129 LOGGER.info("Converting Request {}", request);
131 return RequestParser.parseRequest(LegacyGuardPolicyRequest.createInstance(request));
132 } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
133 LOGGER.error("Failed to convert DecisionRequest: {}", e);
136 // TODO throw exception
142 public DecisionResponse convertResponse(Response xacmlResponse) {
143 LOGGER.info("Converting Response {}", xacmlResponse);
144 DecisionResponse decisionResponse = new DecisionResponse();
146 // Iterate through all the results
148 for (Result xacmlResult : xacmlResponse.getResults()) {
152 if (xacmlResult.getDecision() == Decision.PERMIT) {
154 // Just simply return a Permit response
156 decisionResponse.setStatus(Decision.PERMIT.toString());
158 if (xacmlResult.getDecision() == Decision.DENY) {
160 // Just simply return a Deny response
162 decisionResponse.setStatus(Decision.DENY.toString());
164 if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) {
166 // There is no guard policy, so we return a permit
168 decisionResponse.setStatus(Decision.PERMIT.toString());
172 return decisionResponse;
176 * From the TOSCA metadata section, pull in values that are needed into the XACML policy.
178 * @param policy Policy Object to store the metadata
179 * @param map The Metadata TOSCA Map
180 * @return Same Policy Object
181 * @throws ToscaPolicyConversionException If there is something missing from the metadata
183 protected PolicyType fillMetadataSection(PolicyType policy,
184 Map<String, String> map) throws ToscaPolicyConversionException {
185 if (! map.containsKey("policy-id")) {
186 throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-id");
189 // Do nothing here - the XACML PolicyId is used from TOSCA Policy Name field
192 if (! map.containsKey("policy-version")) {
193 throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-version");
196 // Add in the Policy Version
198 policy.setVersion(map.get("policy-version"));
203 protected TargetType generateTargetType(Map<String, Object> properties, boolean addTargets) {
205 // Go through potential properties
207 AllOfType allOf = new AllOfType();
208 if (properties.containsKey("actor")) {
209 addMatch(allOf, properties.get("actor"), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR);
211 if (properties.containsKey("recipe")) {
212 addMatch(allOf, properties.get("recipe"), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE);
214 if (addTargets && properties.containsKey(FIELD_TARGET)) {
215 addMatch(allOf, properties.get(FIELD_TARGET), 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(DESC_DEFAULT);
337 permit.setRuleId(policyName + ID_RULE);
338 permit.setEffect(EffectType.PERMIT);
339 permit.setTarget(new TargetType());
343 permit.setCondition(condition);
350 private static RuleType generateMinMaxPermit(String policyName, Map<String, Object> properties) {
352 // Get the properties that are common among guards
354 String guardActiveStart = null;
355 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
356 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
358 String guardActiveEnd = null;
359 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
360 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
363 // Generate the time in range
365 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
367 // See if its possible to generate a count
370 if (properties.containsKey("min")) {
371 min = parseInteger(properties.get("min").toString());
374 if (properties.containsKey("max")) {
375 max = parseInteger(properties.get("max").toString());
377 final ApplyType minApply = generateMinCheck(min);
378 final ApplyType maxApply = generateMaxCheck(max);
380 // Make sure we have at least something to check here,
381 // otherwise there really is no point to this policy.
383 if (timeRange == null && minApply == null && maxApply == null) {
389 RuleType permit = new RuleType();
390 permit.setDescription(DESC_DEFAULT);
391 permit.setRuleId(policyName + ID_RULE);
392 permit.setEffect(EffectType.PERMIT);
393 permit.setTarget(new TargetType());
395 // Create the condition
397 permit.setCondition(createCondition(timeRange, minApply, maxApply));
404 private static ConditionType createCondition(ApplyType timeRange, ApplyType minApply, ApplyType maxApply) {
405 final ConditionType condition = new ConditionType();
407 // Check if we have all the fields (this can be a little
408 // ugly) but the ultimate goal is to simplify the policy
409 // condition to only check for necessary attributes.
411 ObjectFactory factory = new ObjectFactory();
412 if (timeRange != null && minApply != null && maxApply != null) {
416 ApplyType applyAnd = new ApplyType();
417 applyAnd.setDescription("return true if all the apply's are true.");
418 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
419 applyAnd.getExpression().add(factory.createApply(timeRange));
420 applyAnd.getExpression().add(factory.createApply(minApply));
421 applyAnd.getExpression().add(factory.createApply(maxApply));
423 // Add into the condition
425 condition.setExpression(factory.createApply(applyAnd));
430 // At least one of these applies is null. We need at least
431 // two to require the And apply. Otherwise there is no need
432 // for an outer And apply as the single condition can work
435 if (timeRange != null && minApply == null && maxApply == null) {
437 // Only the time range check is necessary
439 condition.setExpression(factory.createApply(timeRange));
440 } else if (timeRange == null && minApply != null && maxApply == null) {
442 // Only the min check is necessary
444 condition.setExpression(factory.createApply(minApply));
445 } else if (timeRange == null && minApply == null) {
447 // Only the max check is necessary
449 condition.setExpression(factory.createApply(maxApply));
452 // Ok we will need an outer And and have at least the
453 // time range and either min or max check
455 ApplyType applyAnd = new ApplyType();
456 applyAnd.setDescription("return true if all the apply's are true.");
457 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
458 if (timeRange != null) {
459 applyAnd.getExpression().add(factory.createApply(timeRange));
461 if (minApply != null) {
462 applyAnd.getExpression().add(factory.createApply(minApply));
464 if (maxApply != null) {
465 applyAnd.getExpression().add(factory.createApply(maxApply));
468 // Add into the condition
470 condition.setExpression(factory.createApply(applyAnd));
475 private static RuleType generateBlacklistPermit(String policyName, Map<String, Object> properties) {
479 if (! properties.containsKey(FIELD_TARGET)) {
480 LOGGER.error("Missing target for blacklist policy");
483 final ApplyType targetApply = generateTargetApply(properties.get(FIELD_TARGET));
485 // Get the properties that are common among guards
487 String guardActiveStart = null;
488 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
489 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
491 String guardActiveEnd = null;
492 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
493 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
496 // Generate the time in range
498 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
502 RuleType permit = new RuleType();
503 permit.setDescription(DESC_DEFAULT);
504 permit.setRuleId(policyName + ID_RULE);
505 permit.setEffect(EffectType.PERMIT);
506 permit.setTarget(new TargetType());
508 // Create our condition
510 ObjectFactory factory = new ObjectFactory();
511 ApplyType innerApply;
512 if (timeRange != null) {
513 ApplyType applyAnd = new ApplyType();
514 applyAnd.setDescription("Combine the timeRange with target to create AND");
515 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
516 applyAnd.getExpression().add(factory.createApply(timeRange));
517 applyAnd.getExpression().add(factory.createApply(targetApply));
519 // Now we need to NOT this so the permit happens
521 ApplyType applyNot = new ApplyType();
522 applyNot.setDescription("This should be false for a permit.");
523 applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
524 applyNot.getExpression().add(factory.createApply(applyAnd));
525 innerApply = applyNot;
528 // Just the target is needed
530 ApplyType applyNot = new ApplyType();
531 applyNot.setDescription("This should be false for a permit.");
532 applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
533 applyNot.getExpression().add(factory.createApply(targetApply));
534 innerApply = applyNot;
537 // Create our condition
539 final ConditionType condition = new ConditionType();
541 // Add into the condition
543 condition.setExpression(factory.createApply(innerApply));
547 permit.setCondition(condition);
551 private static ApplyType generateTimeInRange(String start, String end) {
552 if (start == null || end == null) {
553 LOGGER.warn("Missing time range start {} end {}", start, end);
556 if (start.isEmpty() || end.isEmpty()) {
557 LOGGER.warn("Empty time range start {} end {}", start, end);
561 AttributeDesignatorType designator = new AttributeDesignatorType();
562 designator.setAttributeId(XACML3.ID_ENVIRONMENT_CURRENT_TIME.stringValue());
563 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT.stringValue());
564 designator.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
566 AttributeValueType valueStart = new AttributeValueType();
567 valueStart.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
568 valueStart.getContent().add(start);
570 AttributeValueType valueEnd = new AttributeValueType();
571 valueEnd.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
572 valueEnd.getContent().add(end);
574 ObjectFactory factory = new ObjectFactory();
576 ApplyType applyOneAndOnly = new ApplyType();
577 applyOneAndOnly.setDescription("Unbag the current time");
578 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY.stringValue());
579 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
581 ApplyType applyTimeInRange = new ApplyType();
582 applyTimeInRange.setDescription("return true if current time is in range.");
583 applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RANGE.stringValue());
584 applyTimeInRange.getExpression().add(factory.createApply(applyOneAndOnly));
585 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueStart));
586 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueEnd));
588 return applyTimeInRange;
591 private static ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) {
592 AttributeDesignatorType designator = new AttributeDesignatorType();
593 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT.stringValue());
594 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
595 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
599 String issuer = ToscaDictionary.GUARD_ISSUER_PREFIX
600 + CountRecentOperationsPip.ISSUER_NAME
601 + ":tw:" + timeWindow + ":" + timeUnits;
602 designator.setIssuer(issuer);
604 AttributeValueType valueLimit = new AttributeValueType();
605 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
607 // Yes really use toString(), the marshaller will
608 // throw an exception if this is an integer object
611 valueLimit.getContent().add(limit.toString());
613 ObjectFactory factory = new ObjectFactory();
615 ApplyType applyOneAndOnly = new ApplyType();
616 applyOneAndOnly.setDescription("Unbag the limit");
617 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
618 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
620 ApplyType applyLessThan = new ApplyType();
621 applyLessThan.setDescription("return true if current count is less than.");
622 applyLessThan.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN.stringValue());
623 applyLessThan.getExpression().add(factory.createApply(applyOneAndOnly));
624 applyLessThan.getExpression().add(factory.createAttributeValue(valueLimit));
626 return applyLessThan;
629 private static ApplyType generateMinCheck(Integer min) {
633 AttributeDesignatorType designator = new AttributeDesignatorType();
634 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
635 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
636 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
640 AttributeValueType valueLimit = new AttributeValueType();
641 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
643 // Yes really use toString(), the marshaller will
644 // throw an exception if this is an integer object
647 valueLimit.getContent().add(min.toString());
648 ObjectFactory factory = new ObjectFactory();
650 ApplyType applyOneAndOnly = new ApplyType();
651 applyOneAndOnly.setDescription("Unbag the min");
652 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
653 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
655 ApplyType applyGreaterThanEqual = new ApplyType();
656 applyGreaterThanEqual.setDescription("return true if current count is greater than or equal.");
657 applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue());
658 applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
659 applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
661 return applyGreaterThanEqual;
664 private static ApplyType generateMaxCheck(Integer max) {
668 AttributeDesignatorType designator = new AttributeDesignatorType();
669 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
670 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
671 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
675 AttributeValueType valueLimit = new AttributeValueType();
676 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
678 // Yes really use toString(), the marshaller will
679 // throw an exception if this is an integer object
682 valueLimit.getContent().add(max.toString());
683 ObjectFactory factory = new ObjectFactory();
685 ApplyType applyOneAndOnly = new ApplyType();
686 applyOneAndOnly.setDescription("Unbag the min");
687 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
688 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
690 ApplyType applyLessThanEqual = new ApplyType();
691 applyLessThanEqual.setDescription("return true if current count is less than or equal.");
692 applyLessThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL.stringValue());
693 applyLessThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
694 applyLessThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
696 return applyLessThanEqual;
699 @SuppressWarnings("unchecked")
700 private static ApplyType generateTargetApply(Object targetObject) {
701 ObjectFactory factory = new ObjectFactory();
703 // Create a bag of values
705 ApplyType applyStringBag = new ApplyType();
706 applyStringBag.setDescription("Bag the target values");
707 applyStringBag.setFunctionId(XACML3.ID_FUNCTION_STRING_BAG.stringValue());
708 if (targetObject instanceof Collection) {
709 for (Object target : ((Collection<Object>) targetObject)) {
710 if (! (target instanceof String)) {
711 LOGGER.error("Collection of unsupported objects {}", target.getClass());
714 AttributeValueType value = new AttributeValueType();
715 value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
716 value.getContent().add(target.toString());
717 applyStringBag.getExpression().add(factory.createAttributeValue(value));
719 } else if (targetObject instanceof String) {
720 AttributeValueType value = new AttributeValueType();
721 value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
722 value.getContent().add(targetObject.toString());
723 applyStringBag.getExpression().add(factory.createAttributeValue(value));
725 LOGGER.warn("Unsupported object for target {}", targetObject.getClass());
729 // Create our designator
731 AttributeDesignatorType designator = new AttributeDesignatorType();
732 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.stringValue());
733 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
734 designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
736 // Create apply for our AnyOf
738 ApplyType applyAnyOf = new ApplyType();
739 applyAnyOf.setDescription("Find designator as anyof the possible values");
740 applyAnyOf.setFunctionId(XACML3.ID_FUNCTION_ANY_OF.stringValue());
741 applyAnyOf.getExpression().add(factory.createAttributeDesignator(designator));
742 applyAnyOf.getExpression().add(factory.createApply(applyStringBag));
746 private static Integer parseInteger(String strInteger) {
747 Integer theInt = null;
749 theInt = Integer.parseInt(strInteger);
750 } catch (NumberFormatException e) {
751 LOGGER.warn("Expecting an integer", e);
753 Double dblLimit = Double.parseDouble(strInteger);
754 theInt = dblLimit.intValue();
755 } catch (NumberFormatException e1) {
756 LOGGER.error("Failed to parse expected integer as a double", e);
763 @SuppressWarnings("unused")
764 private static AdviceExpressionsType generateRequestIdAdvice() {
765 AdviceExpressionType adviceExpression = new AdviceExpressionType();
766 adviceExpression.setAppliesTo(EffectType.PERMIT);
767 adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_GUARD.stringValue());
769 AttributeDesignatorType designator = new AttributeDesignatorType();
770 designator.setAttributeId(ToscaDictionary.ID_SUBJECT_GUARD_REQUESTID.stringValue());
771 designator.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
772 designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
774 AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType();
775 assignment.setAttributeId(ToscaDictionary.ID_ADVICE_GUARD_REQUESTID.stringValue());
776 assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
777 assignment.setExpression(new ObjectFactory().createAttributeDesignator(designator));
779 adviceExpression.getAttributeAssignmentExpression().add(assignment);
781 AdviceExpressionsType adviceExpressions = new AdviceExpressionsType();
782 adviceExpressions.getAdviceExpression().add(adviceExpression);
784 return adviceExpressions;