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);
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(DESC_DEFAULT);
395 permit.setRuleId(policyName + ID_RULE);
396 permit.setEffect(EffectType.PERMIT);
397 permit.setTarget(new TargetType());
399 // Create the condition
401 permit.setCondition(createCondition(timeRange, minApply, maxApply));
403 // TODO Add the advice - Is the request id needed to be returned?
405 // permit . setAdviceExpressions (adviceExpressions)
412 private static ConditionType createCondition(ApplyType timeRange, ApplyType minApply, ApplyType maxApply) {
413 final ConditionType condition = new ConditionType();
415 // Check if we have all the fields (this can be a little
416 // ugly) but the ultimate goal is to simplify the policy
417 // condition to only check for necessary attributes.
419 ObjectFactory factory = new ObjectFactory();
420 if (timeRange != null && minApply != null && maxApply != null) {
424 ApplyType applyAnd = new ApplyType();
425 applyAnd.setDescription("return true if all the apply's are true.");
426 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
427 applyAnd.getExpression().add(factory.createApply(timeRange));
428 applyAnd.getExpression().add(factory.createApply(minApply));
429 applyAnd.getExpression().add(factory.createApply(maxApply));
431 // Add into the condition
433 condition.setExpression(factory.createApply(applyAnd));
438 // At least one of these applies is null. We need at least
439 // two to require the And apply. Otherwise there is no need
440 // for an outer And apply as the single condition can work
443 if (timeRange != null && minApply == null && maxApply == null) {
445 // Only the time range check is necessary
447 condition.setExpression(factory.createApply(timeRange));
448 } else if (timeRange == null && minApply != null && maxApply == null) {
450 // Only the min check is necessary
452 condition.setExpression(factory.createApply(minApply));
453 } else if (timeRange == null && minApply == null) {
455 // Only the max check is necessary
457 condition.setExpression(factory.createApply(maxApply));
460 // Ok we will need an outer And and have at least the
461 // time range and either min or max check
463 ApplyType applyAnd = new ApplyType();
464 applyAnd.setDescription("return true if all the apply's are true.");
465 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
466 if (timeRange != null) {
467 applyAnd.getExpression().add(factory.createApply(timeRange));
469 if (minApply != null) {
470 applyAnd.getExpression().add(factory.createApply(minApply));
472 if (maxApply != null) {
473 applyAnd.getExpression().add(factory.createApply(maxApply));
476 // Add into the condition
478 condition.setExpression(factory.createApply(applyAnd));
483 private static RuleType generateBlacklistPermit(String policyName, Map<String, Object> properties) {
487 if (! properties.containsKey(FIELD_TARGET)) {
488 LOGGER.error("Missing target for blacklist policy");
491 final ApplyType targetApply = generateTargetApply(properties.get(FIELD_TARGET));
493 // Get the properties that are common among guards
495 String guardActiveStart = null;
496 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
497 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
499 String guardActiveEnd = null;
500 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
501 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
504 // Generate the time in range
506 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
510 RuleType permit = new RuleType();
511 permit.setDescription(DESC_DEFAULT);
512 permit.setRuleId(policyName + ID_RULE);
513 permit.setEffect(EffectType.PERMIT);
514 permit.setTarget(new TargetType());
516 // Create our condition
518 ObjectFactory factory = new ObjectFactory();
519 ApplyType innerApply;
520 if (timeRange != null) {
521 ApplyType applyAnd = new ApplyType();
522 applyAnd.setDescription("Combine the timeRange with target to create AND");
523 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
524 applyAnd.getExpression().add(factory.createApply(timeRange));
525 applyAnd.getExpression().add(factory.createApply(targetApply));
527 // Now we need to NOT this so the permit happens
529 ApplyType applyNot = new ApplyType();
530 applyNot.setDescription("This should be false for a permit.");
531 applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
532 applyNot.getExpression().add(factory.createApply(applyAnd));
533 innerApply = applyNot;
536 // Just the target is needed
538 ApplyType applyNot = new ApplyType();
539 applyNot.setDescription("This should be false for a permit.");
540 applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
541 applyNot.getExpression().add(factory.createApply(targetApply));
542 innerApply = applyNot;
545 // Create our condition
547 final ConditionType condition = new ConditionType();
549 // Add into the condition
551 condition.setExpression(factory.createApply(innerApply));
555 permit.setCondition(condition);
559 private static ApplyType generateTimeInRange(String start, String end) {
560 if (start == null || end == null) {
561 LOGGER.warn("Missing time range start {} end {}", start, end);
564 if (start.isEmpty() || end.isEmpty()) {
565 LOGGER.warn("Empty time range start {} end {}", start, end);
569 AttributeDesignatorType designator = new AttributeDesignatorType();
570 designator.setAttributeId(XACML3.ID_ENVIRONMENT_CURRENT_TIME.stringValue());
571 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT.stringValue());
572 designator.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
574 AttributeValueType valueStart = new AttributeValueType();
575 valueStart.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
576 valueStart.getContent().add(start);
578 AttributeValueType valueEnd = new AttributeValueType();
579 valueEnd.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
580 valueEnd.getContent().add(end);
582 ObjectFactory factory = new ObjectFactory();
584 ApplyType applyOneAndOnly = new ApplyType();
585 applyOneAndOnly.setDescription("Unbag the current time");
586 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY.stringValue());
587 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
589 ApplyType applyTimeInRange = new ApplyType();
590 applyTimeInRange.setDescription("return true if current time is in range.");
591 applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RANGE.stringValue());
592 applyTimeInRange.getExpression().add(factory.createApply(applyOneAndOnly));
593 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueStart));
594 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueEnd));
596 return applyTimeInRange;
599 private static ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) {
600 AttributeDesignatorType designator = new AttributeDesignatorType();
601 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT.stringValue());
602 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
603 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
607 String issuer = ToscaDictionary.GUARD_ISSUER_PREFIX
608 + CountRecentOperationsPip.ISSUER_NAME
609 + ":tw:" + timeWindow + ":" + timeUnits;
610 designator.setIssuer(issuer);
612 AttributeValueType valueLimit = new AttributeValueType();
613 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
615 // Yes really use toString(), the marshaller will
616 // throw an exception if this is an integer object
619 valueLimit.getContent().add(limit.toString());
621 ObjectFactory factory = new ObjectFactory();
623 ApplyType applyOneAndOnly = new ApplyType();
624 applyOneAndOnly.setDescription("Unbag the limit");
625 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
626 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
628 ApplyType applyLessThan = new ApplyType();
629 applyLessThan.setDescription("return true if current count is less than.");
630 applyLessThan.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN.stringValue());
631 applyLessThan.getExpression().add(factory.createApply(applyOneAndOnly));
632 applyLessThan.getExpression().add(factory.createAttributeValue(valueLimit));
634 return applyLessThan;
637 private static ApplyType generateMinCheck(Integer min) {
641 AttributeDesignatorType designator = new AttributeDesignatorType();
642 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
643 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
644 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
648 AttributeValueType valueLimit = new AttributeValueType();
649 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
651 // Yes really use toString(), the marshaller will
652 // throw an exception if this is an integer object
655 valueLimit.getContent().add(min.toString());
656 ObjectFactory factory = new ObjectFactory();
658 ApplyType applyOneAndOnly = new ApplyType();
659 applyOneAndOnly.setDescription("Unbag the min");
660 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
661 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
663 ApplyType applyGreaterThanEqual = new ApplyType();
664 applyGreaterThanEqual.setDescription("return true if current count is greater than or equal.");
665 applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue());
666 applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
667 applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
669 return applyGreaterThanEqual;
672 private static ApplyType generateMaxCheck(Integer max) {
676 AttributeDesignatorType designator = new AttributeDesignatorType();
677 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
678 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
679 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
683 AttributeValueType valueLimit = new AttributeValueType();
684 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
686 // Yes really use toString(), the marshaller will
687 // throw an exception if this is an integer object
690 valueLimit.getContent().add(max.toString());
691 ObjectFactory factory = new ObjectFactory();
693 ApplyType applyOneAndOnly = new ApplyType();
694 applyOneAndOnly.setDescription("Unbag the min");
695 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
696 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
698 ApplyType applyLessThanEqual = new ApplyType();
699 applyLessThanEqual.setDescription("return true if current count is less than or equal.");
700 applyLessThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL.stringValue());
701 applyLessThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
702 applyLessThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
704 return applyLessThanEqual;
707 @SuppressWarnings("unchecked")
708 private static ApplyType generateTargetApply(Object targetObject) {
709 ObjectFactory factory = new ObjectFactory();
711 // Create a bag of values
713 ApplyType applyStringBag = new ApplyType();
714 applyStringBag.setDescription("Bag the target values");
715 applyStringBag.setFunctionId(XACML3.ID_FUNCTION_STRING_BAG.stringValue());
716 if (targetObject instanceof Collection) {
717 for (Object target : ((Collection<Object>) targetObject)) {
718 if (! (target instanceof String)) {
719 LOGGER.error("Collection of unsupported objects {}", target.getClass());
722 AttributeValueType value = new AttributeValueType();
723 value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
724 value.getContent().add(target.toString());
725 applyStringBag.getExpression().add(factory.createAttributeValue(value));
727 } else if (targetObject instanceof String) {
728 AttributeValueType value = new AttributeValueType();
729 value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
730 value.getContent().add(targetObject.toString());
731 applyStringBag.getExpression().add(factory.createAttributeValue(value));
733 LOGGER.warn("Unsupported object for target {}", targetObject.getClass());
737 // Create our designator
739 AttributeDesignatorType designator = new AttributeDesignatorType();
740 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.stringValue());
741 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
742 designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
744 // Create apply for our AnyOf
746 ApplyType applyAnyOf = new ApplyType();
747 applyAnyOf.setDescription("Find designator as anyof the possible values");
748 applyAnyOf.setFunctionId(XACML3.ID_FUNCTION_ANY_OF.stringValue());
749 applyAnyOf.getExpression().add(factory.createAttributeDesignator(designator));
750 applyAnyOf.getExpression().add(factory.createApply(applyStringBag));
754 private static Integer parseInteger(String strInteger) {
755 Integer theInt = null;
757 theInt = Integer.parseInt(strInteger);
758 } catch (NumberFormatException e) {
759 LOGGER.warn("Expecting an integer", e);
761 Double dblLimit = Double.parseDouble(strInteger);
762 theInt = dblLimit.intValue();
763 } catch (NumberFormatException e1) {
764 LOGGER.error("Failed to parse expected integer as a double", e);
771 @SuppressWarnings("unused")
772 private static AdviceExpressionsType generateRequestIdAdvice() {
773 AdviceExpressionType adviceExpression = new AdviceExpressionType();
774 adviceExpression.setAppliesTo(EffectType.PERMIT);
775 adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_GUARD.stringValue());
777 AttributeDesignatorType designator = new AttributeDesignatorType();
778 designator.setAttributeId(ToscaDictionary.ID_SUBJECT_GUARD_REQUESTID.stringValue());
779 designator.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
780 designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
782 AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType();
783 assignment.setAttributeId(ToscaDictionary.ID_ADVICE_GUARD_REQUESTID.stringValue());
784 assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
785 assignment.setExpression(new ObjectFactory().createAttributeDesignator(designator));
787 adviceExpression.getAttributeAssignmentExpression().add(assignment);
789 AdviceExpressionsType adviceExpressions = new AdviceExpressionsType();
790 adviceExpressions.getAdviceExpression().add(adviceExpression);
792 return adviceExpressions;