Thursday, June 25, 2009

Using Camel to direct messages to a Printer using a camel-printer component

I have recently made a feature submission of a camel-printer component to the Apache Camel community. I believe it will be available in Apache Camel 2.1 release cycle.

You can follow the submission to the Apache community at the following JIRA link

https://issues.apache.org/activemq/browse/CAMEL-1675

The objective of this component is to provide a way to direct payloads on a route to a printer. Obviously the payload has to be a formatted piece of payload in order for the component to appropriately print it. The objective is to be able to direct specific payloads as jobs to a line printer in a camel flow.

The functionality allows for the payload to be printed on a default, local remote or wirelessly linked printer using the javax printing API under the covers.

Since the URI scheme for a printer has not been standardized (the nearest thing to a standard being the IETF print standard) and therefore not uniformly applied by vendors, I have chosen "lpr" as the scheme.

There is choice for setting the following options in the printer URI

Printer options

- mediasize: to set the stationary as defined by
enumeration settings in the
javax.print.attribute.standard.MediaSizeName API.
- copies: to set number of copies based on the
javax.print.attribute.standard.Copies API
- sides: to set one sided or two sided printing based on the
javax.print.attribute.standard.Sides API


The way this camel printer works in Camel is as follows

Example 1: Printing text based payloads on a Default printer using letter stationary and one-sided mode

RouteBuilder builder = new RouteBuilder() {
public void configure() {
from(file://inputdir/?delete=true)
.to("lpr://localhost/default?copies=2" +
"&flavor=DocFlavor.INPUT_STREAM&" +
"&mimeType=AUTOSENSE" +
"&mediaSize=na-letter" +
"&sides=one-sided")
}
};


Example 2: Printing GIF based payloads on a Remote printer using A4 stationary and one-sided mode

RouteBuilder builder = new RouteBuilder() {
public void configure() {
from(file://inputdir/?delete=true)
.to("lpr://remotehost/sales/salesprinter" +
"?copies=2&sides=one-sided" +
"&mimeType=GIF&mediaSize=iso-a4" +
"&flavor=DocFlavor.INPUT_STREAM")
}
};


Example 3: Printing JPEG based payloads on a Remote printer using Japanese Postcard stationary and one-sided mode

RouteBuilder builder = new RouteBuilder() {
public void configure() {
from(file://inputdir/?delete=true)
.to("lpr://remotehost/sales/salesprinter" +
"?copies=2&sides=one-sided" +
"&mimeType=JPEG" +
"&mediaSize=japanese-postcard" +
"&flavor=DocFlavor.INPUT_STREAM")
}
};


I hope you like this feature and use it to direct formatted payloads to a printer as part of a camel flow.

Thursday, February 19, 2009

A Camel Dataformat that facilitates symmetric key encryption/decryption of XML payloads at the Payload, XML Element and XML Element Content level

I just developed and submitted a new Dataformat for Camel that facilitates encryption and decryption of XML payloads at the Document, Element and Element Content levels (including simultaneous multi-node encryption using XPATH).

The encrytion capability is based on formats supported using the Apache XML Security (Santuario) project. Encryption/Decryption is "currently" supported using Triple-DES and AES (128, 192 and 256) encryption formats. Additional formats can be easily added later as needed. (Note: The support currently offered is for symmetric encryption. This means the same keyset is needed at both ends of the communication to encrypt/decrypt payloads).

The capability allows Camel users to encrypt/decrypt payloads while being dispatched or received along a route.

The default encrytion format if no algorithm is specified is Triple-DES.

The way it works is as follows

Example 1: Full Payload encryption/decryption

RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("http:www.foo.com/orders")
.marshal().encryptXML()
.unmarshal().encryptXML()
.to("activemq:queue:ORDERS")

}
};


Example 2: Partial Payload Content Only encryption/decryption

RouteBuilder builder = new RouteBuilder() {
public void configure() {
String tagXPATH="//cheesesites/italy/cheese";
boolean secureTagContent = true;

from("http:www.foo.com/orders")
.marshal().encryptXML(tagXPATH, secureTagContent)
.unmarshal().encryptXML(tagXPATH, secureTagContent)
.to("activemq:queue:ORDERS")
}
};


Example 3: Partial Multi Node Payload Content Only encryption/decryption

RouteBuilder builder = new RouteBuilder() {
public void configure() {
String tagXPATH = "//cheesesites/*/cheese";
boolean secureTagContent = true;

from("http:www.foo.com/orders")
.marshal().encryptXML(tagXPATH, secureTagContent)
.unmarshal().encryptXML(tagXPATH, secureTagContent)
.to("activemq:queue:ORDERS")
}
};


Example 4: Partial Payload Content Only encryption/decryption using passPhrase(password)

RouteBuilder builder = new RouteBuilder() {
public void configure() {
String tagXPATH = "//cheesesites/*/cheese";
boolean secureTagContent = true;
byte[] passPhrase = "Just another 24 Byte key".getBytes();

from("http:www.foo.com/orders")
.marshal().encryptXML(tagXPATH, secureTagContent, passPhrase)
.unmarshal()
.encryptXML(tagXPATH, secureTagContent, passPhrase)
.to("activemq:queue:ORDERS")
}
};


Example 5: Payload encryption/decryption using passPhrase with passPhrase Algorithm

RouteBuilder builder = new RouteBuilder() {
public void configure() {
String tagXPATH = "//cheesesites/*/cheese";
boolean secureTagContent = true;
byte[] passPhrase = "Just another 24 Byte key".getBytes();
String algorithm= XMLCipher.TRIPLEDES;

from("http:www.foo.com/orders")
.marshal().encryptXML(tagXPATH , secureTagContent, passPhrase, algorithm)
.unmarshal().encryptXML(tagXPATH, secureTagContent, passPhrase, algorithm)
.to("activemq:queue:ORDERS")
}
};


The other choices for algorithm are

--> XMLCipher.AES_128
--> XMLCipher.AES_192 and
--> XMLCipher.AES_256

For more details on the submission check out the following

https://issues.apache.org/activemq/browse/CAMEL-1360

Sunday, November 30, 2008

A Message Compressor/Decompressor for messages sent using Camel routes

There is tremendous value in message compression of XML based payloads as they are dispatched to remote endpoints utilizing Camel as a mediation router.

Camel supports marshalling and unmarshalling of messages into and out of several different data formats such as JAXB, JSON, HL7 etc. An ability to map a message from XML into a compressed data format such as (ZLIB, GZIP, PKZIP) etc can offer significant advantages with respect to network performance and storage in exchange for a small added cost of message compression.

The messages marshalled using zip compression can be unmarshalled using zip decompression just prior to being consumed at the endpoint. The true value of applying compression during a camel route is that it requires no changes to the source or destination application. Compression takes place just after the message leaves the source application and is picked up by the Camel message listener. The message exchange can now be forwarded/routed via several endpoints in a camel flow. Ideally, the message need be uncompressed only when it arrives at its final destination.

I have implemented this feature/capability and made a submission to the Camel community. I believe this capability is invaluable when you deal with large XML and Text based payloads.

The way this feature is designed to work in Camel is as follows

Example 1: Message Compression

RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("http:www.foo.com/orders")
.marshal().zip(Deflater.BEST_COMPRESSION)
.to("activemq:queue:ORDERS")
}
};


