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;
33 import com.att.research.xacml.util.XACMLPolicyWriter;
35 import java.io.ByteArrayOutputStream;
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.Collection;
39 import java.util.List;
41 import java.util.Map.Entry;
43 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
45 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
46 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
52 import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
53 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
54 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
55 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
59 import org.onap.policy.models.decisions.concepts.DecisionRequest;
60 import org.onap.policy.models.decisions.concepts.DecisionResponse;
61 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
62 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
63 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
64 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
68 public class LegacyGuardTranslator implements ToscaPolicyTranslator {
70 private static final Logger LOGGER = LoggerFactory.getLogger(LegacyGuardTranslator.class);
72 private static final String FIELD_POLICIES = "policies";
73 private static final String FIELD_TOPOLOGY_TEMPLATE = "topology_template";
74 private static final String FIELD_GUARD_ACTIVE_START = "guardActiveStart";
75 private static final String FIELD_GUARD_ACTIVE_END = "guardActiveEnd";
77 public LegacyGuardTranslator() {
81 @SuppressWarnings("unchecked")
83 public List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject)
84 throws ToscaPolicyConversionException {
88 List<PolicyType> scannedPolicies = new ArrayList<>();
92 List<Object> policies;
94 if (toscaObject.containsKey(FIELD_POLICIES)) {
95 policies = (List<Object>) toscaObject.get(FIELD_POLICIES);
96 } else if (toscaObject.containsKey(FIELD_TOPOLOGY_TEMPLATE)) {
97 Map<String, Object> topologyTemplate = (Map<String, Object>) toscaObject.get(FIELD_TOPOLOGY_TEMPLATE);
98 if (topologyTemplate.containsKey(FIELD_POLICIES)) {
99 policies = (List<Object>) topologyTemplate.get(FIELD_POLICIES);
101 LOGGER.warn("topologyTemplate does not contain policies");
102 return scannedPolicies;
105 LOGGER.warn("Failed to find policies or topologyTemplate");
106 return scannedPolicies;
109 // Iterate each of the Policies
111 for (Object policyObject : policies) {
115 LOGGER.debug("Found policy {}", policyObject.getClass());
116 Map<String, Object> policyContents = (Map<String, Object>) policyObject;
117 for (Entry<String, Object> entrySet : policyContents.entrySet()) {
118 LOGGER.debug("Entry set {}", entrySet);
120 // Convert this policy
122 PolicyType policy = this.convertPolicy(entrySet);
123 if (policy == null) {
125 // Somehow there wasn't enough information to create
128 LOGGER.debug("Failed to convert policy");
134 try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
135 XACMLPolicyWriter.writePolicyFile(os, policy);
136 LOGGER.debug("{}", os);
137 } catch (IOException e) {
138 LOGGER.error("Failed to convert {}", e);
141 // Convert and add in the new policy
143 scannedPolicies.add(policy);
147 return scannedPolicies;
151 public Request convertRequest(DecisionRequest request) {
152 LOGGER.debug("Converting Request {}", request);
154 return RequestParser.parseRequest(LegacyGuardPolicyRequest.createInstance(request));
155 } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
156 LOGGER.error("Failed to convert DecisionRequest: {}", e);
159 // TODO throw exception
166 public DecisionResponse convertResponse(Response xacmlResponse) {
167 LOGGER.debug("Converting Response {}", xacmlResponse);
168 DecisionResponse decisionResponse = new DecisionResponse();
170 // Iterate through all the results
172 for (Result xacmlResult : xacmlResponse.getResults()) {
176 if (xacmlResult.getDecision() == Decision.PERMIT) {
178 // Just simply return a Permit response
180 decisionResponse.setStatus(Decision.PERMIT.toString());
182 if (xacmlResult.getDecision() == Decision.DENY) {
184 // Just simply return a Deny response
186 decisionResponse.setStatus(Decision.DENY.toString());
188 if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) {
190 // There is no guard policy, so we return a permit
192 decisionResponse.setStatus(Decision.PERMIT.toString());
196 return decisionResponse;
199 @SuppressWarnings("unchecked")
200 private PolicyType convertPolicy(Entry<String, Object> entrySet) throws ToscaPolicyConversionException {
202 // Policy name should be at the root
204 String policyName = entrySet.getKey();
205 Map<String, Object> policyDefinition = (Map<String, Object>) entrySet.getValue();
207 // Set it as the policy ID
209 PolicyType newPolicyType = new PolicyType();
210 newPolicyType.setPolicyId(policyName);
212 // Optional description
214 if (policyDefinition.containsKey("description")) {
215 newPolicyType.setDescription(policyDefinition.get("description").toString());
218 // There should be a metadata section
220 if (! policyDefinition.containsKey("metadata")) {
221 throw new ToscaPolicyConversionException(policyName + " missing metadata section");
223 this.fillMetadataSection(newPolicyType,
224 (Map<String, Object>) policyDefinition.get("metadata"));
226 // Set the combining rule
228 newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue());
230 // Generate the TargetType
232 if (! policyDefinition.containsKey("properties")) {
233 throw new ToscaPolicyConversionException(policyName + " missing properties section");
235 newPolicyType.setTarget(this.generateTargetType((Map<String, Object>) policyDefinition.get("properties")));
237 // Now create the Permit Rule
239 RuleType rule = generatePermitRule(policyName, policyDefinition.get("type").toString(),
240 (Map<String, Object>) policyDefinition.get("properties"));
242 // Check if we were able to create the rule
245 LOGGER.warn("Failed to create rule");
249 // Add the rule to the policy
251 newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
253 // Return our new policy
255 return newPolicyType;
259 * From the TOSCA metadata section, pull in values that are needed into the XACML policy.
261 * @param policy Policy Object to store the metadata
262 * @param metadata The Metadata TOSCA Map
263 * @return Same Policy Object
264 * @throws ToscaPolicyConversionException If there is something missing from the metadata
266 protected PolicyType fillMetadataSection(PolicyType policy,
267 Map<String, Object> metadata) throws ToscaPolicyConversionException {
268 if (! metadata.containsKey("policy-id")) {
269 throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-id");
272 // Do nothing here - the XACML PolicyId is used from TOSCA Policy Name field
275 if (! metadata.containsKey("policy-version")) {
276 throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-version");
279 // Add in the Policy Version
281 policy.setVersion(metadata.get("policy-version").toString());
286 protected TargetType generateTargetType(Map<String, Object> properties) {
288 // Go through potential properties
290 AllOfType allOf = new AllOfType();
291 if (properties.containsKey("actor")) {
292 addMatch(allOf, properties.get("actor"), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR);
294 if (properties.containsKey("recipe")) {
295 addMatch(allOf, properties.get("recipe"), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE);
297 if (properties.containsKey("targets")) {
298 addMatch(allOf, properties.get("targets"), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
300 if (properties.containsKey("clname")) {
301 addMatch(allOf, properties.get("clname"), ToscaDictionary.ID_RESOURCE_GUARD_CLNAME);
303 if (properties.containsKey("targets")) {
304 addMatch(allOf, properties.get("targets"), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
309 TargetType target = new TargetType();
310 AnyOfType anyOf = new AnyOfType();
311 anyOf.getAllOf().add(allOf);
312 target.getAnyOf().add(anyOf);
316 private static AllOfType addMatch(AllOfType allOf, Object value, Identifier attributeId) {
317 if (value instanceof String) {
318 if (".*".equals(value.toString())) {
320 // There's no point to even have a match
327 MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
328 XACML3.ID_FUNCTION_STRING_EQUAL,
330 XACML3.ID_DATATYPE_STRING,
332 XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
334 allOf.getMatch().add(match);
338 if (value instanceof Collection) {
340 // TODO support a collection of that attribute
346 private static RuleType generatePermitRule(String policyName, String policyType, Map<String, Object> properties) {
348 // Now determine which policy type we are generating
350 if ("onap.policies.controlloop.guard.FrequencyLimiter".equals(policyType)) {
351 return generateFrequencyPermit(policyName, properties);
352 } else if ("onap.policies.controlloop.guard.MinMax".equals(policyType)) {
353 return generateMinMaxPermit(policyName, properties);
358 private static RuleType generateFrequencyPermit(String policyName, Map<String, Object> properties) {
360 // See if its possible to generate a count
362 Integer limit = null;
363 if (properties.containsKey("limit")) {
364 limit = Integer.decode(properties.get("limit").toString());
367 LOGGER.debug("Must have a limit value for frequency guard policy to be created");
371 // Get the properties that are common among guards
373 String timeWindow = null;
374 if (properties.containsKey("timeWindow")) {
375 timeWindow = properties.get("timeWindow").toString();
377 String timeUnits = null;
378 if (properties.containsKey("timeUnits")) {
379 timeUnits = properties.get("timeUnits").toString();
381 String guardActiveStart = null;
382 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
383 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
385 String guardActiveEnd = null;
386 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
387 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
390 // Generate the time in range
392 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
396 final ApplyType countCheck = generateCountCheck(limit, timeWindow, timeUnits);
398 // Now combine into an And
400 ApplyType applyAnd = new ApplyType();
401 applyAnd.setDescription("return true if all the apply's are true.");
402 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
403 applyAnd.getExpression().add(new ObjectFactory().createApply(timeRange));
404 applyAnd.getExpression().add(new ObjectFactory().createApply(countCheck));
406 // And create an outer negation of the And
408 ApplyType applyNot = new ApplyType();
409 applyNot.setDescription("Negate the and");
410 applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
411 applyNot.getExpression().add(new ObjectFactory().createApply(applyAnd));
414 // Create our condition
416 final ConditionType condition = new ConditionType();
417 condition.setExpression(new ObjectFactory().createApply(applyNot));
420 // Now we can create our rule
422 RuleType permit = new RuleType();
423 permit.setDescription("Default is to PERMIT if the policy matches.");
424 permit.setRuleId(policyName + ":rule");
425 permit.setEffect(EffectType.PERMIT);
426 permit.setTarget(new TargetType());
430 permit.setCondition(condition);
432 // TODO Add the advice - Is the request id needed to be returned?
434 // permit.setAdviceExpressions(adviceExpressions);
441 private static RuleType generateMinMaxPermit(String policyName, Map<String, Object> properties) {
443 // Get the properties that are common among guards
445 String guardActiveStart = null;
446 if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
447 guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
449 String guardActiveEnd = null;
450 if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
451 guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
454 // Generate the time in range
456 final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
458 // See if its possible to generate a count
461 if (properties.containsKey("min")) {
462 min = Integer.decode(properties.get("min").toString());
465 if (properties.containsKey("max")) {
466 max = Integer.decode(properties.get("max").toString());
468 final ApplyType minApply = generateMinCheck(min);
469 final ApplyType maxApply = generateMaxCheck(max);
471 // Make sure we have at least something to check here,
472 // otherwise there really is no point to this policy.
474 if (timeRange == null && minApply == null && maxApply == null) {
480 RuleType permit = new RuleType();
481 permit.setDescription("Default is to PERMIT if the policy matches.");
482 permit.setRuleId(policyName + ":rule");
483 permit.setEffect(EffectType.PERMIT);
484 permit.setTarget(new TargetType());
486 // Create our condition
488 final ConditionType condition = new ConditionType();
490 // Check if we have all the fields (this can be a little
491 // ugly) but the ultimate goal is to simplify the policy
492 // condition to only check for necessary attributes.
494 ObjectFactory factory = new ObjectFactory();
495 if (timeRange != null && minApply != null && maxApply != null) {
499 ApplyType applyAnd = new ApplyType();
500 applyAnd.setDescription("return true if all the apply's are true.");
501 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
502 applyAnd.getExpression().add(factory.createApply(timeRange));
503 applyAnd.getExpression().add(factory.createApply(minApply));
504 applyAnd.getExpression().add(factory.createApply(maxApply));
506 // Add into the condition
508 condition.setExpression(factory.createApply(applyAnd));
511 // At least one of these applies is null. We need at least
512 // two to require the And apply. Otherwise there is no need
513 // for an outer And apply as the single condition can work
516 if (timeRange != null && minApply == null && maxApply == null) {
518 // Only the time range check is necessary
520 condition.setExpression(factory.createApply(timeRange));
521 } else if (timeRange == null && minApply != null && maxApply == null) {
523 // Only the min check is necessary
525 condition.setExpression(factory.createApply(minApply));
526 } else if (timeRange == null && minApply == null) {
528 // Only the max check is necessary
530 condition.setExpression(factory.createApply(maxApply));
533 // Ok we will need an outer And and have at least the
534 // time range and either min or max check
536 ApplyType applyAnd = new ApplyType();
537 applyAnd.setDescription("return true if all the apply's are true.");
538 applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
539 if (timeRange != null) {
540 applyAnd.getExpression().add(factory.createApply(timeRange));
542 if (minApply != null) {
543 applyAnd.getExpression().add(factory.createApply(minApply));
545 if (maxApply != null) {
546 applyAnd.getExpression().add(factory.createApply(maxApply));
549 // Add into the condition
551 condition.setExpression(factory.createApply(applyAnd));
557 permit.setCondition(condition);
559 // TODO Add the advice - Is the request id needed to be returned?
561 // permit.setAdviceExpressions(adviceExpressions);
568 private static ApplyType generateTimeInRange(String start, String end) {
569 if (start == null || end == null) {
570 LOGGER.warn("Missing time range start {} end {}", start, end);
573 if (start.isEmpty() || end.isEmpty()) {
574 LOGGER.warn("Empty time range start {} end {}", start, end);
578 AttributeDesignatorType designator = new AttributeDesignatorType();
579 designator.setAttributeId(XACML3.ID_ENVIRONMENT_CURRENT_TIME.stringValue());
580 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT.stringValue());
581 designator.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
583 AttributeValueType valueStart = new AttributeValueType();
584 valueStart.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
585 valueStart.getContent().add(start);
587 AttributeValueType valueEnd = new AttributeValueType();
588 valueEnd.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
589 valueEnd.getContent().add(end);
591 ObjectFactory factory = new ObjectFactory();
593 ApplyType applyOneAndOnly = new ApplyType();
594 applyOneAndOnly.setDescription("Unbag the current time");
595 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY.stringValue());
596 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
598 ApplyType applyTimeInRange = new ApplyType();
599 applyTimeInRange.setDescription("return true if current time is in range.");
600 applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RANGE.stringValue());
601 applyTimeInRange.getExpression().add(factory.createApply(applyOneAndOnly));
602 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueStart));
603 applyTimeInRange.getExpression().add(factory.createAttributeValue(valueEnd));
605 return applyTimeInRange;
608 private static ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) {
609 AttributeDesignatorType designator = new AttributeDesignatorType();
610 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT.stringValue());
611 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
612 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
614 // TODO Add this back in when the operational database PIP is configured.
615 // The issuer indicates that the PIP will be providing this attribute during
616 // the decision making.
618 // Right now I am faking the count value by re-using the request-id field
620 //String issuer = "org:onap:xacml:guard:historydb:tw:" + timeWindow + ":" + timeUnits;
621 //designator.setIssuer(issuer);
623 AttributeValueType valueLimit = new AttributeValueType();
624 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
626 // Yes really use toString(), the marshaller will
627 // throw an exception if this is an integer object
630 valueLimit.getContent().add(limit.toString());
632 ObjectFactory factory = new ObjectFactory();
634 ApplyType applyOneAndOnly = new ApplyType();
635 applyOneAndOnly.setDescription("Unbag the limit");
636 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
637 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
639 ApplyType applyGreaterThanEqual = new ApplyType();
640 applyGreaterThanEqual.setDescription("return true if current count is greater than or equal.");
641 applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue());
642 applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
643 applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
645 return applyGreaterThanEqual;
648 private static ApplyType generateMinCheck(Integer min) {
652 AttributeDesignatorType designator = new AttributeDesignatorType();
653 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
654 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
655 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
659 AttributeValueType valueLimit = new AttributeValueType();
660 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
662 // Yes really use toString(), the marshaller will
663 // throw an exception if this is an integer object
666 valueLimit.getContent().add(min.toString());
667 ObjectFactory factory = new ObjectFactory();
669 ApplyType applyOneAndOnly = new ApplyType();
670 applyOneAndOnly.setDescription("Unbag the min");
671 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
672 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
674 ApplyType applyGreaterThanEqual = new ApplyType();
675 applyGreaterThanEqual.setDescription("return true if current count is greater than or equal.");
676 applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue());
677 applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
678 applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
680 return applyGreaterThanEqual;
683 private static ApplyType generateMaxCheck(Integer max) {
687 AttributeDesignatorType designator = new AttributeDesignatorType();
688 designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
689 designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
690 designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
694 AttributeValueType valueLimit = new AttributeValueType();
695 valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
697 // Yes really use toString(), the marshaller will
698 // throw an exception if this is an integer object
701 valueLimit.getContent().add(max.toString());
702 ObjectFactory factory = new ObjectFactory();
704 ApplyType applyOneAndOnly = new ApplyType();
705 applyOneAndOnly.setDescription("Unbag the min");
706 applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
707 applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
709 ApplyType applyGreaterThanEqual = new ApplyType();
710 applyGreaterThanEqual.setDescription("return true if current count is less than or equal.");
711 applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL.stringValue());
712 applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
713 applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
715 return applyGreaterThanEqual;
718 private static AdviceExpressionsType generateRequestIdAdvice() {
719 AdviceExpressionType adviceExpression = new AdviceExpressionType();
720 adviceExpression.setAppliesTo(EffectType.PERMIT);
721 adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_GUARD.stringValue());
723 AttributeDesignatorType designator = new AttributeDesignatorType();
724 designator.setAttributeId(ToscaDictionary.ID_SUBJECT_GUARD_REQUESTID.stringValue());
725 designator.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
726 designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
728 AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType();
729 assignment.setAttributeId(ToscaDictionary.ID_ADVICE_GUARD_REQUESTID.stringValue());
730 assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
731 assignment.setExpression(new ObjectFactory().createAttributeDesignator(designator));
733 adviceExpression.getAttributeAssignmentExpression().add(assignment);
735 AdviceExpressionsType adviceExpressions = new AdviceExpressionsType();
736 adviceExpressions.getAdviceExpression().add(adviceExpression);
738 return adviceExpressions;