Saturday, 12 January 2019

Camel: Custom Type Converter


You can create custom type converter by implementing ‘TypeConverter’ interface (or) by extending TypeConverterSupport class.

For example, lets try to implement a converter, that convert an order id (which is an integer) to Order object.

In this example, all my orders are stored in file system. Each file has the order id as content.

C:\Users\Public\demoOrders folder contains all the order numbers in a files. Each file represents one unique order. To make the things simple, demoOrders folder contains 'order-10-31-2018.txt' file.

order-10-31-2018.txt
1

Step 1: Create the type converter.
public class OrderConverter extends TypeConverterSupport {

	@Override
	public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException {

		/* Get the order from GenericFile */
		if (value.getClass().equals(GenericFile.class)) {
			System.out.println("Converting GenericFile to Order");
			GenericFile genericFile = (GenericFile) value;
			File file = (File) genericFile.getBody();
			String content;
			try {
				content = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
				int orderId = Integer.parseInt(content);
				return (T) OrdersInfo.getOrder(orderId);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		/* Get the string representaion from order */
		if (value.getClass().equals(Order.class)) {
			System.out.println("Converting Order to String");
			return (T) value.toString();
		}

		/* Get the order from string */
		if (value.getClass().equals(String.class)) {
			System.out.println("Converting String to Order");
			int orderId = Integer.parseInt(value.toString());
			return (T) OrdersInfo.getOrder(orderId);
		}

		return null;
	}

}

Step 2: Register the type converter with camel context.
CamelContext context = new DefaultCamelContext();
context.getTypeConverterRegistry().addTypeConverter(Order.class, GenericFile.class, new OrderConverter());
context.getTypeConverterRegistry().addTypeConverter(String.class, Order.class, new OrderConverter());

context.getTypeConverterRegistry().addTypeConverter(Order.class, GenericFile.class, new OrderConverter());
This statement converts the content of GenericFile to Order object.

context.getTypeConverterRegistry().addTypeConverter(String.class, Order.class, new OrderConverter());
This statement converts the content of order to string.
        
Find the below working application.


Order.java
package com.sample.app.model;

public class Order {
	private int id;
	private String description;

	public Order(int id, String description) {
		this.id = id;
		this.description = description;
	}

	@Override
	public String toString() {
		return "Order [id=" + id + ", description=" + description + "]";
	}

}


OrdersInfo.java
package com.sample.app.storage;

import java.util.HashMap;
import java.util.Map;

import com.sample.app.model.Order;

public class OrdersInfo {

	private static Map<Integer, Order> map = new HashMap<> ();
	
	static {
		map.put(1,  new Order(1, "prod1:5, prod2:10, prod19:1"));
		map.put(2,  new Order(1, "prod1:6, prod2:11, prod19:2"));
		map.put(3,  new Order(1, "prod1:7, prod2:12, prod19:3"));
		map.put(4,  new Order(1, "prod1:8, prod2:13, prod19:4"));
	}
	
	public static Order getOrder(int orderId) {
		return map.get(orderId);
	}
}


OrderConverter.java
package com.sample.app.converters;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.apache.camel.Exchange;
import org.apache.camel.TypeConversionException;
import org.apache.camel.component.file.GenericFile;
import org.apache.camel.support.TypeConverterSupport;

import com.sample.app.model.Order;
import com.sample.app.storage.OrdersInfo;

public class OrderConverter extends TypeConverterSupport {

	@Override
	public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException {

		/* Get the order from GenericFile */
		if (value.getClass().equals(GenericFile.class)) {
			System.out.println("Converting GenericFile to Order");
			GenericFile genericFile = (GenericFile) value;
			File file = (File) genericFile.getBody();
			String content;
			try {
				content = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
				int orderId = Integer.parseInt(content);
				return (T) OrdersInfo.getOrder(orderId);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		/* Get the string representaion from order */
		if (value.getClass().equals(Order.class)) {
			System.out.println("Converting Order to String");
			return (T) value.toString();
		}

		/* Get the order from string */
		if (value.getClass().equals(String.class)) {
			System.out.println("Converting String to Order");
			int orderId = Integer.parseInt(value.toString());
			return (T) OrdersInfo.getOrder(orderId);
		}

		return null;
	}

}


Application.java
package com.sample.app;

import java.util.concurrent.TimeUnit;

import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.file.GenericFile;
import org.apache.camel.impl.DefaultCamelContext;

import com.sample.app.converters.OrderConverter;
import com.sample.app.model.Order;

public class Application {

	public static class FileCopyRoute extends RouteBuilder {

		@Override
		public void configure() throws Exception {
			System.out.println("Inside file Copy Route");
			from("file:C:\\Users\\Public\\demoOrders?noop=true").convertBodyTo(Order.class).convertBodyTo(String.class)
					.to("file:C:\\Users\\Public\\demoCopy");
		}

	}

	public static void main(String args[]) throws Exception {
		CamelContext context = new DefaultCamelContext();

		context.getTypeConverterRegistry().addTypeConverter(Order.class, GenericFile.class, new OrderConverter());
		context.getTypeConverterRegistry().addTypeConverter(String.class, Order.class, new OrderConverter());

		context.addRoutes(new FileCopyRoute());

		context.start();

		TimeUnit.MINUTES.sleep(1);

		context.stop();
	}
}

Run Application.java, you can see below messages in console.
Inside file Copy Route
Converting GenericFile to Order
Converting Order to String

Go to the directory ‘C:\Users\Public\demoCopy’, you can see the file ‘order-10-31-2018.txt’ with below content.

order-10-31-2018.txt
Order [id=1, description=prod1:5, prod2:10, prod19:1]


Previous                                                 Next                                                 Home<

No comments:

Post a Comment