What is the use/ significance of property element in policies?

gagan
New Member

Every policy seems to have <Properties/> element by default (when you add a new policy in UI). What is the use of this element?

On searching docs I found reference to it in JavaScript Policy: http://apigee.com/docs/api-services/reference/javascript-policy

<Property> element

Specifies a property you can access from JavaScript code at runtime.

<Properties>
    <Property name="propName">propertyValue</Property>
</Properties>Default:NonePresence:OptionalType:String

Two questions:

1. How to retrieve this property in JS?

2. What is the significance of it in other policies?

Solved Solved
2 3 1,254
1 ACCEPTED SOLUTION

Good question! @Gagan Garg

The Properties element can be present in every policy configuration, though it is not used by all of them. Two in particular that DO use the Properties element are the JavaCallout and JavaScript policies.

You can use child Property elements to pass data and information from the flow into the Java or JavaScript code that you write. For example, for a JavaCallout, suppose you have this policy configuration:

<JavaCallout name='JWT-Parse-HS256-2'>
  <Properties>
    <Property name="algorithm">HS256</Property>
    <Property name="jwt">{request.formparam.jwt}</Property>
    <Property name='secret-key'>{request.formparam.key}</Property>
    <!-- verify these specific claims -->
    <Property name="claim_iss">http://vinitmehta.net</Property>
  </Properties>

  <ClassName>com.apigee.callout.jwtsigned.JwtParserCallout</ClassName>
  <ResourceURL>java://jwt-signed-edge-callout.jar</ResourceURL>
</JavaCallout>

In your Java code, the constructor is called with a Map<String,Object> of all of the properties. You can retrieve the values passed as properties there by calling map.get("secret-key").

In JavaScript, suppose you have this policy configuration:

<Javascript name='Javascript-1' timeLimit='200' >
  <Properties>
    <Property name='prop1'>my-value-here</Property>
  </Properties>
  <ResourceURL>jsc://readProp.js</ResourceURL>
</Javascript>

...then in JS code, you could access the property like so:

var p = properties.prop1;  // "my-value-here"

Why is this useful? Here's an example: suppose you produce a Javascript callout code that computes the HMACSHA256 of any arbitrary string. You might like to explicitly parameterize that code so that it does not need to read from "magic" context variables. So you could do something like this:

<Javascript name='Javascript-2' timeLimit='200' >
  <Properties>
    <Property name='keyvar'>context_var_containing_key</Property>
    <Property name='payloadvar'>context_var_containing_string_to_hmac</Property>
  </Properties>
  <ResourceURL>jsc://computeHmac.js</ResourceURL>
</Javascript>  

And then in JavaScript, read the properties, and then read the context variables referenced therein. like this:

var key = context.getVariable(properties.keyvar),
    message = context.getVariable(properties.payloadvar);

var hmac = computeHmac(key, "SHA-256", message); 
...

For any policy type, if you are not using the Properties element, then you can omit it from the XML configuration. This is perfectly ok:

<Javascript name='Javascript-3' timeLimit='200' >
  <ResourceURL>jsc://mycode.js</ResourceURL>
</Javascript>

View solution in original post

3 REPLIES 3

gagan
New Member

Tried searching for properties in help doc for other policies, for example:

1. found reference in XML Threat Protection Policy

2. no reference found in Delete OAuth v2.0 Info Policy

even though <properties/> element is present in both policies by default.

Good question! @Gagan Garg

The Properties element can be present in every policy configuration, though it is not used by all of them. Two in particular that DO use the Properties element are the JavaCallout and JavaScript policies.

You can use child Property elements to pass data and information from the flow into the Java or JavaScript code that you write. For example, for a JavaCallout, suppose you have this policy configuration:

<JavaCallout name='JWT-Parse-HS256-2'>
  <Properties>
    <Property name="algorithm">HS256</Property>
    <Property name="jwt">{request.formparam.jwt}</Property>
    <Property name='secret-key'>{request.formparam.key}</Property>
    <!-- verify these specific claims -->
    <Property name="claim_iss">http://vinitmehta.net</Property>
  </Properties>

  <ClassName>com.apigee.callout.jwtsigned.JwtParserCallout</ClassName>
  <ResourceURL>java://jwt-signed-edge-callout.jar</ResourceURL>
</JavaCallout>

In your Java code, the constructor is called with a Map<String,Object> of all of the properties. You can retrieve the values passed as properties there by calling map.get("secret-key").

In JavaScript, suppose you have this policy configuration:

<Javascript name='Javascript-1' timeLimit='200' >
  <Properties>
    <Property name='prop1'>my-value-here</Property>
  </Properties>
  <ResourceURL>jsc://readProp.js</ResourceURL>
</Javascript>

...then in JS code, you could access the property like so:

var p = properties.prop1;  // "my-value-here"

Why is this useful? Here's an example: suppose you produce a Javascript callout code that computes the HMACSHA256 of any arbitrary string. You might like to explicitly parameterize that code so that it does not need to read from "magic" context variables. So you could do something like this:

<Javascript name='Javascript-2' timeLimit='200' >
  <Properties>
    <Property name='keyvar'>context_var_containing_key</Property>
    <Property name='payloadvar'>context_var_containing_string_to_hmac</Property>
  </Properties>
  <ResourceURL>jsc://computeHmac.js</ResourceURL>
</Javascript>  

And then in JavaScript, read the properties, and then read the context variables referenced therein. like this:

var key = context.getVariable(properties.keyvar),
    message = context.getVariable(properties.payloadvar);

var hmac = computeHmac(key, "SHA-256", message); 
...

For any policy type, if you are not using the Properties element, then you can omit it from the XML configuration. This is perfectly ok:

<Javascript name='Javascript-3' timeLimit='200' >
  <ResourceURL>jsc://mycode.js</ResourceURL>
</Javascript>

In the code message = context.getVariable(properties.payloadvar), can we use message = context.getVariable('properties.payloadvar') like with single quotes ?