Hi,
How can I assign a variable using assign message with a JSON with apigee flow variable as JSON attributevalue . I want my variable to be assigned with below JSON where JSON attribute values are flow variables.
{"system_timestamp":"{system.time.year}-{system.time.month}-{system.time.day}T{system.time.hour}:{system.time.minute}:{system.time.second}.{system.time.millisecond}Z", "TransactionId":"{request.header.TransactionId}"}
1 Like
Hi @Krish, this can be done in multiple ways using JS/Assign Message. I have used Assign Message policy, do have a look and modify the logic/config as required.
Method 1 -
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-1">
<DisplayName>Assign Message-1</DisplayName>
<Properties/>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<Set>
<Payload contentType="application/json" variablePrefix="%" variableSuffix="#">
{
"system_timestamp": "%system.time.year#-%system.time.month#-%system.time.day#T%system.time.hour#:%system.time.minute#:%system.time.second#.%system.time.millisecond#Z",
"TransactionId": "%request.header.TransactionId#"
}
</Payload>
</Set>
<AssignVariable>
<Name>final-variable</Name>
<Ref>message.content</Ref>
</AssignVariable>
</AssignMessage>
Method 2 -
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-1">
<DisplayName>Assign Message-1</DisplayName>
<Properties/>
<AssignVariable>
<Name>TransactionId</Name>
<Ref>request.header.TransactionId</Ref>
<Value>some-static-value</Value>
</AssignVariable>
<AssignVariable>
<Name>year</Name>
<Ref>system.time.year</Ref>
</AssignVariable>
<AssignVariable>
<Name>month</Name>
<Ref>system.time.month</Ref>
</AssignVariable>
<AssignVariable>
<Name>day</Name>
<Ref>system.time.day</Ref>
</AssignVariable>
<AssignVariable>
<Name>hour</Name>
<Ref>system.time.hour</Ref>
</AssignVariable>
<AssignVariable>
<Name>minute</Name>
<Ref>system.time.minute</Ref>
</AssignVariable>
<AssignVariable>
<Name>second</Name>
<Ref>second</Ref>
</AssignVariable>
<AssignVariable>
<Name>millisecond</Name>
<Ref>system.time.millisecond</Ref>
</AssignVariable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<!-- using set payload to form a app/json payload ------------------>
<Set>
<Payload contentType="application/json" variablePrefix="%" variableSuffix="#">
{
"system_timestamp": "%year#-%month#-%day#T%hour#:%minute#:%second#%millisecond#Z",
"TransactionId": "%TransactionId#"
}
</Payload>
</Set>
<!-- Setting final variable --------------------------------------->
<AssignVariable>
<Name>final-variable</Name>
<Ref>message.content</Ref>
</AssignVariable>
</AssignMessage>
Final Response/Variable Output,
{
"system_timestamp": "2018-10-31T0:44:15.68Z",
"TransactionId": "TRAN10790"
}
1 Like
Hi @Siddharth Barahalikar
Thank you for the suggestion. However, this will not work as in both the approach message content is getting changed. I donât want that. I want to keep message.content as is, just want to create a flow variable which i want to use in post client flow.
1 Like
You just want this JSON as it is saved in a variable so that you can use it in MLP?
{"system_timestamp":"{system.time.year}-{system.time.month}-{system.time.day}T{system.time.hour}:{system.time.minute}:{system.time.second}.{system.time.millisecond}Z", "TransactionId":"{request.header.TransactionId}"}
Something like this?
<AssignVariable>
<Name>final-variable</Name>
<Value>{"system_timestamp":"{system.time.year}-{system.time.month}-{system.time.day}T{system.time.hour}:{system.time.minute}:{system.time.second}.{system.time.millisecond}Z", "TransactionId":"{request.header.TransactionId}"}</Value>
</AssignVariable>
1 Like
FYI
you do not need variablePrefix=â%â and so on. Since sometime in 2015, you can do this:
<Payload contentType="application/json" >
{
"system_timestamp": "{year}-{month}-{day}T{hour}:{minute}:{second}{millisecond}Z",
"TransactionId": "{TransactionId}"
}
</Payload>
I personally find the curly braces to be easier on the eyes.
1 Like
@Dino-at-Google yes it works without %. However it does solve my issue as I donât want to change the payload. I want to assign the json to a variable which i can use in post client flow.
1 Like
Yes. you are right. However below assign variable doesnât work as you suggested.
<AssignVariable>
<Name>final-variable</Name>
<Value>{"system_timestamp":"{system.time.year}-{system.time.month}-{system.time.day}T{system.time.hour}:{system.time.minute}:{system.time.second}.{system.time.millisecond}Z", "TransactionId":"{request.header.TransactionId}"}</Value>
</AssignVariable>
1 Like
ah, I understand. To avoid the problem, use createNew=true to create a NEW message, rather than over-writing the payload in the existing message. Like this:
<AssignMessage name="Assign-Message-1">
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew='true' transport='http' type='request'>contrivedMessage</AssignTo>
<Set> ...</Set>
<AssignVariable>
<Name>destination_variable</Name>
<Ref>contrivedMessage.content</Ref>
</AssignVariable>
</AssignMessage>
BUT!! You donât need this any longer. You do not need to create a contrived message in order to get message template magic. You can just assign directly using the AssignVariable with the Template child element. Like this:
<AssignMessage name='AM-1'>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignVariable>
<Name>my_destination_variable</Name>
<Value>BADDBEEF</Value>
<Template>{
"system_timestamp": "{year}-{month}-{day}T{hour}:{minute}:{second}{millisecond}Z",
"TransactionId": "{TransactionId}"
}</Template>
</AssignVariable>
</AssignMessage>
If you really are formatting a timestamp, thereâs an opportunity to improve that a little more with the message template function âtimeFormatUTCMsâ, like this:
<AssignMessage name='AM-2'>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignVariable>
<Name>timeFormatString1</Name>
<Value>yyyyMMdd-HHmmss</Value>
</AssignVariable>
<AssignVariable>
<Name>formatted_time</Name>
<Template>{timeFormatUTCMs(timeFormatString1,system.timestamp)}</Template>
</AssignVariable>
<AssignVariable>
<Name>my_destination_variable</Name>
<Template>{
"system_timestamp": "{formatted_time}",
"TransactionId": "{TransactionId}"
}</Template>
</AssignVariable>
</AssignMessage>
See more examples here: https://github.com/DinoChiesa/ApigeeEdge-MessageTemplate-Demo
1 Like
@Dino-at-Google Is tag new thing, cause I am getting validation error while saving the change. BTW I am using 18.5. However, it works in the apigee cloud.
Error Saving Revision
Error occurred while validation of bean AM-1.xml. Reason: - Schema validation failed. Cause : unexpected element (uri:ââ, local:âTemplateâ). Expected elements are <{}Ref>,<{}Value>,<{}Name>. Line number : 7. Column number : 20. File name : AM-1.xml..
If is available only in the latest version(>18.5), can you suggest how can I achieve this in 18.5 apigee version?
1 Like
@Dino-at-Google In your first approach, no other policy executes after assign message with createNew=true. I have added this assign message policy in fault rules and after that, I have one RF policy, the RF policy doesnât execute if I keep createNew=true, If I change to createNew=false, RF executes.
I need RF policy to execute regardless.
1 Like
yes, the Template element is a new thing, added only to the cloud for now.
I suppose it will be in OPDK 19.01, but I am not certain of that.
If you would like to resolve message templates like this, but in prior releases, then you can do something like this in JavaScript:
var resolveVariableReferences = (function (){
var variableNameRe = "[^ \t\n\"',/\\\\{}]+?"; // non-greedy capture
var varPrefixRe = '{';
var varSuffixRe = '}';
var variableRegex = new RegExp( varPrefixRe + '(' + variableNameRe + ')' + varSuffixRe);
function resolveVariableReferences(s) {
var match = variableRegex.exec(s);
while (match){
var variableName = match[1];
var value = context.getVariable(variableName);
if (value && value !== '') {
s = s.replace('{' + variableName + '}', value);
}
match = variableRegex.exec(s);
}
return s;
}
return resolveVariableReferences;
}());
var template = "https://{endpoint}/api/User?userId={accesstoken.user.login}";
var resolvedValue = resolveVariableReferences(template);
context.setVariable('resolved-template', resolvedValue);
can you show me the flow? I understand the words but what youâre describing is not making sense to me.
1 Like
@Dino-at-Google
I found the problem. Now I am able to create a variable with a json message contrivedMessage.content using the assign message policy.
But when i use the same variable in message logging, message is not formatted as json in sumologic.
If i use
{contrivedMessage.content}
message is coming without starting {.
If i use {contrivedMessage.content}
message is coming { âtestâ:âvalueâ}.
As it is coming with \ sumologic could not parse it as json.
Before when i used to formed the json log in the message logging policy as below, message used to come to sumo as json message.
{âsystem_timestampâ:â{system.time.year}â}
1 Like