Fix sonars in xacml-pdp
[policy/xacml-pdp.git] / applications / common / src / main / java / org / onap / policy / pdp / xacml / application / common / std / StdBaseTranslator.java
index d2d383b..61d28f5 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.policy.pdp.xacml.application.common.std;
 
-import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.Advice;
 import com.att.research.xacml.api.Decision;
 import com.att.research.xacml.api.Obligation;
 import com.att.research.xacml.api.Request;
 import com.att.research.xacml.api.Response;
 import com.att.research.xacml.api.Result;
 import com.att.research.xacml.api.XACML3;
-import com.google.gson.Gson;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
-import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
-import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
-import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
@@ -50,6 +46,7 @@ import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
 import org.onap.policy.models.decisions.concepts.DecisionRequest;
 import org.onap.policy.models.decisions.concepts.DecisionResponse;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.onap.policy.pdp.xacml.application.common.OnapObligation;
 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
@@ -58,27 +55,27 @@ import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class StdBaseTranslator implements ToscaPolicyTranslator {
+public abstract class StdBaseTranslator implements ToscaPolicyTranslator {
     private static final Logger LOGGER = LoggerFactory.getLogger(StdBaseTranslator.class);
-    private static Gson gson = new Gson();
+    private static final ObjectFactory factory = new ObjectFactory();
 
     public static final String POLICY_ID = "policy-id";
     public static final String POLICY_VERSION = "policy-version";
 
     @Override
-    public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
-        throw new ToscaPolicyConversionException("Please override converPolicy");
+    public Object convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
+        throw new ToscaPolicyConversionException("Please override convertPolicy");
     }
 
     @Override
-    public Request convertRequest(DecisionRequest request) {
+    public Request convertRequest(DecisionRequest request) throws ToscaPolicyConversionException {
         return null;
     }
 
     @Override
     public DecisionResponse convertResponse(Response xacmlResponse) {
         LOGGER.info("Converting Response {}", xacmlResponse);
-        DecisionResponse decisionResponse = new DecisionResponse();
+        var decisionResponse = new DecisionResponse();
         //
         // Setup policies
         //
@@ -95,12 +92,16 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
                 // Go through obligations
                 //
                 scanObligations(xacmlResult.getObligations(), decisionResponse);
-            } else if (xacmlResult.getDecision() == Decision.DENY
-                    || xacmlResult.getDecision() == Decision.INDETERMINATE) {
                 //
-                // TODO we have to return an ErrorResponse object instead
+                // Go through advice
                 //
-                decisionResponse.setStatus("A better error message");
+                scanAdvice(xacmlResult.getAssociatedAdvice(), decisionResponse);
+            } else {
+                //
+                // Return error information back
+                //
+                decisionResponse.setStatus("error");
+                decisionResponse.setMessage(xacmlResult.getStatus().getStatusMessage());
             }
         }
 
@@ -109,55 +110,23 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
 
     /**
      * scanObligations - scans the list of obligations and make appropriate method calls to process
-     * obligations.
+     * obligations. This method must be overridden and be implemented for the specific application as
+     * obligations may have different expected attributes per application.
      *
      * @param obligations Collection of obligation objects
      * @param decisionResponse DecisionResponse object used to store any results from obligations.
      */
-    protected void scanObligations(Collection<Obligation> obligations, DecisionResponse decisionResponse) {
-        for (Obligation obligation : obligations) {
-            LOGGER.info("Obligation: {}", obligation);
-            for (AttributeAssignment assignment : obligation.getAttributeAssignments()) {
-                LOGGER.info("Attribute Assignment: {}", assignment);
-                processObligationAttribute(assignment, decisionResponse);
-            }
-        }
-    }
+    protected abstract void scanObligations(Collection<Obligation> obligations, DecisionResponse decisionResponse);
 
     /**
-     * processObligationAttribute - processes an individual obligation attribute assignment object.
+     * scanAdvice - scans the list of advice and make appropriate call to process the advice. This method
+     * can be overridden for each specific application as advice may have different expected attributes per
+     * application.
      *
-     * @param assignment AttributeAssignment object
-     * @param decisionResponse DecisionResponse object used to store any results from attribute assignment.
+     * @param advice Collection of Advice objects
+     * @param decisionResponse DecisionResponse object used to store any results from advice.
      */
-    @SuppressWarnings("unchecked")
-    protected void processObligationAttribute(AttributeAssignment assignment, DecisionResponse decisionResponse) {
-        //
-        // We care about the content attribute
-        //
-        if (ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_CONTENTS
-                .equals(assignment.getAttributeId())) {
-            //
-            // The contents are in Json form
-            //
-            Object stringContents = assignment.getAttributeValue().getValue();
-            LOGGER.info("DCAE contents: {}{}", XacmlPolicyUtils.LINE_SEPARATOR, stringContents);
-            //
-            // Let's parse it into a map using Gson
-            //
-            Map<String, Object> result;
-            result = gson.fromJson(stringContents.toString(), Map.class);
-            //
-            // Find the metadata section
-            //
-            Map<String, Object> metadata = (Map<String, Object>) result.get("metadata");
-            if (metadata != null) {
-                decisionResponse.getPolicies().put(metadata.get(POLICY_ID).toString(), result);
-            } else {
-                LOGGER.error("Missing metadata section in policy contained in obligation.");
-            }
-        }
-    }
+    protected abstract void scanAdvice(Collection<Advice> advice, DecisionResponse decisionResponse);
 
     /**
      * From the TOSCA metadata section, pull in values that are needed into the XACML policy.
@@ -196,40 +165,31 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
      * But this is fine for now.
      *
      * @param <T> RuleType, PolicyType, PolicySetType object
+     * @Param policyId The policy-id
      * @param ruleOrPolicy Incoming RuleType, PolicyType, PolicySetType object
      * @param jsonPolicy JSON String representation of policy.
+     * @param weight Weighting for the policy (optional)
      * @return Return the Incoming RuleType, PolicyType, PolicySetType object for convenience.
      */
-    protected <T> T addObligation(T ruleOrPolicy, String jsonPolicy) {
+    protected <T> T addObligation(T ruleOrPolicy, String policyId, String jsonPolicy, Integer weight,
+            String policyType) {
         //
         // Creating obligation for returning policy
         //
-        LOGGER.info("Obligation Policy {}{}", XacmlPolicyUtils.LINE_SEPARATOR, jsonPolicy);
-        //
-        // Create an AttributeValue for it
-        //
-        AttributeValueType value = new AttributeValueType();
-        value.setDataType(ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_DATATYPE.stringValue());
-        value.getContent().add(jsonPolicy);
+        LOGGER.info("Obligation Policy id: {} type: {} weight: {} policy:{}{}", policyId, policyType, weight,
+                XacmlPolicyUtils.LINE_SEPARATOR, jsonPolicy);
         //
-        // Create our AttributeAssignmentExpression where we will
-        // store the contents of the policy in JSON format.
+        // Create our OnapObligation
         //
-        AttributeAssignmentExpressionType expressionType = new AttributeAssignmentExpressionType();
-        expressionType.setAttributeId(ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_CONTENTS.stringValue());
-        ObjectFactory factory = new ObjectFactory();
-        expressionType.setExpression(factory.createAttributeValue(value));
+        var onapObligation = new OnapObligation(policyId, jsonPolicy, policyType, weight);
         //
-        // Create an ObligationExpression for it
+        // Generate the obligation
         //
-        ObligationExpressionType obligation = new ObligationExpressionType();
-        obligation.setFulfillOn(EffectType.PERMIT);
-        obligation.setObligationId(ToscaDictionary.ID_OBLIGATION_REST_BODY.stringValue());
-        obligation.getAttributeAssignmentExpression().add(expressionType);
+        ObligationExpressionType obligation = onapObligation.generateObligation();
         //
         // Now we can add it into the rule/policy/policyset
         //
-        ObligationExpressionsType obligations = new ObligationExpressionsType();
+        var obligations = new ObligationExpressionsType();
         obligations.getObligationExpression().add(obligation);
         if (ruleOrPolicy instanceof RuleType) {
             ((RuleType) ruleOrPolicy).setObligationExpressions(obligations);
@@ -237,6 +197,8 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
             ((PolicyType) ruleOrPolicy).setObligationExpressions(obligations);
         } else if (ruleOrPolicy instanceof PolicySetType) {
             ((PolicySetType) ruleOrPolicy).setObligationExpressions(obligations);
+        } else {
+            LOGGER.error("Unsupported class for adding obligation {}", ruleOrPolicy.getClass());
         }
         //
         // Return as a convenience
@@ -255,7 +217,7 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
         //
         // Create the match for the policy type
         //
-        MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+        var match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
                 XACML3.ID_FUNCTION_STRING_EQUAL,
                 type,
                 XACML3.ID_DATATYPE_STRING,
@@ -264,7 +226,7 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
         //
         // Add it to an AnyOfType object
         //
-        AnyOfType anyOf = new AnyOfType();
+        var anyOf = new AnyOfType();
         anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(match));
         //
         // Return new AnyOfType
@@ -287,23 +249,22 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
         // Create an ApplyType that checks if the request contains the
         // policy-type attribute
         //
-        AttributeDesignatorType designator = new AttributeDesignatorType();
+        var designator = new AttributeDesignatorType();
         designator.setAttributeId(ToscaDictionary.ID_RESOURCE_POLICY_TYPE.stringValue());
         designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
         designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
 
-        ApplyType applyBagSize = new ApplyType();
+        var applyBagSize = new ApplyType();
         applyBagSize.setDescription("Get the size of policy-type attributes");
         applyBagSize.setFunctionId(XACML3.ID_FUNCTION_STRING_BAG_SIZE.stringValue());
 
-        AttributeValueType valueZero = new AttributeValueType();
+        var valueZero = new AttributeValueType();
         valueZero.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
         valueZero.getContent().add("0");    // Yes really - represent as a string
 
-        ObjectFactory factory = new ObjectFactory();
         applyBagSize.getExpression().add(factory.createAttributeDesignator(designator));
 
-        ApplyType applyGreaterThan = new ApplyType();
+        var applyGreaterThan = new ApplyType();
         applyGreaterThan.setDescription("Does the policy-type attribute exist?");
         applyGreaterThan.setFunctionId(XACML3.ID_FUNCTION_INTEGER_EQUAL.stringValue());
 
@@ -313,7 +274,7 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
         //
         // Create an apply type that checks the actual value
         //
-        AttributeValueType value = new AttributeValueType();
+        var value = new AttributeValueType();
         value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
         value.getContent().add(type);
 
@@ -321,7 +282,7 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
         // Create string-is-in apply - which determines if the policy-type
         // is in the request bag of resources for policy-type
         //
-        ApplyType applyIsIn = new ApplyType();
+        var applyIsIn = new ApplyType();
         applyIsIn.setDescription("Is this policy-type in the list?");
         applyIsIn.setFunctionId(XACML3.ID_FUNCTION_STRING_IS_IN.stringValue());
         applyIsIn.getExpression().add(factory.createAttributeValue(value));
@@ -330,7 +291,7 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
         //
         // Create our outer apply
         //
-        ApplyType applyOr = new ApplyType();
+        var applyOr = new ApplyType();
         applyOr.setDescription("IF exists and is equal");
         applyOr.setFunctionId(XACML3.ID_FUNCTION_OR.stringValue());
 
@@ -340,7 +301,7 @@ public class StdBaseTranslator implements ToscaPolicyTranslator {
         //
         // Finally create the condition
         //
-        ConditionType condition = new ConditionType();
+        var condition = new ConditionType();
 
         condition.setExpression(factory.createApply(applyOr));