Monday, April 17, 2017

How to access transport headers inside the custom message formatter.

Find the blow custom formatter class and you can see the way we access the transport headers.

package com.wso2.sample.formatter;

import org.apache.axiom.om.OMOutputFormat;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.MessageFormatter;

import java.io.OutputStream;
import java.net.URL;
import java.util.Map;
import java.util.Set;

public class CustomMessageFormatter implements MessageFormatter {

    public void writeTo(MessageContext messageContext, OMOutputFormat omOutputFormat, OutputStream outputStream, boolean b) throws AxisFault {
        Map headerMap = (Map) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS);
        Set keySet = headerMap.keySet();
        for (String key : keySet) {
            System.out.println(key + " >> " + headerMap.get(key));
        }
    }

    public String getContentType(MessageContext messageContext, OMOutputFormat omOutputFormat, String s) {
        return null;
    }

    public URL getTargetAddress(MessageContext messageContext, OMOutputFormat omOutputFormat, URL url) throws AxisFault {
        return null;
    }

    public String formatSOAPAction(MessageContext messageContext, OMOutputFormat omOutputFormat, String s) {
        return null;
    }

    public byte[] getBytes(MessageContext messageContext, OMOutputFormat omOutputFormat) throws AxisFault {
        return new byte[0];
    }
}

Note: You can get the transport headers using getProperty(MessageContext.TRANSPORT_HEADERS). Transport headers comes as key and value pairs (Map).

According to the above sample you can print the headers as below

Accept >> */*
Accept-Encoding >> gzip, deflate
Accept-Language >> en-US,en;q=0.8
Cache-Control >> no-cache
Content-Type >> application/xml
Host >> tharanga:8280
Origin >> chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Postman-Token >> 8e78f643-842c-175a-69c0-3a94e1ba1950
Sample-Custom-header >> Test value

How to use custom handler in WSO2 APIM

In this article, I'm going to explain how to custom handler in WSO2 APIM

You can follow below steps
  1. Implement sample handler. You can follow this blog to write a custom handler.
  2. Create a jar file
  3. Add the jar file to the <APIM_HOME>/repository/components/lib
  4.  Login to the management console 
  5. Go to the Main menu -> Service Bus -> Source View
  6. Add the below configuration to the API, handlers configuration section
<handler class="com.wso2.sample.handler.CustomHandler"></handler>

How to write handler class for WSO2 APIM?

In this article, I'm going to cover below areas
  1. How to write custom handler 
  2. How to get the request and response payload
Find the below sample custom handler to cover above scenarios.

package com.wso2.sample.handler;

import org.apache.axis2.context.MessageContext;
import org.apache.commons.io.IOUtils;

import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.rest.AbstractHandler;
import org.apache.synapse.transport.passthru.util.RelayUtils;

import java.io.InputStream;
import java.io.StringWriter;

public class CustomHandler extends AbstractHandler {

    public boolean handleRequest(org.apache.synapse.MessageContext messageContext) {
        try {
            RelayUtils.buildMessage(((Axis2MessageContext) messageContext).getAxis2MessageContext());
            InputStream jsonPaylodStream = (InputStream) ((Axis2MessageContext) messageContext)
                    .getAxis2MessageContext().getProperty(
                            "org.apache.synapse.commons.json.JsonInputStream");
            StringWriter writer = new StringWriter();
            IOUtils.copy(jsonPaylodStream, writer);
            // You can get the request message here
            String payloadMessge = writer.toString();
            System.out.println("Request payload message :" + payloadMessge);
            return true;
        } catch (Exception ex) {
            return true;
        }
    }

    public boolean handleResponse(org.apache.synapse.MessageContext messageContext) {
        try {
            RelayUtils.buildMessage(((Axis2MessageContext) messageContext).getAxis2MessageContext());

            InputStream jsonPaylodStream = (InputStream) ((Axis2MessageContext) messageContext)
                    .getAxis2MessageContext().getProperty(
                            "org.apache.synapse.commons.json.JsonInputStream");
            StringWriter writer = new StringWriter();
            IOUtils.copy(jsonPaylodStream, writer);
            // You can get the response message here
            String payloadMessge = writer.toString();
            System.out.println("Response payload message :" + payloadMessge);
            return true;
        } catch (Exception ex) {
            return true;
        }
    }
}

Before access the payload, we need to build the message, so, we can build the message as below
RelayUtils.buildMessage(((Axis2MessageContext) messageContext).getAxis2MessageContext());

After that you can access the payload with below code segment.
  InputStream jsonPaylodStream = (InputStream) ((Axis2MessageContext) messageContext)
          .getAxis2MessageContext().getProperty(
                   "org.apache.synapse.commons.json.JsonInputStream");
  StringWriter writer = new StringWriter();
  IOUtils.copy(jsonPaylodStream, writer);
  // You can get the response message here
  String payloadMessge = writer.toString();

Tuesday, April 11, 2017

How to access transport headers in WSO2 custom formatter?

You can access the transport header using messageContext.getProperty as below. (Transport header stored under TRANSPORT_HEADERS property.)

Map<String, Object> headerMap = 
      (Map<String, Object>) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS);

Find the below sample formatter

package com.wso2.sample.formatter;

import org.apache.axiom.om.OMOutputFormat;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.MessageFormatter;

import java.io.OutputStream;
import java.net.URL;
import java.util.Map;
import java.util.Set;

public class SampleFormatter implements MessageFormatter {

    public void writeTo(MessageContext messageContext, OMOutputFormat omOutputFormat, OutputStream outputStream, boolean b) throws AxisFault {
        Map<String, Object> headerMap = (Map<String, Object>) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS);
        Set<String> keySet = headerMap.keySet();
        for (String key : keySet) {
            System.out.println(key + " >> " + headerMap.get(key));
        }
    }

    public String getContentType(MessageContext messageContext, OMOutputFormat omOutputFormat, String s) {
        return null;
    }

    public URL getTargetAddress(MessageContext messageContext, OMOutputFormat omOutputFormat, URL url) throws AxisFault {
        return null;
    }

    public String formatSOAPAction(MessageContext messageContext, OMOutputFormat omOutputFormat, String s) {
        return null;
    }

    public byte[] getBytes(MessageContext messageContext, OMOutputFormat omOutputFormat) throws AxisFault {
        return new byte[0];
    }
}

Now you can see the transport headers in as below. (According to the above sample it displayed in the carbon log file)

Accept >> */*
Accept-Encoding >> gzip, deflate
Accept-Language >> en-US,en;q=0.8
Cache-Control >> no-cache
Content-Type >> application/xml
Host >> tharanga:8280
Origin >> chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Postman-Token >> 8e78f643-842c-175a-69c0-3a94e1ba1950