Example 1: Message Decompression

RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("activemq:queue:ORDERS")
.unmarshal().zip()
.bean((MyOrderProcessor.class);
}
};


I hope you like this feature and use it judiciously in an enterprise environment that utilizes Camel as a mediation layer to route messages to their ultimate destinations as a compact set of payloads.

Please find my submission to the Apache community here

https://issues.apache.org/activemq/browse/CAMEL-1133

Monday, November 10, 2008

Easing development in Servicemix 4 using Archetypes

I recently submitted maven archetypes to the Apache Servicemix community for adding ease of use in Servicemix 4 in the following areas
  • An OSGi based Camel maven archetype to ease development of Camel routes for deployment in the Servicemix 4 OSGi container (servicemix-osgi-camel-service-unit)
  • A CXF WSDL first maven archetype to ease development of WSDL first web services (servicemix-osgi-cxf-wsdl-first-service-unit)
  • An CXF Code first archetype to ease development of Code first web services (servicemix-osgi-cxf-code-first-service-unit)

If you are interested in using these archetypes check out the following jira issues at the Apache Servicemix community site. These fixes will be committed into the upcoming release of Servicemix 4.

Thursday, October 16, 2008

Opening up to Open Source

Over the last several years, I have had the opportunity to work on projects utilizing IONA supported versions of Open Source software from the Apache Foundation. I have delivered projects using

  • FUSE ESB (Apache Servicemix)
  • FUSE Message Broker (Apache ActiveMQ)
  • FUSE Services Framework (Apache CXF) and
  • FUSE Mediation Router (Apache Camel)

I have also had the good fortune to work with Eclipse Project chairpersons such as Eric Newcomer and Apache Committers, Thought Leaders and Project chairpersons such as Guillaume Nodet, James Strachan, Bruce Snyder and Dan Kulp.

I have also benefited from the knowledge of my "most excellent" consulting colleagues such as Rich Bonneau, Dhiraj Bokde, Adrian Trenaman, Rohan Mars, Peter Mackinnon, David Greco and many others.

I also developed the Open Source Courseware material for the technology sets mentioned above and delivered customer training, solution workshops and open enrolment classes.

Over the coming weeks, I plan on putting forward articles, use-cases, how-to's and other bits of information to hopefully ease the challenges in applying the above mentioned open source offerings in real world applications.

I hope you find these articles useful and applicable in your environments.