Java/Java Script policy to handle the dynamic fields Values based on the JSON payload

I have a requirement that Azure JSON payload dynamic flieds values to be captured and transformed to another JSON request.


As per different JSON payloads at https://docs.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-common-schema-definitions

Here the common alert schema may change the fields and also the JSON paths based on alert type. Due to this the AssignMessage policy is failing in Apigee .

For Ex: Following fields values needed to capture and pass the values to another JSON via AssignMessage policy using
<Set><Payload contentType="application/json" variablePrefix="@" variableSuffix="#"></Payload></Set>


If signalType = Metric, capture the following field values

"severity": "Sev3",
"signalType": "Metric",
"monitorCondition": "Fired",
"monitoringService": "Platform",
"description": "Test Metric alert",

If signalType = Activity Log, capture following filed values

"alertRule": "Contoso IT Metric Alert",
"severity": "Sev3",
"signalType": "Activity Log",
"description": "Test Metric alert",

If signalType = Log
.......


Is there any way to capture the required field values irrespective of the JSON schemas via Java/Java Script policy? and pass those values to another JSON?


Java/Java Script policy to handle the dynamic field Valaues based on the JSON payload

0 3 92
3 REPLIES 3

You can do what you want but you'll need several steps and conditions. It sounds to me from your description that based on ONE field within a JSON payload ("signalType") , you want to extract different subsets of fields from that same payload.

if signalType is.... ...then extract
Metric severity, monitorCondition, monitoringService, description
Activity Log severity, alertRule, description
Log ???

The way to do this in Apigee is

  • first, extract signalType
  • Then configure N distinct AssignMessage policies with different configurations and jsonpaths
  • Use Conditions around the AM policies

like this

 

<Flow>
  <Request>
    <Step> 
      <Name>AM-Extract-SignalType</Name> 
    </Step>
    <Step> 
      <Name>AM-Extract-Fields-for-Metric</Name> 
      <Condition>extracted-signalType = "Metric"</Condition>
    </Step>
    <Step> 
      <Name>AM-Extract-Fields-for-ActivityLog</Name> 
      <Condition>extracted-signalType = "Activity Log"</Condition>
    </Step>
     ...

 

The first policy should be something like this:

 

<AssignMessage name='AM-Extract-SignalType'>
  <AssignVariable>
    <Name>path-signalType</Name> 
    <Value>$.data.essentials.signalType</Value>
  </AssignVariable>
  <AssignVariable>
    <Name>extracted-signalType</Name> 
    <Value>BADDBEEF</Value>
    <Template>{jsonPath(path-signalType,request.content)}</Template>
  </AssignVariable>
</AssignMessage>

 

TheAM-Extract-Fields-for-Metric policy might look like this:

 

<AssignMessage name='AM-Extract-Fields-for-Metric'>
  <AssignVariable>
    <Name>path-severity</Name> 
    <Value>$.data.essentials.severity</Value>
  </AssignVariable>
  <AssignVariable>
    <Name>path-monitorCondition</Name> 
    <Value>$.data.essentials.monitorCondition</Value>
  </AssignVariable>
  <AssignVariable>
    <Name>path-monitoringService</Name> 
    <Value>$.data.essentials.monitoringService</Value>
  </AssignVariable>
  <AssignVariable>
    <Name>path-description</Name> 
    <Value>$.data.essentials.description</Value>
  </AssignVariable>
  <Set>
    <Payload contentType='application/json'>{
  "severity" : "{jsonPath(path-severity,request.content)}",
  "description" : "{jsonPath(path-description,request.content)}",
  "monitorCondition" : "{jsonPath(path-monitorCondition,request.content)}",
  "monitoringService" : "{jsonPath(path-monitoringService,request.content)}"
}</Payload>
  </Set>
</AssignMessage>

 

And then I think you can figure out what the other AM policies should look like.

Or, as suggested by your own subject line, you could do this in a single JavaScript policy. It would look somehting like this: 

var c1 = JSON.parse(context.getVariable('request.content'));
var signalType = c1.data.essentials.signalType;
var c2 = {
    "signalType" : c1.data.essentials.signalType,
    "severity" : c1.data.essentials.severity,
    "description" : c1.data.essentials.description
    };
if (signalType == 'Metric') {
  c2.monitorCondition = c1.data.essentials.monitorCondition;
  c2.monitoringService = c1.data.essentials.monitoringService;
}
else if (signalType == 'Activity Log') {
  c2.alertRule = c1.data.essentials.alertRule;
}
else {
  ...
}
context.setVariable('modified-content', JSON.stringify(c2, null, 2));

Resume back on it. 

Thanks for the solution.