Resource bundle type functionality

Not applicable

We are customizing messages returned for conditions that arise within Edge and need to use a concept of Resource bundles for the usual reasons - to provide locale specific support, message reuse and externalization.

What is the best practice for this? Storing messages in a KVM does not seem plausible since I can't directly query the KVM in Javascript without first using a KVM policy to reassign everything to variables which seems rather convoluted.

Is there a way that I can upload a property file as a scoped resource and easily use it within that scope in my policies including all scripts?

If this is not supported I am thinking perhaps I can create an environment or organization scoped Javascript file with a structure encapsulating the sections for each locale, something like below. I would prefer to use something built into Apigee if it exists... thoughts?

var messages = 
    [
     { locale_code : "en-US", 
       entries : [{msg_key : "welcome.msg", 
                   msg_value : "welcome to {0}"}, 
                  {msg_key : "thankyou.msg", 
                   msg_value : "thank you!"}] },
     { locale_code : "es-AR", 
       entries : [{msg_key : "welcome.msg", 
                   msg_value : "beinvenidos a {0}"}, 
                  {msg_key : "thankyou.msg", 
                   msg_value : "gracias!"}] }
     ];

Solved Solved
1 2 124
1 ACCEPTED SOLUTION

You can, in fact, configure an organization-wide or environment-wide resource.

It's not exposed in the Administrative UI for Apigee Edge, currently, but it is possible in the Administrative API. (See the documentation for this API).

For example, suppose you have this JS file:

var messages = {
    "en-US": {
      "welcome": "welcome to {0}",
      "thankyou" : "thank you!"
    } ,
    "es-AR" : {
      "welcome" : "beinvenidos a {0}",
      "thankyou": "gracias!"
    }
  };

You can load that into an environment-specific resource, like so:

curl -i -X POST -n \
   -H content-type:application/octet-stream \
   -H accept:application/json \
   'https://api.enterprise.apigee.com/v1/o/MYORG/e/test/resources?name=messages.js&type=jsc' \
   --upload-file /Users/me/examples/messages.js 

If you want to UPDATE that file after it already exists, you should use PUT:

curl -i -X PUT -n \
   -H content-type:application/octet-stream \
   -H accept:application/json \
   'https://api.enterprise.apigee.com/v1/o/MYORG/e/test/resources/jsc/messages.js' \
   --upload-file /Users/me/examples/messages.js 

Then, configure your JavaScript policy like so:

<Javascript timeLimit="200" name="JavaScript-1">
    <Properties/>
    <IncludeURL>jsc://messages.js</IncludeURL>
    <ResourceURL>jsc://JavaScript-1.js</ResourceURL>
</Javascript>

And then, in your Javascript-1.js file, do something like this:

function applySubstitution(template, a) {
  function replacer(match, p1, p2, p3, offset, string) {
    var index = p2.slice(1,-1);
    if (a[index]) {
      return p1 + a[index] + p3;
    }
    return p1 + '??' + p3;
  }
  var re1 = new RegExp('([^{}]*)({[0-9]+})([^{}]*)','g');
  return template.replace(re1,replacer);
}

var locale = 'en-US';
var personName = 'Kevin';
var entries = messages[locale] ? messages[locale] : messages['en-US'];
var template = entries['welcome'] ? entries['welcome'] : "Welcome, dude!" ;
context.setVariable('response.content', applySubstitution(template, [personName]));


The variable 'messages' will be known and resolvable when executing the Javacript-1.js file.

View solution in original post

2 REPLIES 2

You can, in fact, configure an organization-wide or environment-wide resource.

It's not exposed in the Administrative UI for Apigee Edge, currently, but it is possible in the Administrative API. (See the documentation for this API).

For example, suppose you have this JS file:

var messages = {
    "en-US": {
      "welcome": "welcome to {0}",
      "thankyou" : "thank you!"
    } ,
    "es-AR" : {
      "welcome" : "beinvenidos a {0}",
      "thankyou": "gracias!"
    }
  };

You can load that into an environment-specific resource, like so:

curl -i -X POST -n \
   -H content-type:application/octet-stream \
   -H accept:application/json \
   'https://api.enterprise.apigee.com/v1/o/MYORG/e/test/resources?name=messages.js&type=jsc' \
   --upload-file /Users/me/examples/messages.js 

If you want to UPDATE that file after it already exists, you should use PUT:

curl -i -X PUT -n \
   -H content-type:application/octet-stream \
   -H accept:application/json \
   'https://api.enterprise.apigee.com/v1/o/MYORG/e/test/resources/jsc/messages.js' \
   --upload-file /Users/me/examples/messages.js 

Then, configure your JavaScript policy like so:

<Javascript timeLimit="200" name="JavaScript-1">
    <Properties/>
    <IncludeURL>jsc://messages.js</IncludeURL>
    <ResourceURL>jsc://JavaScript-1.js</ResourceURL>
</Javascript>

And then, in your Javascript-1.js file, do something like this:

function applySubstitution(template, a) {
  function replacer(match, p1, p2, p3, offset, string) {
    var index = p2.slice(1,-1);
    if (a[index]) {
      return p1 + a[index] + p3;
    }
    return p1 + '??' + p3;
  }
  var re1 = new RegExp('([^{}]*)({[0-9]+})([^{}]*)','g');
  return template.replace(re1,replacer);
}

var locale = 'en-US';
var personName = 'Kevin';
var entries = messages[locale] ? messages[locale] : messages['en-US'];
var template = entries['welcome'] ? entries['welcome'] : "Welcome, dude!" ;
context.setVariable('response.content', applySubstitution(template, [personName]));


The variable 'messages' will be known and resolvable when executing the Javacript-1.js file.

thanks Dino!