java custom logic after reading data from BaaS

Not applicable
after fetching results from BaaS, i want to add custom java logic on data before response is sent to client. please suggest if it is possible and where i can get some sample code for this. thanks
Solved Solved
1 11 699
1 ACCEPTED SOLUTION

Either Java or Javascript callouts can be used in the Response flow of an Apigee Edge proxy. Within those callouts you can inspect or modify the response. It is super simple to do this in Javascript. For example, in Javascript:

var c = context.getVariable('response.content'); 

c = JSON.parse(c);

c.additionalProperty = "This is an additional property";

if (c.existingProperty) {
  delete c.existingProperty;  // remove an existing property
}

context.setVariable('response.content', JSON.stringify(c));

You can also do similar things in Java, but it is slightly more complicated, due to the greater degree of structure in Java itself. You could use the Jackson library to parse and stringify JSON, for example in Java.

View solution in original post

11 REPLIES 11

Not applicable
Are you doing this in Apigee Edge? If so you can use a JavaCallout to execute Java code, but Javascript might be a better bet, and better yet, Node.js. Are those options? Your best bet for this is going to be using Node.js since it enables you to make parallel calls and aggregate the responses. Have you looked into Node.js for this?

As i understand from apigee docs, javaCallout is used to process input request (adding extra params etc) and then passing request further to BaaS. but my requirement is like i will get multiple results from BaaS and want to return an aggregated(processed) response to client. i may use apigee edge for BaaS. hope i could clarify my requirement. thanks

You can use Java on both sides of the request - inbound and outbound.

Hi Anurag, If you could point me to the location in the Apigee documentation that gives the impression that Java can be used only for the Request flow, I'll get that fixed. Thanks!

Thanks Dino. i looked into an example at http://apigee.com/docs/api-services/cookbook/use-java-customize-api where it was explained how to customize inbound request. i couldn't find a similar for outbound. please point me if there is such example exist.

There is no example that I know of in the documentation which shows how to customize a response using a Java callout. However as far as I know there is also no statement in the documentation that "it is not possible to customize a response using a Java callout." If that is not correct, please advise.

Either Java or Javascript callouts can be used in the Response flow of an Apigee Edge proxy. Within those callouts you can inspect or modify the response. It is super simple to do this in Javascript. For example, in Javascript:

var c = context.getVariable('response.content'); 

c = JSON.parse(c);

c.additionalProperty = "This is an additional property";

if (c.existingProperty) {
  delete c.existingProperty;  // remove an existing property
}

context.setVariable('response.content', JSON.stringify(c));

You can also do similar things in Java, but it is slightly more complicated, due to the greater degree of structure in Java itself. You could use the Jackson library to parse and stringify JSON, for example in Java.

my BaaS results me n number of records for a query. i want to aggregate them by a custom logic in java before sending back to mobile device. can you suggest me a java example for the same. thanks.

Yes, @Anurag Goyal , I think you could use the jackson JSON library, like this:

public ExecutionResult execute(MessageContext msgCtxt,
                               ExecutionContext exeCtxt) {
    String varName;
    String varprefix = "agg";
    try {
        Message msg = msgCtxt.getMessage();
        InputStream src = msg.getContentAsStream();
        BaasReply reply = mapper.readValue(src, BaasReply.class);


        // perform aggregation here....


        // serialize the modified reply back to JSON here....
        String result = mapper.writer()
            .withDefaultPrettyPrinter()
            .writeValueAsString(reply));


        varName = varprefix + "_modified";
        msgCtxt.setVariable(varName, result);
    }
    catch (Exception e) {
        e.printStackTrace();
        varName = varprefix + "_error";
        msgCtxt.setVariable(varName, "Exception " + e.toString());
        varName = varprefix + "_stacktrace";
        msgCtxt.setVariable(varName, ExceptionUtils.getStackTrace(e));
        return ExecutionResult.ABORT;
    }
    return ExecutionResult.SUCCESS;
}


This will require the mapper object to be a class member. Create it in the constructor as follows:

private ObjectMapper mapper; // can reuse, share globally
private Map properties; // read-only
public AggregatorCallout (Map properties) {
    this.properties = properties;
    mapper =
        new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);


}

This callout code requires these imports of libraries available in Edge:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;

import org.apache.commons.lang.exception.ExceptionUtils;

...and you must compile with these jars:

 expressions-1.0.0.jar
 message-flow-1.0.0.jar
 jackson-core-2.3.0.jar
 jackson-databind-2.3.0.jar
 jackson-coreutils-1.6.jar
 jackson-annotations-2.3.0.jar
 commons-lang-2.6.jar

The BaasReply type looks something like this:

import java.util.List;


public class BaasReply {
    public String action;
    public String application;
    public String path;
    public String uri;
    public List<BaasCustomEntity> entities;
    public long timestamp;
    public int duration;
    public String organization;
    public String applicationName;
    public int count;
}


And the BaasCustomEntity is similar, but it models your own custom entity.

Edit: I've attached a zip containing the code here.

Thanks Dino. i will try it out.

zip for java source attached here.