* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2020 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.Advice;
import com.att.research.xacml.api.Identifier;
import com.att.research.xacml.api.Obligation;
import com.att.research.xacml.api.Request;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import lombok.Setter;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
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.PolicyType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
import org.onap.policy.common.utils.coder.StandardYamlCoder;
import org.onap.policy.models.decisions.concepts.DecisionRequest;
import org.onap.policy.models.decisions.concepts.DecisionResponse;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
import org.onap.policy.pdp.xacml.application.common.OnapObligation;
import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
+import org.onap.policy.pdp.xacml.application.common.matchable.MatchableCallback;
+import org.onap.policy.pdp.xacml.application.common.matchable.MatchablePolicyType;
+import org.onap.policy.pdp.xacml.application.common.matchable.MatchableProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* @author pameladragosh
*
*/
-public class StdMatchableTranslator extends StdBaseTranslator {
+public class StdMatchableTranslator extends StdBaseTranslator implements MatchableCallback {
private static final Logger LOGGER = LoggerFactory.getLogger(StdMatchableTranslator.class);
private static final StandardYamlCoder standardYamlCoder = new StandardYamlCoder();
- private final Map<ToscaPolicyTypeIdentifier, ToscaPolicyType> matchablePolicyTypes = new HashMap<>();
+ private final Map<ToscaPolicyTypeIdentifier, ToscaServiceTemplate> matchablePolicyTypes = new HashMap<>();
+ private final Map<ToscaPolicyTypeIdentifier, MatchablePolicyType> matchableCache = new HashMap<>();
+
@Setter
private RestServerParameters apiRestParameters;
@Setter
}
@Override
- public Request convertRequest(DecisionRequest request) {
+ public Request convertRequest(DecisionRequest request) throws ToscaPolicyConversionException {
LOGGER.info("Converting Request {}", request);
try {
return StdMatchablePolicyRequest.createInstance(request);
} catch (XacmlApplicationException e) {
- LOGGER.error("Failed to convert DecisionRequest: {}", e);
+ throw new ToscaPolicyConversionException("Failed to convert DecisionRequest", e);
}
- //
- // TODO throw exception
- //
- return null;
}
/**
);
}
+ @Override
+ protected void scanAdvice(Collection<Advice> advice, DecisionResponse decisionResponse) {
+ LOGGER.warn("scanAdvice not supported by {}", this.getClass());
+ }
+
/**
* scanClosestMatchObligation - scans for the obligation specifically holding policy
* contents and their details.
}
@Override
- public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
+ public Object convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
//
// Get the TOSCA Policy Type for this policy
//
- Collection<ToscaPolicyType> toscaPolicyTypes = this.getPolicyTypes(toscaPolicy.getTypeIdentifier());
+ ToscaServiceTemplate toscaPolicyTypeTemplate = this.findPolicyType(toscaPolicy.getTypeIdentifier());
//
// If we don't have any TOSCA policy types, then we cannot know
// which properties are matchable.
//
- if (toscaPolicyTypes.isEmpty()) {
+ if (toscaPolicyTypeTemplate == null) {
throw new ToscaPolicyConversionException(
"Cannot retrieve Policy Type definition for policy " + toscaPolicy.getName());
}
// Generate the TargetType - the policy should not be evaluated
// unless all the matchable properties it cares about are matched.
//
- Pair<TargetType, Integer> pairGenerated = generateTargetType(toscaPolicy.getProperties(), toscaPolicyTypes);
+ Pair<TargetType, Integer> pairGenerated = generateTargetType(toscaPolicy, toscaPolicyTypeTemplate);
newPolicyType.setTarget(pairGenerated.getLeft());
//
// Now represent the policy as Json
return newPolicyType;
}
- /**
- * For generating target type, we scan for matchable properties
- * and use those to build the policy.
- *
- * @param properties Properties section of policy
- * @param policyTypes Collection of policy Type to find matchable metadata
- * @return {@code Pair<TargetType, Integer>} Returns a TargetType and a Total Weight of matchables.
- */
- protected Pair<TargetType, Integer> generateTargetType(Map<String, Object> properties,
- Collection<ToscaPolicyType> policyTypes) {
- TargetType targetType = new TargetType();
- //
- // Iterate the properties
- //
- int totalWeight = findMatchableFromMap(properties, policyTypes, targetType);
- LOGGER.info("Total weight is {}", totalWeight);
- return Pair.of(targetType, totalWeight);
- }
-
- @SuppressWarnings("unchecked")
- protected int findMatchableFromList(List<Object> listProperties, Collection<ToscaPolicyType> policyTypes,
- TargetType targetType) {
- LOGGER.info("findMatchableFromList {}", listProperties);
- int totalWeight = 0;
- for (Object property : listProperties) {
- if (property instanceof List) {
- totalWeight += findMatchableFromList((List<Object>) property, policyTypes, targetType);
- } else if (property instanceof Map) {
- totalWeight += findMatchableFromMap((Map<String, Object>) property, policyTypes, targetType);
- }
+ @Override
+ public ToscaPolicyType retrievePolicyType(String derivedFrom) {
+ ToscaServiceTemplate template = this.findPolicyType(new ToscaPolicyTypeIdentifier(derivedFrom, "1.0.0"));
+ if (template == null) {
+ LOGGER.error("Could not retrieve Policy Type {}", derivedFrom);
+ return null;
}
- return totalWeight;
+ return template.getPolicyTypes().get(derivedFrom);
}
- protected int findMatchableFromMap(Map<String, Object> properties, Collection<ToscaPolicyType> policyTypes,
- TargetType targetType) {
- LOGGER.info("findMatchableFromMap {}", properties);
- int totalWeight = 0;
- for (Entry<String, Object> entrySet : properties.entrySet()) {
- //
- // Is this a matchable property?
- //
- if (isMatchable(entrySet.getKey(), policyTypes)) {
- LOGGER.info("Found matchable property {}", entrySet.getKey());
- int weight = generateMatchable(targetType, entrySet.getKey(), entrySet.getValue());
- LOGGER.info("Weight is {}", weight);
- totalWeight += weight;
- } else {
- //
- // Check if we need to search deeper
- //
- totalWeight += checkDeeperForMatchable(entrySet.getValue(), policyTypes, targetType);
- }
- }
- return totalWeight;
+ @Override
+ public ToscaDataType retrieveDataType(String datatype) {
+ //
+ // Our outer class is not storing the current template being scanned
+ //
+ LOGGER.error("this retrieveDataType should not be called.");
+ return null;
}
- @SuppressWarnings("unchecked")
- protected int checkDeeperForMatchable(Object property, Collection<ToscaPolicyType> policyTypes,
- TargetType targetType) {
- if (property instanceof List) {
- return findMatchableFromList((List<Object>) property, policyTypes, targetType);
- } else if (property instanceof Map) {
- return findMatchableFromMap((Map<String, Object>) property, policyTypes,
- targetType);
- }
- LOGGER.info("checkDeeperForMatchable not necessary for {}", property);
- return 0;
- }
+ private class MyMatchableCallback implements MatchableCallback {
+ private StdMatchableTranslator translator;
+ private ToscaServiceTemplate template;
- /**
- * isMatchable - Iterates through available TOSCA Policy Types to determine if a property
- * should be treated as matchable.
- *
- * @param propertyName Name of property
- * @param policyTypes Collection of TOSCA Policy Types to scan
- * @return true if matchable
- */
- protected boolean isMatchable(String propertyName, Collection<ToscaPolicyType> policyTypes) {
- for (ToscaPolicyType policyType : policyTypes) {
- for (Entry<String, ToscaProperty> propertiesEntry : policyType.getProperties().entrySet()) {
- if (checkIsMatchableProperty(propertyName, propertiesEntry)) {
- return true;
- }
- //
- // Check if its a list or map
- //
- if (isListOrMap(propertiesEntry.getValue().getType())
- && ! isYamlType(propertiesEntry.getValue().getEntrySchema().getType())) {
- LOGGER.info("need to search list or map");
- }
- }
+ public MyMatchableCallback(StdMatchableTranslator translator, ToscaServiceTemplate template) {
+ this.translator = translator;
+ this.template = template;
}
- LOGGER.info("isMatchable false for {}", propertyName);
- return false;
- }
-
- private boolean isListOrMap(String type) {
- return "list".equalsIgnoreCase(type) || "map".equalsIgnoreCase(type);
- }
- private boolean isYamlType(String type) {
- return "string".equalsIgnoreCase(type) || "integer".equalsIgnoreCase(type) || "float".equalsIgnoreCase(type)
- || "boolean".equalsIgnoreCase(type) || "timestamp".equalsIgnoreCase(type);
- }
-
- /**
- * checkIsMatchableProperty - checks the policy contents for matchable field. If the metadata doesn't exist,
- * then definitely not. If the property doesn't exist, then definitely not. Otherwise need to have a metadata
- * section with the matchable property set to true.
- *
- * @param propertyName String value of property
- * @param propertiesEntry Section of the TOSCA Policy Type where properties and metadata sections are held
- * @return true if matchable
- */
- protected boolean checkIsMatchableProperty(String propertyName, Entry<String, ToscaProperty> propertiesEntry) {
- if (! propertiesEntry.getKey().equals(propertyName)
- || propertiesEntry.getValue().getMetadata() == null) {
- return false;
- }
- for (Entry<String, String> entrySet : propertiesEntry.getValue().getMetadata().entrySet()) {
- if ("matchable".equals(entrySet.getKey()) && "true".equals(entrySet.getValue())) {
- return true;
+ @Override
+ public ToscaPolicyType retrievePolicyType(String derivedFrom) {
+ ToscaPolicyType policyType = this.template.getPolicyTypes().get(derivedFrom);
+ if (policyType != null) {
+ return policyType;
}
+ return translator.retrievePolicyType(derivedFrom);
}
- return false;
- }
- /**
- * generateMatchable - Given the object, generates list of MatchType objects and add them
- * to the TargetType object. Returns a weight which is the number of AnyOf's generated. The
- * weight can be used to further filter the results for "closest match".
- *
- * @param targetType TargetType object to add matches to
- * @param key Property key
- * @param value Object is the value - which can be a Collection or single Object
- * @return int Weight of the match.
- */
- @SuppressWarnings("unchecked")
- protected int generateMatchable(TargetType targetType, String key, Object value) {
- int weight = 0;
- if (value instanceof Collection) {
- AnyOfType anyOf = generateMatches((Collection<Object>) value,
- new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + key));
- if (! anyOf.getAllOf().isEmpty()) {
- targetType.getAnyOf().add(anyOf);
- weight = 1;
- }
- } else {
- AnyOfType anyOf = generateMatches(Arrays.asList(value),
- new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + key));
- if (! anyOf.getAllOf().isEmpty()) {
- targetType.getAnyOf().add(anyOf);
- weight = 1;
- }
+ @Override
+ public ToscaDataType retrieveDataType(String datatype) {
+ return this.template.getDataTypes().get(datatype);
}
- return weight;
+
}
/**
- * generateMatches - Goes through the collection of objects, creates a MatchType object
- * for each object and associates it with the given attribute Id. Returns the AnyOfType
- * object that contains all the generated MatchType objects.
+ * For generating target type, we scan for matchable properties
+ * and use those to build the policy.
*
- * @param matchables Collection of object to generate MatchType from
- * @param attributeId Given attribute Id for each MatchType
- * @return AnyOfType object
+ * @param properties Properties section of policy
+ * @param policyTypes Collection of policy Type to find matchable metadata
+ * @return {@code Pair<TargetType, Integer>} Returns a TargetType and a Total Weight of matchables.
*/
- protected AnyOfType generateMatches(Collection<Object> matchables, Identifier attributeId) {
+ protected Pair<TargetType, Integer> generateTargetType(ToscaPolicy policy, ToscaServiceTemplate template) {
//
- // This is our outer AnyOf - which is an OR
+ // Our return object
//
- AnyOfType anyOf = new AnyOfType();
- for (Object matchable : matchables) {
- //
- // Default to string
- //
- Identifier idFunction = XACML3.ID_FUNCTION_STRING_EQUAL;
- Identifier idDatatype = XACML3.ID_DATATYPE_STRING;
- //
- // See if we are another datatype
+ TargetType target = new TargetType();
+ //
+ // See if we have a matchable in the cache already
+ //
+ MatchablePolicyType matchablePolicyType = matchableCache.get(policy.getTypeIdentifier());
+ //
+ // If not found, create one
+ //
+ if (matchablePolicyType == null) {
//
- // We should add datetime support. But to do that we need
- // probably more metadata to describe how that would be translated.
+ // Our callback
//
- if (matchable instanceof Integer) {
- idFunction = XACML3.ID_FUNCTION_INTEGER_EQUAL;
- idDatatype = XACML3.ID_DATATYPE_INTEGER;
- } else if (matchable instanceof Double) {
- idFunction = XACML3.ID_FUNCTION_DOUBLE_EQUAL;
- idDatatype = XACML3.ID_DATATYPE_DOUBLE;
- } else if (matchable instanceof Boolean) {
- idFunction = XACML3.ID_FUNCTION_BOOLEAN_EQUAL;
- idDatatype = XACML3.ID_DATATYPE_BOOLEAN;
- }
+ MyMatchableCallback myCallback = new MyMatchableCallback(this, template);
//
- // Create a match for this
+ // Create the matchable
//
- MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
- idFunction,
- matchable.toString(),
- idDatatype,
- attributeId,
- XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+ matchablePolicyType = new MatchablePolicyType(
+ template.getPolicyTypes().get(policy.getType()), myCallback);
//
- // Now create an anyOf (OR)
+ // Cache it
//
- anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(match));
+ matchableCache.put(policy.getTypeIdentifier(), matchablePolicyType);
}
- return anyOf;
- }
-
- /**
- * Get Policy Type definitions. This could be previously loaded, or could be
- * stored in application path, or may need to be pulled from the API.
- *
- *
- * @param policyTypeId Policy Type Id
- * @return A list of PolicyTypes
- */
- private List<ToscaPolicyType> getPolicyTypes(ToscaPolicyTypeIdentifier policyTypeId) {
- //
- // Create identifier from the policy
- //
- ToscaPolicyTypeIdentifier typeId = new ToscaPolicyTypeIdentifier(policyTypeId);
//
- // Find the Policy Type
+ // Fill in the target type with potential matchables
//
- ToscaPolicyType policyType = findPolicyType(typeId);
- if (policyType == null) {
- return Collections.emptyList();
+ try {
+ fillTargetTypeWithMatchables(target, matchablePolicyType, policy.getProperties());
+ } catch (ToscaPolicyConversionException e) {
+ LOGGER.error("Could not generate target type", e);
}
//
- // Create our return object
+ // There may be a case for default policies there is no weight - need to clean
+ // up the target then else PDP will report bad policy missing AnyOf
//
- List<ToscaPolicyType> listTypes = new ArrayList<>();
- listTypes.add(policyType);
+ int weight = calculateWeight(target);
+ LOGGER.debug("Weight is {} for policy {}", weight, policy.getName());
//
- // Look for parent policy types that could also contain matchable properties
+ // Assume the number of AllOf's is the weight for now
//
- ToscaPolicyType childPolicyType = policyType;
- while (! childPolicyType.getDerivedFrom().startsWith("tosca.policies.Root")) {
- //
- // Create parent policy type id.
- //
- // We will have to assume the same version between child and the
- // parent policy type it derives from.
- //
- // Or do we assume 1.0.0?
- //
- ToscaPolicyTypeIdentifier parentId = new ToscaPolicyTypeIdentifier(childPolicyType.getDerivedFrom(),
- "1.0.0");
- //
- // Find the policy type
- //
- ToscaPolicyType parentPolicyType = findPolicyType(parentId);
- if (parentPolicyType == null) {
- //
- // Probably would be best to throw an exception and
- // return nothing back.
+ return Pair.of(target, weight);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void fillTargetTypeWithMatchables(TargetType target, MatchablePolicyType matchablePolicyType,
+ Map<String, Object> properties) throws ToscaPolicyConversionException {
+ for (Entry<String, Object> entrySet : properties.entrySet()) {
+ String propertyName = entrySet.getKey();
+ Object propertyValue = entrySet.getValue();
+ MatchableProperty matchable = matchablePolicyType.get(propertyName);
+ if (matchable != null) {
//
- // But instead we will log a warning
+ // Construct attribute id
//
- LOGGER.warn("Missing parent policy type - proceeding anyway {}", parentId);
+ Identifier id = new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + propertyName);
//
- // Break the loop
+ // Depending on what type it is, add it into the target
//
- break;
+ ToscaPolicyTranslatorUtils.buildAndAppendTarget(target,
+ matchable.getType().generate(propertyValue, id));
+
+ continue;
}
//
- // Great save it
- //
- listTypes.add(parentPolicyType);
- //
- // Move to the next parent
+ // Here is the special case where we look for a Collection of values that may
+ // contain potential matchables
//
- childPolicyType = parentPolicyType;
+ if (propertyValue instanceof List) {
+ for (Object listValue : ((List<?>) propertyValue)) {
+ if (listValue instanceof Map) {
+ fillTargetTypeWithMatchables(target, matchablePolicyType, (Map<String, Object>) listValue);
+ }
+ }
+ } else if (propertyValue instanceof Map) {
+ fillTargetTypeWithMatchables(target, matchablePolicyType, (Map<String, Object>) propertyValue);
+ }
+ }
+ }
+
+ protected int calculateWeight(TargetType target) {
+ int weight = 0;
+ for (AnyOfType anyOf : target.getAnyOf()) {
+ for (AllOfType allOf : anyOf.getAllOf()) {
+ weight += allOf.getMatch().size();
+ }
}
- return listTypes;
+
+ return weight;
}
/**
* @param policyTypeId ToscaPolicyTypeIdentifier to find
* @return ToscaPolicyType object. Can be null if failure.
*/
- private ToscaPolicyType findPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+ private ToscaServiceTemplate findPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
//
// Is it loaded in memory?
//
- ToscaPolicyType policyType = this.matchablePolicyTypes.get(policyTypeId);
- if (policyType == null) {
+ ToscaServiceTemplate policyTemplate = this.matchablePolicyTypes.get(policyTypeId);
+ if (policyTemplate == null) {
//
// Load the policy
//
- policyType = this.loadPolicyType(policyTypeId);
+ policyTemplate = this.loadPolicyType(policyTypeId);
+ //
+ // Save it
+ //
+ if (policyTemplate != null) {
+ this.matchablePolicyTypes.put(policyTypeId, policyTemplate);
+ }
}
//
// Yep return it
//
- return policyType;
+ return policyTemplate;
}
/**
* @param policyTypeId ToscaPolicyTypeIdentifier input
* @return ToscaPolicyType object. Null if failure.
*/
- private ToscaPolicyType loadPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+ private ToscaServiceTemplate loadPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
//
// Construct what the file name should be
//
//
LOGGER.info("Read in local policy type {}", policyTypePath.toAbsolutePath());
try {
- ToscaServiceTemplate serviceTemplate = standardYamlCoder.decode(new String(bytes, StandardCharsets.UTF_8),
- ToscaServiceTemplate.class);
- JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
- jtst.fromAuthorative(serviceTemplate);
- ToscaServiceTemplate completedJtst = jtst.toAuthorative();
//
- // Search for our Policy Type, there really only should be one but
- // this is returned as a map.
+ // Decode the template
//
- for ( Entry<String, ToscaPolicyType> entrySet : completedJtst.getPolicyTypes().entrySet()) {
- ToscaPolicyType entryPolicyType = entrySet.getValue();
- if (policyTypeId.getName().equals(entryPolicyType.getName())
- && policyTypeId.getVersion().equals(entryPolicyType.getVersion())) {
- LOGGER.info("Found existing local policy type {} {}", entryPolicyType.getName(),
- entryPolicyType.getVersion());
- //
- // Just simply return the policy type right here
- //
- return entryPolicyType;
- } else {
- LOGGER.warn("local policy type contains different name version {} {}", entryPolicyType.getName(),
- entryPolicyType.getVersion());
- }
- }
+ ToscaServiceTemplate template = standardYamlCoder.decode(new String(bytes, StandardCharsets.UTF_8),
+ ToscaServiceTemplate.class);
//
- // This would be an error, if the file stored does not match what its supposed to be
+ // Ensure all the fields are setup correctly
//
- LOGGER.error("Existing policy type file does not contain right name and version");
+ JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
+ jtst.fromAuthorative(template);
+ return jtst.toAuthorative();
} catch (CoderException e) {
LOGGER.error("Failed to decode tosca template for {}", policyTypePath, e);
}
* @param policyTypePath Path object to store locally
* @return ToscaPolicyType object. Null if failure.
*/
- private synchronized ToscaPolicyType pullPolicyType(ToscaPolicyTypeIdentifier policyTypeId, Path policyTypePath) {
+ private synchronized ToscaServiceTemplate pullPolicyType(ToscaPolicyTypeIdentifier policyTypeId,
+ Path policyTypePath) {
//
// This is what we return
//
- ToscaPolicyType policyType = null;
+ ToscaServiceTemplate policyTemplate = null;
try {
PolicyApiCaller api = new PolicyApiCaller(this.apiRestParameters);
- policyType = api.getPolicyType(policyTypeId);
+ policyTemplate = api.getPolicyType(policyTypeId);
} catch (PolicyApiException e) {
LOGGER.error("Failed to make API call", e);
LOGGER.error("parameters: {} ", this.apiRestParameters);
// Store it locally
//
try {
- standardYamlCoder.encode(policyTypePath.toFile(), policyType);
+ standardYamlCoder.encode(policyTypePath.toFile(), policyTemplate);
} catch (CoderException e) {
LOGGER.error("Failed to store {} locally to {}", policyTypeId, policyTypePath, e);
}
//
// Done return the policy type
//
- return policyType;
+ return policyTemplate;
}
/**