Developing a Custom Policy¶
A custom policy is a Java class with some annotations that mark the class as a custom policy and indicate which method the Server has to execute to intercept the query before executing it. Every time a custom policy is executed, the Server creates a new instance of the class.
We strongly recommend using the Denodo4E plugin for Eclipse, to develop
custom policies (see the file README
in
<DENODO_HOME>/tools/denodo4e
).
To develop a custom policy, add the
<DENODO_HOME>/lib/contrib/denodo-commons-commons-custom.jar
file to
the Classpath of your environment.
You can find the Javadoc of the required classes and annotations in the
<DENODO_HOME>/docs/vdp/api
directory.
There is a sample custom policy in the directory
<DENODO_HOME>/samples/vdp/customPolicies/
This custom policy limits the number of concurrent queries that a user/role can execute over the same view or stored procedure. This custom policy has one input parameter called “Limit”, which sets the maximum number of concurrent queries this user/role can execute.
The README
file of this directory explains how to compile the
example and import it into Virtual DataPort.
To develop a custom policy, create a new Java class and annotate it with
the annotation com.denodo.common.custom.annotations.CustomElement
.
This annotation has the following parameters:
type
: it has to becom.denodo.common.custom.annotations.CustomElementType.VDPCUSTOMPOLICY
name
: name of the custom policy. The Administration Tool displays this value in the list of custom policies.
To access to the context of the query, add an attribute of the class
com.denodo.common.custom.policy.CustomRestrictionPolicyContext
and
annotate it with com.denodo.common.custom.annotations.CustomContext
.
At runtime, this attribute will hold the context of the query. That is:
The query the user wants to execute:
getQuery()
.The fields involved in the query. That is, all the field in the
SELECT
,WHERE
,GROUP BY
andHAVING
clauses:getFieldsInQuery()
.The user who executes the query and her roles:
getCurrentUserName()
andgetCurrentUserRoles()
.Database where the query is executed:
getCurrentDatabaseName()
.User / role to whom the custom policy was assigned:
getPolicyCredentialsName()
andgetPolicyCredentialsType()
. The latter method returns if the policy is assigned to a user or a role.View / stored procedure that the custom policy was assigned to:
getElementType()
andgetElementName()
.Properties of the query. Invoke
getProperty(...)
to obtain the value of the property andsetProperty(...)
to change it. The available properties are the constants defined in theCustomRestrictionPolicyContext
class:I18N_PROPERTY
,SWAP_PROPERTY
, etc.Provides a JMX connection to the Virtual DataPort server that the custom policy can use to retrieve any data via JMX:
getJmxConnection()
.Provides a method to log a message in the Server’s logging system:
log(...)
.
When a custom policy is executed, the Server will execute the method
marked with the annotation
com.denodo.common.custom.annotations.CustomExecutor
.
The Java class of the custom policy must have one and only one method
marked with the annotation CustomExecutor
. This method has to return
a com.denodo.common.custom.policy.CustomRestrictionPolicyValue
object.
To add parameters to the custom policy, add a parameter to this method
and annotate it with
com.denodo.common.custom.annotations.CustomParam
. This annotation
has two parameters:
name
: the Administration Tool uses this parameter to display information about the custom policy to the users.mandatory
: boolean value that indicates if this parameter is optional.
The value of these parameters is set when assigning the custom policy to a Virtual DataPort user or role.
The class CustomRestrictionPolicyValue
(class of the objects
returned by the policy) has two constructors:
CustomRestrictionPolicyValue(CustomRestrictionPolicyType policyType)
Constructs aCustomRestrictionPolicyValue
without imposing any restriction.CustomRestrictionPolicyValue( CustomRestrictionPolicyType policyType, CustomRestrictionPolicyFilterType filterType, String condition, Set<String> sensitiveFields)
Constructs aCustomRestrictionPolicyValue
, which may impose a restriction.
CustomRestrictionPolicyType
is an enum
with the following
fields:
REJECT
: it means that the policy rejects the query.ACCEPT
: it means that the policy accepts the query and the Server will execute it.ACCEPT_WITH_FILTER
: it means that the policy accepts the query but it sets some restrictions, which are determined by the fields of the second constructor:filterType
,condition
andsensitiveFields
.
If you want the custom policy to accept (ACCEPT
) or reject
(REJECT
) the query, instance the object using the first constructor.
If you want the custom policy to accept the query with some restrictions
(ACCEPT_WITH_FILTER
), use the second constructor and provide a
non-null value for filterType
, condition
and
sensitiveFields
. In this case, the custom policy works in the same
way as a restriction, so you have to define a condition, a set of
sensitive fields and a type of filter.
The object CustomRestrictionPolicyFilterType
tells the Server what
to do when the query returns a row that does not verify the
condition
. The filter can be:
REJECT_ROW
: the Server will only include in the result of the query, the rows that verify the condition set by the parametercondition
.REJECT_ROW_IF_ANY_SENSITIVE_FIELDS_USED
: if the query uses at least one field ofsensitiveFields
, the Server will only return the rows that verifycondition
. If the query uses none of thesensitiveFields
, the Server will not filter any row.REJECT_ROW_IF_ALL_SENSITIVE_FIELDS_USED
: if the query uses all the fields ofsensitiveFields
, the Server will only return the rows that verifycondition
. If the query does not use all the fields insensitiveFields
, the Server will not filter any row.MASK_SENSITIVE_FIELDS_IF_ANY_USED
: if the query uses at least one field ofsensitiveFields
, the Server will set toNULL
the fields in theSet sensitiveFields
of the rows that do not verifycondition
. If the query does not use any field insensitiveFields
, the Server will not mask any field.MASK_SENSITIVE_FIELDS_IF_ALL_USED
: if the query uses all the fields ofsensitiveFields
, the Server will set toNULL
the fields in theSet sensitiveFields
of the rows that do not verifycondition
. If the query does not use all the fields insensitiveFields
, the Server will not mask any field.