StackCheats

Custom Class Mediators to Convert Payloads

WSO2 Class Mediators: Change Values of a Payload Attribute

July 17, 2019

wso2class-mediators

Intro

Class mediators provide an extended platform to develop user-specific implementations and custom mediation logic in the form of Java classes. In this sheet, we will be developing a custom class mediator to read, manipulate and convert (change) a simple payload to meet our requirements.

Class mediators are designed to use on user-specific custom implementations when there are no other built-in mediators to solve the requirement

Requirement

The requirement is to develop a simple custom class mediator to read and change the value of the name attribute of a given payload from “medium” to “Athiththan”.

The actual payload and the expected converted (changed) payload formats are given below.

-------------------------------------
// request payload || original
{
"post": "WSO2 Class Mediator: Convert Payload",
"dev": {
"name": "medium"
}
}
-------------------------------------
// mediated payload || tconverted
{
"post": "WSO2 Class Mediator: Convert Payload",
"dev" : {
"name": "Athiththan"
}
}
-------------------------------------

Configure

To fabricate our custom class mediator or to generate a maven project, we can follow either

  • using the given pom.xml file to generate a maven project
  • using a custom-developed maven-archetype to generate a maven project

Following sections presents the steps on using given pom.xml and using custom developed-archetype to generate maven projects for our custom implementation.

pom.xml

Create a maven quick-start project and replace the dependencies with the following

<!-- change the packaging to bundle (from jar) to support OSGi -->
<packaging>jar</packaging>
<dependencies>
<!-- apache synapse and related dependencies -->
<dependency>
<groupId>org.apache.synapse</groupId>
<artifactId>synapse-core</artifactId>
<version>2.1.7-wso2v60</version>
</dependency>
<dependency>
<groupId>org.apache.axis2.wso2</groupId
<artifactId>axis2</artifactId
<version>1.6.1.wso2v20</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>wso2-nexus</id
<url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>wso2-nexus</id
<url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
<releases>
<enabled>true</enabled
<updatePolicy>daily</updatePolicy
<checksumPolicy>ignore</checksumPolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId
<artifactId>maven-compiler-plugin</artifactId
<version>2.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- build plugin for OSGi Bundle support -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId
<version>2.3.4</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>
${groupId}
</Bundle-SymbolicName>
<Bundle-Name>${groupId}</Bundle-Name
<Export-Package>
${groupId}.*,
</Export-Package>
<Import-Package>
*; resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

Build using Maven Archetype

Clone or download the custom-developed maven-archetype and run the following command to build and install the archetype locally on your machine to generate boilerplates for our custom class mediators.

WSO2 Mediators Maven Archetype

Maven Archetype for WSO2 Class Mediators

mvn clean install

Then, execute the following command to generate a Maven project (boilerplate)

Change the command according to your required Group ID and Artifact ID arguments

mvn archetype:generate -DarchetypeGroupId=com.athiththan.wso2 \
-DarchetypeArtifactId=wso2-mediators \
-DarchetypeVersion=1.0.0 \
-DgroupId=<Your Group ID> \
-DartifactId=<Your Artifact ID>

Development

Class Mediator

We can develop a custom Class mediator by implementing the Mediator class or by extending the AbstractMediator class. In this sheet, We will discuss developing a custom class mediator by extending the org.apache.synapse.mediators.AbstractMediator class.

The custom mediation logic has to defined inside the mediate() method to get execute

A simple class mediator implementation to convert the name attribute from medium to Athiththan is presented below.

package <your package namespace>;
import org.apache.synapse.MessageContext;
import org.apache.synapse.commons.json.JsonUtil;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.json.JSONObject;
public class CustomMediator extends AbstractMediator {
@Override
public boolean mediate(MessageContext synCtx) {
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) synCtx)
.getAxis2MessageContext();
try {
JSONObject jsonObject = new JSONObject(JsonUtil.jsonPayloadToString(axis2MessageContext));
if (jsonObject.has("dev") && jsonObject.getJSONObject("dev").has("name")
&& "medium".equals((String) jsonObject.getJSONObject("dev").get("name"))) {
jsonObject.getJSONObject("dev").put("name", "Athiththan");
}
JsonUtil.newJsonPayload(axis2MessageContext, jsonObject.toString(), true, true);
} catch (JSONException e) {
e.printStackTrace();
}
return true;
}
}

Build, Run & Test

Build

Execute the following command from our project root folder to build and package our custom mediator implementation.

mvn clean package

As a result, maven will package our implementation as a JAR (Java Archive) artifact, which can be found inside the /target folder.

Run & Test

For demonstration purposes

I will be mocking and using the Token_Endpoint of WSO2 API Manager (2.6.0) and will be referring to the installation path of WSO2 API-M as <API-M_HOME> and our JAR artifact as CM-IMPL-JAR.

  • Copy the CM-IMPL_JAR from the /target folder and paste it inside the <API-M_HOME>/repository/components/lib/ directory
  • Navigate to <API-M_HOME>/repository/deployment/server/synapse-configs/default/api/ and open and edit the inSequence tag of the _TokenAPI_.xml file as follows
<inSequence>
<!-- <property name="uri.var.portnum" expression="get-property('keyManager.port')"/>
<property name="uri.var.hostname" expression="get-property('keyManager.hostname')"/>
<send>
<endpoint>
<http uri-template="https://{uri.var.hostname}:{uri.var.portnum}/oauth2/token">
<timeout>
<duration>60000</duration
<responseAction>fault</responseAction>
</timeout>
</http>
</endpoint>
</send> -->
<!-- convert dev.name to athiththan -->
<class name="<YOUR PACKAGE NAME>.<CLASS NAME>" />
<respond />
</inSequence>

Replace <YOUR PACKAGE NAME>.<CLASS NAME> with the actual package name and your Java class name.

For example …

If you have implemented your class mediator implementation in a Java class named CustomClassMediator inside the com.sample.demos package, then it comes as com.sample.demos.CustomClassMediator resulting <class name="com.sample.demos.CustomClassMediator" />.

After pasting our CM-IMPL_JAR and editing the _TokenAPI_.xml file, start the WSO2 API Manager instance using the following command.

sh wso2server.sh

Use the following cURL command to execute the Token Endpoint of the WSO2 API Manager instance by replacing the <Your Host> tag with respective host value

curl -k --request POST \
-d '{"post":"WSO2 Class Mediator: Convert Payload","dev":{"name":"medium"}}' \
-H "Content-Type: application/json" \
https://<YOUR HOST>:8243/token

After successful execution, we can observe the response as follows

{
"post":"WSO2 Class Mediator: Convert Payload",
"dev":{
"name":"Athiththan"
}
}

GitHub

Revamp Mediator

A custom mediation logic to convert payload attribute values using WSO2 Class Mediator extension


Athiththan Kathirgamasegaran