Download as pdf or txt
Download as pdf or txt
You are on page 1of 69

Camel in Action 1st Edition Claus Ibsen

Jonathan Anstey
Visit to download the full and correct content document:
https://ebookmeta.com/product/camel-in-action-1st-edition-claus-ibsen-jonathan-anst
ey/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Climate Adaptation Modelling 1st Edition Claus Kondrup

https://ebookmeta.com/product/climate-adaptation-modelling-1st-
edition-claus-kondrup/

Dirty Claus 1st Edition M K Moore

https://ebookmeta.com/product/dirty-claus-1st-edition-m-k-moore/

Real Negotiations Driving Values and Handling


Complexities 2nd Edition Robert Ibsen

https://ebookmeta.com/product/real-negotiations-driving-values-
and-handling-complexities-2nd-edition-robert-ibsen/

Sociologists in Action on Inequalities Race Class


Gender and Sexuality 1st Edition Shelley K White
Jonathan M White Kathleen Odell Korgen

https://ebookmeta.com/product/sociologists-in-action-on-
inequalities-race-class-gender-and-sexuality-1st-edition-shelley-
k-white-jonathan-m-white-kathleen-odell-korgen/
Articulating the Action Figure Essays on the Toys and
Their Messages Jonathan Alexandratos Editor

https://ebookmeta.com/product/articulating-the-action-figure-
essays-on-the-toys-and-their-messages-jonathan-alexandratos-
editor/

Scientific publishing and presentation Claus Ascheron

https://ebookmeta.com/product/scientific-publishing-and-
presentation-claus-ascheron/

hapi.js in Action 1st Edition Matt Harrison

https://ebookmeta.com/product/hapi-js-in-action-1st-edition-matt-
harrison/

Terraform in Action 1st Edition Scott Winkler

https://ebookmeta.com/product/terraform-in-action-1st-edition-
scott-winkler/

Pandas in Action 1st Edition Boris Paskhaver

https://ebookmeta.com/product/pandas-in-action-1st-edition-boris-
paskhaver/
Camel in Action
Camel in Action

CLAUS IBSEN
JONATHAN ANSTEY

MANNING
Greenwich
(74° w. long.)
For online information and ordering of this and other Manning books, please visit
www.manning.com. The publisher offers discounts on this book when ordered in quantity.
For more information, please contact

Special Sales Department


Manning Publications Co.
180 Broad Street, Suite 1323
Stamford, CT 06901
Email: [email protected]

©2011 by Manning Publications Co. All rights reserved.

No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in


any form or by means electronic, mechanical, photocopying, or otherwise, without prior written
permission of the publisher.

Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial caps
or all caps.

Recognizing the importance of preserving what has been written, it is Manning’s policy to have
the books we publish printed on acid-free paper, and we exert our best efforts to that end.
Recognizing also our responsibility to conserve the resources of our planet, Manning books are
printed on paper that is at least 15 percent recycled and processed without the use of elemental
chlorine.

Manning Publications Co. Development editor: Cynthia Kane


180 Broad Street, Suite 1323 Copyeditor: Andy Carroll
Stamford, CT 06901 Cover designer: Marija Tudor
Typesetter: Gordan Salinovic

ISBN 978-1-935182-36-8
Printed in the United States of America
1 2 3 4 5 6 7 8 9 10 – MAL – 15 14 13 12 11 10
To the Apache Camel community
May this book be a helpful companion on your journeys with Camel
brief contents
PART 1 FIRST STEPS . ...................................................................1
1 ■ Meeting Camel 3
2 ■ Routing with Camel 22

PART 2 CORE CAMEL .................................................................59


3 ■ Transforming data with Camel 61
4 ■ Using beans with Camel 93
5 ■ Error handling 120
6 ■ Testing with Camel 154
7 ■ Understanding components 188
8 ■ Enterprise integration patterns 237

PART 3 OUT IN THE WILD .........................................................281


9 ■ Using transactions 283
10 ■ Concurrency and scalability 315
11 ■ Developing Camel projects 359
12 ■ Management and monitoring 385
13 ■ Running and deploying Camel 410
14 ■ Bean routing and remoting 443

vii
contents
foreword xvii
foreword xix
preface xxi
acknowledgments xxiii
about this book xxv
about the cover illustration xxix
about the authors xxxi

PART 1 FIRST STEPS. .......................................................1

1 Meeting Camel 3
1.1 Introducing Camel

4
What is Camel? 4 Why use Camel? 5 Getting ■

started 8 Getting Camel 8 Your first Camel ride 9


■ ■

1.2 Camel’s message model 13


Message 13 ■
Exchange 14
1.3 Camel’s architecture 15
Architecture from 10,000 feet 15 ■
Camel concepts 16
1.4 Your first Camel ride, revisited 20
1.5 Summary 21

ix
x CONTENTS

2 Routing with Camel 22


2.1 Introducing Rider Auto Parts 23
2.2 Understanding endpoints 24
Working with files over FTP 24 ■
Sending to a JMS queue 26
2.3 Creating routes in Java 28
Using the RouteBuilder 29 ■
The Java DSL 30
2.4 Creating routes with Spring 34
Bean injection and Spring 34 ■
The Spring DSL 37 ■
Using
Camel and Spring 40
2.5 Routing and EIPs 43
Using a content-based router 44 Using message filters 49

Using multicasting 50 Using recipient lists 52 Using the


■ ■

wireTap method 55
2.6 Summary and best practices 57

PART 2 CORE CAMEL ....................................................59

3 Transforming data with Camel


3.1 Data transformation overview
Data transformation with Camel
61
62
62
3.2 Transforming data using EIPs and Java 63
Using the Message Translator EIP 63 ■
Using the Content
Enricher EIP 70
3.3 Transforming XML 73
Transforming XML with XSLT 73 ■
Transforming XML with
object marshaling 75
3.4 Transforming with data formats 77
Data formats provided with Camel 78 Using Camel’s CSV data

format 79 Using Camel’s Bindy data format 80 Using


■ ■

Camel’s JSON data format 83 Configuring Camel data


formats 84 Writing your own data format 85


3.5 Transforming with templates 86


Using Apache Velocity 87
3.6 About Camel type converters 88
How the Camel type-converter mechanism works 88 Using Camel ■

type converters 90 Writing your own type converter 90


3.7 Summary and best practices 92


CONTENTS xi

4 Using beans with Camel


4.1
93
Using beans the hard way and the easy way
Invoking a bean from pure Java 94 Invoking a bean defined in

94

Spring 95 Using beans the easy way 96


4.2 The Service Activator pattern 97


4.3 Camel’s bean registries 98
SimpleRegistry 100 JndiRegistry 101
■ ■
ApplicationContext-
Registry 101 ■
OsgiServiceRegistry 102
4.4 Selecting bean methods 103
How Camel selects bean methods 104 Camel’s method-selection

algorithm 105 Some method-selection examples 107


Potential method-selection problems 109


4.5 Bean parameter binding 111
Binding with multiple parameters 112 Binding using built-in ■

types 113 Binding using Camel annotations 114 Binding


■ ■

using Camel language annotations 115


4.6 Summary and best practices 119

5 Error handling 120


5.1 Understanding error handling 121
Recoverable and irrecoverable errors 121 ■
Where Camel’s error
handling applies 123
5.2 Error handlers in Camel 124
The default error handler 125 The dead letter channel error

handler 126 The transaction error handler 128 The no error


■ ■

handler 128 The logging error handler 128 Features of the


■ ■

error handlers 128


5.3 Using error handlers with redelivery 129
An error-handling use case 129 Using redelivery 130
■ ■
Error
handlers and scopes 135 Handling faults 137

5.4 Using exception policies 138


Understanding how onException catches exceptions 139 Understanding ■

how onException works with redelivery 142 Understanding how ■

onException can handle exceptions 143 Custom exception ■

handling 146 Ignoring exceptions 148 Implementing an error


■ ■

handler solution 149


5.5 Other error-handling features 150
Using onWhen 150 ■
Using onRedeliver 151 ■
Using
retryWhile 152
5.6 Summary and best practices 153
xii CONTENTS

6 Testing with Camel 154


6.1 Introducing the Camel Test Kit
The Camel JUnit extensions 155 Using the Camel Test Kit 156

155

Unit testing with the CamelTestSupport class 156 Unit testing an ■

existing RouteBuilder class 159 Unit testing with the SpringCamel-


TestSupport class 159 Unit testing in multiple environments 161


6.2 Using the Mock component 166


Introducing the Mock component 167 Unit testing with the Mock ■

component 167 Verifying that the correct message arrived 169


Using expressions with mocks 170 Testing the ordering of


messages 174 Using mocks to simulate real components 175


6.3 Simulating errors 178


Simulating errors using a processor 178 Simulating errors using ■

mocks 180 Simulating errors using interceptors 180


6.4 Testing without mocks 183


Integration testing 183 ■
Using NotifyBuilder 185
6.5 Summary and best practices 187

7 Understanding components 188


7.1 Overview of Camel components
Manually adding components 190 ■
189
Autodiscovering components 190
7.2 Working with files (File and FTP components) 192
Reading and writing files with the File component 193 ■
Accessing remote
files with the FTP component 196
7.3 Asynchronous messaging (JMS component) 197
Sending and receiving messages 200 ■
Request-reply
messaging 201 Message mappings

202
7.4 Web services (CXF component) 205
Configuring CXF 206 Using a contract-first approach

209
Using a code-first approach 215
7.5 Networking (MINA component) 216
Using MINA for network programming 217 ■
Using custom codecs 219
7.6 Working with databases (JDBC and JPA components) 221
Accessing data with the JDBC component 221 ■
Persisting objects with the
JPA component 224
7.7 In-memory messaging (Direct, SEDA, and VM
components) 229
Synchronous messaging with the Direct component 229
Asynchronous messaging with SEDA and VM 230
CONTENTS xiii

7.8 Automating tasks (Timer and Quartz components) 232


Using the Timer component 232 ■
Enterprise scheduling with
Quartz 233
7.9 Summary and best practices 235

8 Enterprise integration patterns


8.1 Introducing enterprise integration patterns
237

The Aggregator and Splitter EIPs 238 The Routing Slip and■
238

Dynamic Router EIPs 239 The Load Balancer EIP 239


8.2 The Aggregator EIP 239


Introducing the Aggregator EIP 240 Completion conditions for

the Aggregator 243 Using persistence with the Aggregator 248


Using recovery with the Aggregator 251


8.3 The Splitter EIP 255
Using the Splitter 256 Using beans for splitting 258 Splitting
■ ■

big messages 260 Aggregating split messages 262 When errors


■ ■

occur during splitting 264


8.4 The Routing Slip EIP 266
Using the Routing Slip EIP 267 Using a bean to compute the

routing slip header 267 Using an Expression as the routing


slip 268 Using @RoutingSlip annotation 269


8.5 The Dynamic Router EIP 270


Using the Dynamic Router 270 ■
Using the @DynamicRouter
annotation 271
8.6 The Load Balancer EIP 272
Introducing the Load Balancer EIP 272 Load-balancing ■

strategies 274 Using the failover load balancer 275 Using a


■ ■

custom load balancer 278


8.7 Summary and best practices 280

PART 3 OUT IN THE WILD ............................................281

9 Using transactions 283


9.1 Why use transactions? 284
The Rider Auto Parts partner integration application 284 Setting ■

up the JMS broker and the database 287 The story of the lost ■

message 288
9.2 Transaction basics 289
About Spring’s transaction support 290 Adding ■

transactions 291 Testing transactions 293



xiv CONTENTS

9.3 The Transactional Client EIP 296


Using local transactions 297 ■
Using global transactions 298
9.4 Configuring and using transactions 301
Configuring transactions 301 Using transactions with multiple

routes 303 Returning a custom response when a transaction


fails 306
9.5 Compensating for unsupported transactions 309
Introducing UnitOfWork 309 Using Synchronization

callbacks 310 Using onCompletion 312


9.6 Summary and best practices 313

10 Concurrency and scalability 315


10.1 Introducing concurrency 316
Running the example without concurrency 318 ■
Using
concurrency 318
10.2 Using thread pools 323
Understanding thread pools in Java 323 Camel thread pool ■

profiles 326 Creating custom thread pools 328 Using


■ ■

ExecutorServiceStrategy 329
10.3 Using concurrency with EIPs 330
Using concurrency with the Threads EIP 331 Using concurrency ■

with the Multicast EIP 332 Using concurrency with the Wire

Tap EIP 334


10.4 Synchronicity and threading 335
Asynchronous caller using one thread 336 Synchronous caller ■

using one thread 337 Asynchronous caller using multiple


threads 339 Synchronous caller using multiple threads 340


Returning an early reply to a caller 342


10.5 The concurrency client API 344
The concurrency client API in Java 344 ■
The concurrency client
API in Camel 347
10.6 The asynchronous routing engine 350
Hitting the scalability limit 350 Scalability in Camel 352

Components supporting asynchronous processing 353


Asynchronous API 354 Writing a custom asynchronous

component 356
10.7 Summary and best practices 358
CONTENTS xv

11 Developing Camel projects


11.1 Managing projects with Maven
359

Using Camel Maven archetypes 360 Camel Maven


360

dependencies 364 Using Camel in Eclipse 366 Using the


■ ■

Maven Eclipse plugin 366 Using the m2eclipse plugin 368


11.2 Developing custom components 371


Setting up a new Camel component 371 ■
Diving into the
implementation 373
11.3 Developing interceptors 377
Creating an InterceptStrategy 377
11.4 Using alternative languages 380
The Scala DSL 380 Adding Scala routes to the CamelContext

382
Mixing Java and Scala 382
11.5 Summary and best practices 384

12 Management and monitoring 385


12.1 Monitoring Camel 386
Checking health at the network level 386 Checking health at the ■

JVM level 388 Checking health at the application level 388


12.2 Using JMX with Camel 389


Using JConsole to manage Camel 390 ■
Using JConsole to remotely
manage Camel 391
12.3 Tracking application activity 393
Using log files 393 Using core logs 394 Using custom
■ ■

logging 394 ■
Using Tracer 398 Using notifications 402

12.4 Managing Camel applications 405


Managing Camel application lifecycles 405 ■
Managing custom
Camel components 406
12.5 Summary and best practices 409

13 Running and deploying Camel 410


13.1 Starting Camel 411
How Camel starts 411 Camel startup options

413 ■
Ordering
routes 416 Disabling autostartup 418

13.2 Starting and stopping routes at runtime 419


Using CamelContext to start and stop routes at runtime 420
Using RoutePolicy to start and stop routes at runtime 422
xvi CONTENTS

13.3 Shutting down Camel 424


Graceful shutdown 425
13.4 Deploying Camel 428
Embedded in a Java application 428 Embedded in a web

application 430 Embedded in JBoss Application Server 436


13.5 Camel and OSGi 437


Setting up Maven to generate an OSGi bundle 438 Installing

and running Apache Karaf 439 Deploying the example 440


13.6 Summary and best practices 441

14 Bean routing and remoting 443


14.1 Using beans for routing 444
Inventory update at Rider Auto Parts 444 Receiving messages

with @Consume 445 Sending messages with @Produce 448


When to use beans for routing 450


14.2 Hiding middleware 451
Introducing the starter kit 453 ■
Using Spring remoting and
Camel proxies 456
14.3 Summary and best practices 460

appendix A Simple, the expression language 461


appendix B Expressions and predicates 471
appendix C The producer and consumer templates 477
appendix D The Camel community 483
appendix E Akka and Camel 487
index 501
foreword
Languages are a critical aspect of software development. They give us the vocabulary
to express what a program should do. They force us to encode our requirements in
precise and non-ambiguous terms. Lastly, they enable the sharing of knowledge
between developers. No, I’m not talking about Java, Haskell, or PL/1. I’m talking
about the languages we use to communicate from human to human, from developer
to developer, or from end user to product manager. For a long time, the world of
enterprise integration (or EAI, as it was commonly known in the “dark ages of integra-
tion”) lacked such a vocabulary. Each vendor offered a proprietary solution, which
not only failed to integrate at a technical level with other vendors’ offerings, but also
used a different language to describe the main components and their functions. This
not only caused confusion, but was also a key inhibitor to creating a community of
developers that could span the vast space of enterprise integration. Each “tribe” was
essentially held hostage by the language bestowed upon them. Ironically, integration
developers were faced with the same “tower of Babel” problem that their software was
designed to solve!
Establishing a common vocabulary that enables knowledge sharing and collabora-
tion was the key motivator for us to write Enterprise Integration Patterns (EIPs). Each
of the 65 patterns has a descriptive name, which represents the solution to a design
challenge in the integration space. Besides supporting effective communication, this
vocabulary also raises the level of abstraction at which we can describe integration
problems and solutions.
A shared vocabulary is a big step forward, but a giant step we could not imagine at
the time was that our language would spur the development of a whole family of open

xvii
xviii FOREWORD

source messaging and enterprise service bus (ESB) products. These tools embrace the
EIP vocabulary by implementing many patterns directly in the platform. With Apache
Camel, a Splitter pattern translates directly into a “split” element in the Camel DSL.
We couldn’t have wished for a more direct translation of the pattern language into an
implementation platform.
Claus and Jon bring the saga to a grand finale by showing us how to use the Camel
pattern language to compose real-life messaging solutions. In doing so, they not only
cover fundamental concepts like routing and transformation, but also dig into often-
neglected parts of the development process, including testing, monitoring, and deploy-
ing. They find the right balance of the pattern language, Camel core concepts, and run-
ning code to help you build easy-to-understand and robust messaging solutions.
GREGOR HOHPE
COAUTHOR OF ENTERPRISE INTEGRATION PATTERNS
WWW.EAIPATTERNS.COM
foreword
I was one of the original founders of both Apache ActiveMQ (an open source high-
performance message broker) and ServiceMix (an open source ESB based on JBI and
OSGi). I found that Enterprise Integration Patterns were becoming increasingly cen-
tral to what we were doing on these projects and how we were using them; the only dif-
ference was the context and technologies with which we were using the patterns.
There have been many libraries and frameworks over the years to help with inte-
gration. But frequently the concepts behind the Enterprise Integration Patterns get
transformed into some complex class hierarchies or objects that need to be wired
together just so, and the original intentions and patterns are often lost. The developer
is forced from then on to focus on the low-level detail and some complex class library
API, losing the bigger picture and patterns.
Integration is hard and once you start down the path of integrating things together
the code can very easily mushroom; being able to easily comprehend, communicate,
adapt, and maintain integration solutions is vital to be able to solve integration prob-
lems efficiently in an agile way.
So we decided it was time for a new integration framework that put the EIPs at its
core and tried to raise the abstraction level so that developers could describe declara-
tively in very concise terms what Enterprise Integration Patterns they wanted to use in
a simple domain-specific language. Using a convention over configuration approach,
developers would declaratively describe what they wanted to do, using the Enterprise
Integration Pattern language; it would be both quick and easy to get things done and

xix
xx FOREWORD

also very easy for any developer on a team (including the developer himself months
after writing the code!) to understand and adapt the code.
There are many different places we wanted to use the EIPs; whether in a stand-
alone application, a web services stack, an enterprise message broker like Apache
ActiveMQ, or inside a full-blown ESB like Apache ServiceMix, so we wanted a light-
weight framework that was middleware agnostic that users could embed anywhere
they wanted it. We also wanted developers to focus on the Enterprise Integration Pat-
terns first and foremost and not to get lost in the weeds of different middleware APIs
and technologies.
We also wanted developers to be able to use whatever DSL flavor they wished
(whether Java, XML, Groovy, Ruby, Scala, or whatever) and yet, at runtime, still be able
to introspect the framework and understand all of the EIPs that were being used. They
would be able to visualize the core patterns to the team at any point in the project life-
cycle, auto-document the patterns, or even support things like graphical editing of the
Enterprise Integration Patterns at design time or runtime.
So Apache Camel was born, and since then we’ve seen the codebase, community,
and number of components, technologies, and data formats grow massively as more
and more developers have found Apache Camel an ideal way to design, implement,
and maintain the Enterprise Integration Patterns.
In this book Claus and Jon describe the Enterprise Integration Patterns and the
concepts which underlie Apache Camel. Then they walk you through how to take the
concepts and apply them to many real-life scenarios to provide scalable and efficient
solutions that are easy to understand and quick to adapt to your integration needs. I
hope you’ll enjoy reading this book as much as I did!
JAMES STRACHAN
CO-FOUNDER OF APACHE ACTIVEMQ
CAMEL, AND SERVICEMIX
TECHNICAL DIRECTOR FUSESOURCE.COM
HTTP://MACSTRAC.BLOGSPOT.COM
preface
Developers who have done integration work know what a difficult task it can be. IT sys-
tems may not have been designed to be accessible from other systems, and if they were
designed for interoperability, they may not speak the protocol you need. As a devel-
oper, you end up spending a considerable amount of time working with the plumbing
of the integration protocols to open up the IT systems to the outside world.
In Enterprise Integration Patterns, Gregor Hohpe and Bobby Woolf gave us a standard
way to describe, document, and implement complex integration problems. Develop-
ers and architects alike can use this common language and catalog of solutions to
tackle their integration problems. But although Hohpe and Woolf gave us the theory,
the industry still needed an open source implementation of the book.
James Strachan, Rob Davies, Guillaume Nodet, and Hiram Chirino, within the
open source communities of Apache ActiveMQ and Apache ServiceMix, brought the
idea of Camel to life. Apache Camel is essentially an implementation of the EIP book,
and in the summer of 2007 version 1.0 was released.
Apache Camel is an integration framework whose main goal is to make integration
easier. It implements many of the EIP patterns and allows you to focus on solving busi-
ness problems, freeing you from the burden of plumbing. Using connectivity compo-
nents has never been easier, because you don’t have to implement JMS message
listeners or FTP clients, deal with converting data between protocols, or mess with the
raw details of HTTP requests. All of this is taken care of by Camel, which makes media-
tion and routing as easy as writing a few lines of Java code or XML in a Spring XML file.

xxi
xxii PREFACE

Apache Camel has since become very popular and today has an ever-growing com-
munity. As with many open source projects that become popular, a logical next step is
for someone to write a book about the project. Hadrian Zbarcea, the Project Manage-
ment Committee chair of the Apache Camel project, realized this, and in early 2009
he contacted Manning to discuss the need for such a book. Hadrian got in touch with
me (Claus Ibsen), inviting me in as a coauthor. It was perfect timing, as I was taking
over from James Strachan as the lead on Apache Camel. Later that year, Hadrian had
to step down as an author, but he invited Jonathan Anstey in as his replacement, to
ensure the project could continue.
Jonathan and I are both integration specialists working for FuseSource, which is
the professional company that offers enterprise services around various Apache proj-
ects. This book is written by the people who wrote the Camel code, which ensures you
have the most updated Camel book on the market.
Writing this book has been a very intense journey, proven by the fact that we were
able to complete the manuscript in a year. It took a long time to implement the exam-
ples and to ensure that the accompanying source code is of the highest standard. But
the result is a great source of examples that should inspire you to get the best out of
Camel, and it should be a good starting point for your Camel projects. While we were
writing this book, we were also implementing new features in Camel, which often
meant we had to go back and revise the material along the way. But we have kept up,
and this book uses the latest Camel release at the time of writing (Camel 2.5).
We hope this book brings great value to you and helps you prosper in the Camel
community.
CLAUS IBSEN
acknowledgments
We first want to thank Cynthia Kane, our development editor at Manning, who put up
with our many missed deadlines and gave great feedback during the writing process.
We’d also like to thank our awesome copy editor, Andy Carroll, for catching an amaz-
ing number of grammatical errors in the early revisions of the book. The greater Man-
ning team deserves kudos as well; they’ve made for a very pleasant writing experience
over the past year and a half.
Big thanks to our team of reviewers, who provided invaluable feedback during var-
ious stages of the book’s development: Bruce Snyder, Charles Moulliard, Christophe
Avare, Christopher Hunt, Domingo Suarez Torres, Doug Tillman, Fintan Bolton, Gor-
don Dickens, Gregor Hohpe, Jeroen Benckhuijsen, John S. Griffon, Kevin Jackson,
Marco Ughetti, Martin Gilday, Martin Krasser, Michael Nash, Mick Knutson, Roman
Kalukiewicz, Tijs Rademakers, and Willem Jiang.
Special thanks to Willem Jiang for being our technical proofreader, catching those
bugs we missed, and helping improve the source code for the book.
Thanks to Martin Krasser for contributing appendix E, which is all about using
Camel from the Akka project. We couldn’t think of a better person to write about
Camel and Akka.
We’d also like to thank Hadrian Zbarcea for getting this book project started—who
knows when this book would have been written or by whom if he hadn’t gotten us
together!
We’d like to thank Gregor Hohpe and James Strachan for writing the forewords to
our book. Gregor’s book, Enterprise Integration Patterns, has been one of our favorite

xxiii
xxiv ACKNOWLEDGMENTS

tech books for years now, so it’s an honor to have Gregor on board to write the fore-
word. Without the EIP book, Apache Camel would look a lot different than it does
today, if it existed at all.
In our opinion, James is an inspiration to many developers out there—including
us. He has co-founded tons of successful open source projects; Camel is just one of
them. If James and the other Apache Camel co-founders had not decided to create
Camel, we wouldn’t be writing this book. So, again, thanks!
Finally, we’d like to give a big warm thank you to the community. Without the com-
munity, the Apache Camel project wouldn’t be as successful as it is today. In fact, with-
out the success, both of us would have different kinds of jobs today, which wouldn’t
involve hacking on Camel all day along.

CLAUS
I would like to thank my beautiful wife, Christina, for her understanding of the long
hours I needed to spend during evenings and weekends working on the book. Knowing
that you would never let my hand go, that the family life is safe and secure, is exactly the
support any writer needs in taking up such a big challenge as writing a book.
A warm thank you goes to our dog, Bambi, who patiently sleeps in my office, and occa-
sionally wakes up and politely “asks” me for a break and a walk. I must admit many of
the ideas and thoughts behind this book came to me during my walks with Bambi.

JON
I would like to thank my amazing wife, Lisa, for the patience, support, and encourage-
ment I needed throughout the writing of this book. It simply would not have hap-
pened if it wasn’t for you. To Georgia, my beautiful daughter: thank you for cheering
me up when the writing got the better of me. I love you both!
about this book
Apache Camel exists because integration is hard and Camel’s creators wanted to make
things easier for users. Camel’s online documentation serves as a reference for its
many features and components. In contrast, this book aims to guide readers through
these features, starting with the simple points and building up to advanced Camel
usage by the end of the book. Throughout the book, Camel’s features are put into
action in real-life scenarios.

Roadmap
The book is divided into three parts:

Part 1—First steps

Part 2—Core Camel

Part 3—Out in the wild
Part 1 starts off simple by introducing you to Camel’s core functionality and concepts,
and it presents some basic examples.

Chapter 1 introduces you to Camel and explains what Camel is and where it fits
into the bigger enterprise software picture. You’ll also learn the concepts and
terminology of Camel.

Chapter 2 covers Camel’s main feature, which is message routing. The Java DSL
and Spring DSL are covered as are several enterprise integration patterns
(EIPs). EIPs are basically canned solutions to integration problems.

xxv
xxvi ABOUT THIS BOOK

Building on part 1’s foundation, part 2 covers the core features of Camel. You’ll need
many of these features when using Camel.

Chapter 3 explains how Camel can help you transform your data to different
formats while it’s being routed.

In chapter 4 we take a look at how you can use Java beans in Camel.

Chapter 5 covers all of Camel’s error-handling features.

In chapter 6 we look at the testing facilities shipped with Camel. You can use
these features for testing your own Camel applications or applications based on
other stacks.

Chapter 7 covers the most heavily used components among Camel’s large selec-
tion of components.

Chapter 8 looks in depth at five of the most complex EIPs.
In part 3 we cover the topics that are useful when you’ve gained a better understand-
ing of Camel from the earlier chapters.

Chapter 9 explains how you can use transactions in your Camel applications.

In chapter 10 we discuss how to deal with concurrency and scalability in your
Camel applications.

Chapter 11 explains how to create new Camel projects, which could be Camel
applications, custom components, or interceptors. This chapter doesn’t require
much additional Camel knowledge, so you could read this right after part 1.
The Scala DSL is also touched on here.

In chapter 12 we cover how to manage and monitor Camel applications.
Among other things, how to read the Camel logs and how to control Camel
with JMX are covered.

In chapter 13 we discuss the many ways to start and stop Camel. Deployment to
several of the most popular containers is also discussed.

Chapter 14 covers what we consider extra features of Camel: routing with beans
and using remoting to hide Camel APIs. We consider this extra because these
features do routing without using any of Camel’s DSLs and in some cases with
no Camel APIs. They take a different approach than what was discussed
throughout the book.
The appendixes at the end of the book contain useful reference material on the Sim-
ple expression language, expressions and predicates, the producer and consumer
templates, and the Camel community. Appendix E is written by Martin Krasser and
shows how to use Akka with Camel.

Who should read this book


We wrote this book primarily for developers who have found the online Camel docu-
mentation lacking and needed a guidebook that explained things in a more detailed
and organized way. Although we mainly targeted existing Camel users, Camel in Action
ABOUT THIS BOOK xxvii

is a great way to start learning about Camel. Experienced engineers and architects are
also encouraged to read this book, as it explains advanced Camel concepts that you
just can’t find elsewhere. Test and Q&A engineers will find Camel and this book useful
as a means of driving tests that require communication with various transports and
APIs. System administrators, too, may find the management, monitoring, and deploy-
ment topics of great value.
Camel’s features are focused on the enterprise business community and its needs,
but it’s also a generic and very useful integration toolkit. Any Java developer who
needs to send a message somewhere will probably find Camel and this book useful.

Code conventions
The code examples in this book are abbreviated in the interest of space. In particular,
some of the namespace declarations in the XML configurations and package imports
in Java classes have been omitted. We encourage you to use the source code when
working with the examples. The line lengths of some of the examples exceed the page
width, and in cases like these, the ➥ marker is used to indicate that a line has been
wrapped for formatting.
All source code in listings or in text is in a fixed-width font like this to separate
it from ordinary text. Code annotations accompany many of the listings, highlighting
important concepts. In some cases, numbered bullets link to explanations that follow
the listing.

Source code downloads


The source code for the examples in this book is available online from the publisher’s
website at http://www.manning.com/CamelinAction, as well as from this site: http://
code.google.com/p/camelinaction.

Software requirements
The following software is required to run the examples:

JDK 5 or better

Maven 2.2.1 or better

Apache Camel 2.5 or better
Apache Camel can be downloaded from its official website: http://camel.apache.org/
download.html.
All the examples can be run using Maven. Chapter 1 shows you how to get started
with Maven and run the examples.

Author Online
The purchase of Camel in Action includes free access to a private web forum run by Man-
ning Publications, where you can make comments about the book, ask technical ques-
tions, and receive help from the authors and from other users. To access the forum and
xxviii ABOUT THIS BOOK

subscribe to it, point your web browser to http://www.manning.com/CamelinAction.


This page provides information on how to get on the forum once you’re registered,
what kind of help is available, and the rules of conduct on the forum.
Manning’s commitment to our readers is to provide a venue where a meaningful
dialogue between individual readers and between readers and the authors can take
place. It is not a commitment to any specific amount of participation on the part of
the authors, whose contribution to the forum remains voluntary (and unpaid). We
suggest you try asking the authors some challenging questions, lest their interest stray!
The Author Online forum and the archives of previous discussions will be accessi-
ble from the publisher’s website as long as the book is in print.
about the cover illustration
The illustration on the cover of Camel in Action bears the caption “A Bedouin,” and is
taken from a collection of costumes of the Ottoman Empire published on Janu-
ary 1, 1802, by William Miller of Old Bond Street, London. The title page is missing
from the collection and we have been unable to track it down to date. The book’s
table of contents identifies the figures in both English and French, and each illustra-
tion also bears the names of two artists who worked on it, both of whom would no
doubt be surprised to find their art gracing the front cover of a computer program-
ming book ...200 years later.
The collection was purchased by a Manning editor at an antiquarian flea market in
the “Garage” on West 26th Street in Manhattan. The seller was an American based in
Ankara, Turkey, and the transaction took place just as he was packing up his stand for
the day. The Manning editor did not have on his person the substantial amount of
cash that was required for the purchase and a credit card and check were both politely
turned down. With the seller flying back to Ankara that evening, the situation was get-
ting hopeless. What was the solution? It turned out to be nothing more than an old-
fashioned verbal agreement sealed with a handshake. The seller simply proposed that
the money be transferred to him by wire and the editor walked out with the bank
information on a piece of paper and the portfolio of images under his arm. Needless
to say, we transferred the funds the next day, and we remain grateful and impressed by
this unknown person’s trust in one of us. It recalls something that might have hap-
pened a long time ago.

xxix
xxx ABOUT THE COVER ILLUSTRATION

The pictures from the Ottoman collection, like the other illustrations that appear
on our covers, bring to life the richness and variety of dress customs of two centuries
ago. They recall the sense of isolation and distance of that period—and of every other
historic period except our own hyperkinetic present. Dress codes have changed since
then and the diversity by region, so rich at the time, has faded away. It is now often
hard to tell the inhabitant of one continent from another. Perhaps, trying to view it
optimistically, we have traded a cultural and visual diversity for a more varied personal
life. Or a more varied and interesting intellectual and technical life.
We at Manning celebrate the inventiveness, the initiative, and, yes, the fun of the
computer business with book covers based on the rich diversity of regional life of two
centuries ago‚ brought back to life by the pictures from this collection.
about the authors
CLAUS IBSEN has worked as a software engineer and architect for more than 13 years.
He has often worked with integration in various forms, from integrating with legacy
systems on AS/400s to building custom in-house integration frameworks. Claus has
designed and architected a large solution for custom clearance for the district of
Shanghai, China. He tracks the trends in the open source integration space and it led
him to Camel in late 2007. He became a committer in March 2008.
He currently holds a position as principal software engineer at FuseSource, as proj-
ect lead on Apache Camel. Claus has ambitions to pick up speaking engagements, so
you will likely be able to catch up with him at various conferences.
Claus lives in Sweden near Malmo with his wife and dog, which is spoiled as the
only child in the family. He is Danish by nationality.
JONATHAN ANSTEY is a software engineer with varied experience in manufacturing con-
trol systems, build infrastructure, and enterprise integration. He got involved in the
Apache Camel project in early 2008 and hasn’t looked back since. Most recently, Jon
has been working on Apache Camel and other Apache open source projects
at FuseSource.
When Jon is not hacking on Camel, he likes to spend time with his wife and daugh-
ter in St. John’s, Newfoundland.

xxxi
Part 1

First steps

A pache Camel is an open source integration framework that aims to make


integrating systems easier. In the first chapter of this book we’ll introduce you to
Camel and show you how it fits into the bigger enterprise software picture. You’ll
also learn the concepts and terminology of Camel.
Chapter 2 focuses on one of Camel’s most important features: message rout-
ing. Camel has two main ways of defining routing rules: the Java-based domain-
specific language (DSL) and the Spring XML configuration format. In addition
to these route-creation techniques, we’ll show you how to design and implement
solutions to enterprise integration problems using enterprise integration pat-
terns (EIPs) and Camel.
Meeting Camel

This chapter covers


■ An introduction to Camel
■ Camel’s main features
■ Your first Camel ride
■ Camel’s architecture and concepts

Building complex systems from scratch is a very costly endeavor, and one that’s almost
never successful. An effective and less risky alternative is to assemble a system like a
jigsaw puzzle from existing, proven components. We depend daily on a multitude of
such integrated systems, making possible everything from phone communications,
financial transactions, and healthcare to travel planning and entertainment.
You can’t finalize a jigsaw puzzle until you have a complete set of pieces that plug
into each other simply, seamlessly, and robustly. That holds true for system integra-
tion projects as well. But whereas jigsaw puzzle pieces are made to plug into each
other, the systems we integrate rarely are. Integration frameworks aim to fill this gap.
As an integrator, you’re less concerned about how the system you integrate works and
more focused on how to interoperate with it from the outside. A good integration
framework provides simple, manageable abstractions for the complex systems you’re
integrating and the “glue” for plugging them together seamlessly.
Apache Camel is such an integration framework. In this book, we’ll help you
understand what Camel is, how to use it, and why we think it’s one of the best inte-
gration frameworks out there.

3
4 CHAPTER 1 Meeting Camel

This chapter will start off by introducing Camel and highlighting some of its core
features. We’ll then take a look at the Camel distribution and explain how you can run
the Camel examples in the book. We’ll round off the chapter by bringing core Camel
concepts to the table so you can understand Camel’s architecture.
Are you ready? Let’s meet Camel.

1.1 Introducing Camel


Camel is an integration framework that aims to make your integration projects pro-
ductive and fun. The Camel project was started in early 2007, but although it’s rela-
tively young, Camel is already a mature open source project, available under the
liberal Apache 2 license, and it has a strong community.
Camel’s focus is on simplifying integration. We’re confident that by the time you
finish reading these pages, you’ll appreciate Camel and add it to your “must have” list
of tools.
The Apache Camel project was named Camel simply because the name is short
and easy to remember. Rumor has it the name may be inspired by the fact that one of
the founders once smoked Camel cigarettes. At the Camel website a FAQ entry
(http://camel.apache.org/why-the-name-camel.html) lists other lighthearted reasons
for the name.

1.1.1 What is Camel?


At the core of the Camel framework is a routing engine, or more precisely a routing-
engine builder. It allows you to define your own routing rules, decide from which
sources to accept messages, and determine how to process and send those messages to
other destinations. Camel uses an integration language that allows you to define com-
plex routing rules, akin to business processes.
One of the fundamental principles of Camel is that it makes no assumptions about
the type of data you need to process. This is an important point, because it gives you,
the developer, an opportunity to integrate any kind of system, without the need to
convert your data to a canonical format.
Camel offers higher-level abstractions that allow you to interact with various sys-
tems using the same API regardless of the protocol or data type the systems are using.
Components in Camel provide specific implementations of the API that target differ-
ent protocols and data types. Out of the box, Camel comes with support for over 80
protocols and data types. Its extensible and modular architecture allows you to imple-
ment and seamlessly plug in support for your own protocols, proprietary or not.
These architectural choices eliminate the need for unnecessary conversions and make
Camel not only faster but also very lean. As a result, it’s suitable for embedding into
other projects that require Camel’s rich processing capabilities. Other open source
projects, such as Apache ServiceMix and ActiveMQ, already use Camel as a way to
carry out enterprise integration.
We should also mention what Camel isn’t. Camel isn’t an enterprise service bus
(ESB), although some call Camel a lightweight ESB because of its support for rout-
ing, transformation, monitoring, orchestration, and so forth. Camel doesn’t have a
Introducing Camel 5

container or a reliable message bus, but it can be deployed in one, such as Open-
ESB or the previously mentioned ServiceMix. For that reason, we prefer to call
Camel an integration framework rather than an ESB.
To understand what Camel is, it helps to look at its main features. So let’s take a
look at them.

1.1.2 Why use Camel?


Camel introduces a few novel ideas into the integration space, which is why its authors
decided to create Camel in the first place, instead of using an existing framework.
We’ll explore the rich set of Camel features throughout the book, but these are the
main ideas behind Camel:
■ Routing and mediation engine ■ Enterprise integration patterns (EIPs)
■ Domain-specific language (DSL) ■ Extensive component library
■ Payload-agnostic router ■ Modular and pluggable architecture
■ POJO model ■ Easy configuration
■ Automatic type converters ■ Lightweight core
■ Test kit ■ Vibrant community

Let’s dive into the details of each of these features.


ROUTING AND MEDIATION ENGINE
The core feature of Camel is its routing and mediation engine. A routing engine will
selectively move a message around, based on the route’s configuration. In Camel’s
case, routes are configured with a combination of enterprise integration patterns and
a domain-specific language, both of which we’ll describe next.
ENTERPRISE INTEGRATION PATTERNS (EIPS)
Although integration problems are diverse, Gregor Hohpe and Bobby Woolf noticed
that many problems and their solutions are quite similar. They cataloged them
in their book Enterprise Integration Patterns, a must-read for any integration profes-
sional (http://www.enterpriseintegrationpatterns.com). If you haven’t read it, we
encourage you to do so. At the very least, it will help you understand Camel concepts
faster and easier.
The enterprise integration patterns, or EIPs, are helpful not only because they pro-
vide a proven solution for a given problem, but also because they help define and
communicate the problem itself. Patterns have known semantics, which makes com-
municating problems much easier. The difference between using a pattern language
and describing the problem at hand is similar to using spoken language rather than
sign language. If you’ve ever visited a foreign country, you’ve probably experienced
the difference.
Camel is heavily based on EIPs. Although EIPs describe integration problems and
solutions and also provide a common vocabulary, the vocabulary isn’t formalized.
Camel tries to close this gap by providing a language to describe the integration solu-
tions. There’s almost a one-to-one relationship between the patterns described in
Enterprise Integration Patterns and the Camel DSL.
6 CHAPTER 1 Meeting Camel

DOMAIN-SPECIFIC LANGUAGE (DSL)


Camel’s domain-specific language (DSL) is a major contribution to the integration
space. A few other integration frameworks currently feature a DSL (and some allow
you to use XML to describe routing rules), but unlike Camel their DSLs are based on
custom languages. Camel is unique because it offers multiple DSLs in regular pro-
gramming languages such as Java, Scala, Groovy, and it also allows routing rules to be
specified in XML.
The purpose of the DSL is to allow the developer to focus on the integration problem
rather than on the tool—the programming language. Although Camel is written mostly
in Java, it does support mixing multiple programming languages. Each language has its
own strengths, and you may want to use different languages for different tasks. You have
the freedom to build a solution your own way with as few constraints as possible.
Here are some examples of the DSL using different languages and staying func-
tionally equivalent:
■ Java DSL
from("file:data/inbox").to("jms:queue:order");
■ Spring DSL
<route>
<from uri="file:data/inbox"/>
<to uri="jms:queue:order"/>
</route>
■ Scala DSL
from "file:data/inbox" -> "jms:queue:order"

These examples are real code, and they show how easily you can route files from a
folder to a JMS queue. Because there’s a real programming language underneath, you
can use the existing tooling support, such as code completion and compiler error
detection, as illustrated in figure 1.1.

Figure 1.1 Camel DSLs use real programming languages like Java, so you can use existing tooling support.
Introducing Camel 7

Here you can see how the Eclipse IDE’s autocomplete feature can give us a list of DSL
terms that are valid to use.
EXTENSIVE COMPONENT LIBRARY
Camel provides an extensive library of more than 80 components. These components
enable Camel to connect over transports, use APIs, and understand data formats.
PAYLOAD-AGNOSTIC ROUTER
Camel can route any kind of payload—you aren’t restricted to carrying XML payloads.
This freedom means that you don’t have to transform your payload into a canonical
format to facilitate routing.
MODULAR AND PLUGGABLE ARCHITECTURE
Camel has a modular architecture, which allows any component to be loaded into
Camel, regardless of whether the component ships with Camel, is from a third party,
or is your own custom creation.
POJO MODEL
Beans (or POJOs) are considered first-class citizens in Camel, and Camel strives to let
you use beans anywhere and anytime in your integration projects. This means that in
many places you can extend Camel’s built-in functionality with your own custom code.
Chapter 4 has a complete discussion of using beans within Camel.
EASY CONFIGURATION
The convention over configuration paradigm is followed whenever possible, which mini-
mizes configuration requirements. In order to configure endpoints directly in routes,
Camel uses an easy and intuitive URI configuration.
For example, you could configure a file consumer to scan recursively in a sub-
folder and include only a .txt file, as follows:
from("file:data/inbox?recursive=true&include=*.txt")...

AUTOMATIC TYPE CONVERTERS


Camel has a built-in type-converter mechanism that ships with more than 150 convert-
ers. You no longer need to configure type-converter rules to go from byte arrays to
strings, for example. And if you find a need to convert to types that Camel doesn’t sup-
port, you can create your own type converter. The best part is that it works under the
hood, so you don’t have to worry about it.
The Camel components also leverage this feature; they can accept data in most
types and convert the data to a type they’re capable of using. This feature is one of the
top favorites in the Camel community. You may even start wondering why it wasn’t
provided in Java itself! Chapter 3 covers more about type converters.
LIGHTWEIGHT CORE
Camel’s core can be considered pretty lightweight, with the total library coming in at
about 1.6 MB and only having a dependency on Apache Commons Logging and Fuse-
Source Commons Management. This makes Camel easy to embed or deploy anywhere
you like, such as in a standalone application, web application, Spring application, Java
8 CHAPTER 1 Meeting Camel

EE application, JBI container, OSGi bundle, Java Web Start, or on the Google App
engine. Camel was designed not to be a server or ESB but instead to be embedded in
whatever platform you choose.
TEST KIT
Camel provides a Test Kit that makes it easier for you to test your own Camel applica-
tions. The same Test Kit is used extensively to test Camel itself, and it includes more
than 6,000 unit tests. The Test Kit contains test-specific components that, for example,
can help you mock real endpoints. It also contains setup expectations that Camel can
use to determine whether an application satisfied the requirements or failed. Chap-
ter 6 covers testing with Camel.
VIBRANT COMMUNITY
Camel has an active community. This is essential if you intend to use any open source
project in your application. Inactive projects have little community support, so if you
run into issues, you’re on your own. With Camel, if you’re having any trouble, users
and developers alike will come to your aid promptly. For more information on
Camel’s community, see appendix D.
Now that you’ve seen the main features that make up Camel, we’ll get a bit more
hands on by looking at the Camel distribution and trying out an example.

1.2 Getting started


In this section, we’ll show you how to get your hands on a Camel distribution, explain
what’s inside, and then run an example using Apache Maven. After this, you’ll know
how to run any of the examples from the book’s source code.
Let’s first get the Camel distribution.

1.2.1 Getting Camel


Camel is available from the official Apache Camel website at http://
camel.apache.org/download.html. On that page you’ll see a list of all the Camel
releases and also the downloads for the latest release.
For the purposes of this book, we’ll be using Camel 2.5.0. To get this version, click
on the Camel 2.5.0 Release link and near the bottom of the page you’ll find two
binary distributions: the zip distribution is for Windows users, and the tar.gz distribu-
tion is for Unix/Linux/Cygwin users. When you’ve downloaded one of the distribu-
tions, extract it to a location on your hard drive.
Open up a command prompt, and go to the location where you extracted the
Camel distribution. Issuing a directory listing here will give you something like this:
janstey@mojo:~/apache-camel-2.5.0$ ls
doc examples lib LICENSE.txt NOTICE.txt README.txt

As you can see, the distribution is pretty small, and you can probably guess what each
directory contains already. Here are the details:
Getting started 9

■ doc—Contains the Camel Manual in PDF and HTML formats. This user guide is
a download of a large portion of the Apache Camel wiki at the time of release.
As such, it’s a great reference for those not able to browse to the Camel website.
■ examples—Includes 27 Camel examples. You’ll see an example shortly.
■ lib—Contains all Camel libraries and third-party dependencies needed for the
core of Camel to run. You’ll see later in the chapter how Maven can be used to
easily grab dependencies for the components outside the core.
■ LICENSE.txt—Contains the license of the Camel distribution. Because this is an
Apache project, the license is the Apache License, version 2.0.
■ NOTICE.txt—Contains copyright information about the third-party dependen-
cies included in the Camel distribution.
■ README.txt—Contains a short intro to what Camel is and a list of helpful links
to get new users up and running fast.
Now let’s try out one of the Camel examples.

1.2.2 Your first Camel ride


So far, we’ve shown you how to get a Camel distribution and we’ve explored what’s
inside. At this point, feel free to explore the distribution; all examples have instruc-
tions to help you figure them out.
From this point on, though, we won’t be using the distribution at all. The exam-
ples in the book’s source all use Apache Maven, which means that Camel libraries will
be downloaded automatically for you—there’s no need to make sure the Camel distri-
bution’s libraries are on the path, for example.
You can get the book’s source code from either the book’s website, at http://
manning.com/ibsen or from the Google Code project that’s hosting the source:
http://code.google.com/p/camelinaction.
The first example we’ll look at can
be considered the “hello world” of inte-
grations: routing files. Suppose you
data/inbox File data/outbox
need to read files from one directory
(data/inbox), process them in some
way, and write the result to another
Figure 1.2 Files are routed from the data/inbox
directory (data/outbox). For simplic- directory to the data/outbox directory.
ity, you’ll skip the processing, so your
output will be merely a copy of the original file. Figure 1.2 illustrates this process.
It looks pretty simple, right? Here’s a possible solution using pure Java (with no
Camel).

Listing 1.1 Routing files from one folder to another in plain Java
public class FileCopier {
public static void main(String args[]) throws Exception {
File inboxDirectory = new File("data/inbox");
File outboxDirectory = new File("data/outbox");
10 CHAPTER 1 Meeting Camel

outboxDirectory.mkdir();
File[] files = inboxDirectory.listFiles();
for (File source : files) {
if (source.isFile()) {
File dest = new File(
outboxDirectory.getPath()
+ File.separator
+ source.getName());
copyFIle(source, dest);
}
}
}
private static void copyFile(File source, File dest)
throws IOException {
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[(int) source.length()];
FileInputStream in = new FileInputStream(source);
in.read(buffer);
try {
out.write(buffer);
} finally {
out.close();
in.close();
}
}
}
The FileCopier example in listing 1.1 is a pretty simple use case, but it still results
in 34 lines of code. You have to use low-level file APIs and ensure that resources get
closed properly, a task that can easily go wrong. Also, if you wanted to poll the data/
inbox directory for new files, you’d need to set up a timer and also keep track of
which files you’ve already copied. This simple example is getting more complex.
Integration tasks like these have been done thousands of times before—you
shouldn’t ever need to code something like this by hand. Let’s not reinvent the wheel
here. Let’s see what a polling solution looks like if you use an integration framework
like Apache Camel.

Listing 1.2 Routing files from one folder to another with Apache Camel
public class FileCopierWithCamel {
public static void main(String args[]) throws Exception {
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
public void configure() {
from("file:data/inbox?noop=true")
.to("file:data/outbox");
B Routes files from
inbox to outbox
}
});
context.start();
Thread.sleep(10000);
context.stop();
}
}
Getting started 11

Most of this code is boilerplate stuff when using Camel. Every Camel application uses
a CamelContext that’s subsequently started and then stopped. You also add a sleep
method to allow your simple Camel application time to copy the files. What you
should really focus on in listing 1.2 is the route B.
Routes in Camel are defined in such a way that they flow when read. This route can
be read like this: consume messages from file location data/inbox with the noop
option set, and send to file location data/outbox. The noop option tells Camel to
leave the source file as is. If you didn’t use this option, the file would be moved. Most
people who have never seen Camel before will be able to understand what this route
does. You may also want to note that, excluding the boilerplate code, you created a
file-polling route in just one line of Java code B.
To run this example, you’ll need to download and install Apache Maven from the
Maven site at http://maven.apache.org/download.html. Once you have Maven up
and working, open a terminal and browse to the chapter1/file-copy directory of the
book’s source. If you take a directory listing here, you’ll see several things:
■ data—Contains the inbox directory, which itself contains a single file named
message1.xml.
■ src—Contains the source code for the listings shown in this chapter.
■ pom.xml—Contains information necessary to build the examples. This is the
Maven Project Object Model (POM) XML file.

NOTE We used Maven 2.2.1 during the development of the book. Newer ver-
sions of Maven may not work or appear exactly as we’ve shown.

The POM is shown here.

Listing 1.3 The Maven POM required to use Camel’s core library
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent> B
Parent POM
<groupId>com.camelinaction</groupId>
<artifactId>chapter1</artifactId>
<version>1.0</version>
</parent>

<artifactId>file-copy</artifactId>

<name>Camel in Action :: Chapter 1 :: File Copy Example</name>


<dependencies>
<dependency>
<groupId>org.apache.camel</groupId> C Camel’s
<artifactId>camel-core</artifactId> core library
<version>${camel-version}</version>
</dependency>
</dependencies>
</project>
12 CHAPTER 1 Meeting Camel

Maven itself is a complex topic, and we won’t go into great detail here. We’ll give you
enough information to be productive with the examples in this book. For an in-depth
look at Maven, we recommend reading Maven by Example and Maven: The Complete Ref-
erence, both of which are freely available from http://www.sonatype.com/book. We’ll
also discuss using Maven to develop Camel applications in chapter 11, so there’s a
good deal of information there too.
The Maven POM in listing 1.3 is probably one of the shortest POMs you’ll ever
see—almost everything uses the defaults provided by Maven. Besides those defaults,
there are also some settings configured in the parent POM B. Probably the most
important section to point out here is the dependency on the Camel library C. This
dependency element tells Maven to do the following:
1 Create a search path based on the groupId, artifactId, and version. The ver-
sion element is set to the camel-version property, which is defined in the POM
referenced in the parent element B, and will resolve to 2.5.0. The type of depen-
dency was not specified, so the JAR file type will be assumed. The search path will
be org/apache/camel/camel-core/2.5.0/camel-core-2.5.0.jar.
2 Because listing 1.3 defined no special places for Maven to look for the Camel
dependencies, it will look in Maven’s central repository, located at http://
repo1.maven.org/maven2.
3 Combining the search path and the repository URL, Maven will try to down-
load http://repo1.maven.org/maven2/org/apache/camel/camel-core/2.5.0/
camel-core-2.5.0.jar.
4 This JAR will be saved to Maven’s local download cache, which is typically located
in the home directory under .m2/repository. This would be ~/.m2/repository on
Linux/Unix and C:\Documents and Settings\<Username>\.m2\ repository on
Windows XP, and C:\Users\<Username>\.m2\repository on Windows Vista/7.
5 When the application code in listing 1.2 is started, the Camel JAR will be added
to the classpath.
To run the example in listing 1.2, use the following command:
mvn compile exec:java -Dexec.mainClass=camelinaction.FileCopierWithCamel

This instructs Maven to compile the source in the src directory and to execute the
FileCopierWithCamel class with the camel-core JAR on the classpath.

NOTE In order to run any of the examples in this book you’ll need an Inter-
net connection. A broadband speed connection is preferable because Apache
Maven will download many JAR dependencies of the examples, some of which
are large. The whole set of examples will download about 140 MB of libraries.

Run the Maven command from the chapter1/file-copy directory, and after it completes,
browse to the data/outbox folder to see the file copy that has just been made. Congrat-
ulations, you’ve just run your first Camel example! It was a simple example, but knowing
how it’s set up will enable you to run pretty much any of the book’s examples.
Another random document with
no related content on Scribd:
Minä menin sanomaan hänelle jäähyväisiä.

"Miksi jo nyt menette? Odottakaa vähän, mamma tulee kohta."

"Ei, minä en voi", vastasin minä, "parasta on minun tulla toiste."

Minun kauhukseni, tosiaan suureksi kauhukseni astui Sofia juuri


silloin vakavin askelin saliin. Hänen kasvonsa olivat kalpeammat
kuin tavallisesti ja silmäluomet punaiset itkusta. Minua hän ei ollut
huomaavinaankaan.

"Tules tänne, niin saat nähdä, Sonja!" sanoi Varvara. "Tuo pikku
notaari kävelee lakkaamatta tästä ohitse."

"Se on kaiketi vakooja", huomautti Solia hyvin halveksivalla


äänellä.

Se oli minulle jo liiaksi! Minä riensin ulos enkä tosiaankaan tiedä,


mitenkä minä pääsin kotiin.

Minun mieleni oli niin raskas ja katkera, että sitä en voi


kavalakaan. Neljänkolmatta tunnin kuluessa kaksi sellaista julmaa
iskua! Minä olin saanut tietää, että Sofia rakasti toista ja että minä
olin ainiaaksi kadottanut hänen kunnioituksensa. Minä tunsin olevani
niin nöyryytetty ja kukistettu, että en edes voinut olla suutuksissani
itseenikään. Maaten sohvalla, kasvot seinään päin, antauduin
nauttimaan harmini ja toivottomuuteni ensimmäisen purkauksen
katkeruutta.

Yht'äkkiä kuulin astuntaa huoneeni lattialla. Minä nousin ylös.


Tulija oli eräs lähimpiä ystäviäni, Jakov Pasinkov.
Minä kyllä olisin suuttunut kehen hyvänsä muuhun ihmiseen, joka
olisi sinä päivänä tullut kutsumatta minun huoneeseni, mutta
kerrassaan mahdoton oli minun suuttua Pasinkoviin. Päin vastoin
surunkin vaiheella, joka niin katkerasti minua ahdisti, minä tosiaan
ilostuin hänen tulostansa ja tervehdin häntä ystävällisesti. Vanhan
tapansa mukaan astui hän pari kertaa edes takaisin huoneessa,
puhkuen ja vetäen pitkiä jalkojaan jäljestänsä, seisoi sitte
silmänräpäyksen ajan ääneti minun edessäni ja kävi viimein yhtä
ääneti nurkkaan istumaan.
IV.

Minä olin hyvin kauan, melkein ihan lapsuudesta asti ollut hyvä tuttu
Jakov Pasinkovin kanssa. Hän oli ollut kasvatettavana samassa
yksityisessä oppilaitoksessa Moskovassa, saksalaisen Winterkellerin
luona, jossa minäkin olin viettänyt kolme vuotta.

Jakovin isä, joka oli köyhä, virasta eronnut majori ja muuten hyvin
rehellinen, mutta hiukan heikkomielinen mies, oli tullut herra
Winterkellerin luo pienen, silloin seitsenvuotisen poikansa kanssa,
maksanut hänestä vuoden maksun, mutta sitte matkustanut pois
Moskovasta ja kadonnut, antamatta enää mitään tietoa itsestään.
Tuon tuostakin kuului hämäriä kummallisia huhuja hänen
vaiheistansa. Vasta kahdeksan vuoden kuluttua saatiin varmasti
tietää hänen hukkuneen Irtish-joen tulvaan. Ei kukaan tiennyt, mikä
hänet oli vienyt Siperiaan.

Jakovilla ei ollut ketään läheisiä sukulaisia. Hänen äitinsä oli


kuollut jo hyvin kauan sitte. Sillä tavalla joutui hän jäämään
Winterkellerin taloon. Oli hänellä tosiaan yksi etäinen sukulainen,
jota hän sanoi "tädiksi", mutta hän oli niin köyhä, että alussa ei
uskaltanut tulla tervehtimään nuorta sukulaistansa, kun pelkäsi, että
poika tungettaisiin hänelle vastuksiksi.
Vaimovanhuksen pelko oli kuitenkin turha. Hyväsydämminen
saksalainen piti Jakovin luonansa, antoi hänen opiskella ja syödä
yhdessä toisten oppilasten kanssa (mutta arkipäivinä jätettiin aina
jälkiruoka hänelle antamatta) ja teki hänelle vaatteita vanhoista
nuuskanruskeista kapoista, joita hänen äitinsä, hyvin vanha, mutta
vielä reipas ja toimelias liiviläisvaimo, oli käyttänyt.

Kaikkein näiden asianhaarain tähden ja varsinkin siitä syystä, että


Jakovin asema koulussa oli muka alhaisempi, kohtelivat kumppanit
tavallisesti häntä huolimattomasti ja halveksivasti. He katselivat
häntä yli olkansa kuin köyhää poikaa, josta ei kukaan huolinut, ja
sanoivat häntä milloin "akankapaksi", milloin "myssysankariksi",
hänen tätinsä kun aina käytti kummallista pitsimyssyä, jonka
päälaella törrötti keltainen nauhaviuhka kuin hernetukku, ja milloin
"Jermakin pojaksi", koska hänen isänsä oli kulkenut Irtishiin kuten
kuuluisa Jermak. Mutta huolimatta noista haukkumanimistä, hänen
naurettavista vaatteistaan ja köyhyydestään kaikki kuitenkin pitivät
hänestä paljon. Mahdoton tosiaan olikin olla häntä suosimatta.
Parempi sydämmistä, nöyrempää ja uhraavaisempaa ihmistä tuskin
vain on koskaan ollut maailmassa.

Kuin minä näin hänet ensi kerran, oli hän kuudentoista vuoden
ijässä ja minä olin äsken täyttänyt kolmetoista. Minä olin silloin hyvin
itserakas ja lellitelty poika, rikkaassa kodissa kasvanut. Niinpä minä
heti kouluun tultuani kiiruhdin tekemään lähempää tuttavuutta erään
ruhtinaan pojan kanssa, josta herra Winterkeller piti aivan erityistä
huolta, ja parin muun ylhäissukuisen pojan kanssa. Kaikki muut
pidätin minä kaukana itsestäni enkä Pasinkovia ottanut edes
huomioonikaan. Sitä pitkää ja hoikkaa poikaa rumassa nutussaan ja
lyhyissä housuissa, joiden alta näkyi karkeat, kuluneet puolisukat,
katselin minä köyhän työmiehen pojan tai sellaisen palveluspojan
vertaiseksi, jonka isäni oli minulle valinnut kotitilustemme maaorjain
joukosta.

Pasinkov oli hyvin kohtelias kaikille, mutta ei koskaan koettanut


tunkeutua kenenkään suosioon millään erityisillä keinoilla. Jos hänet
karkoitettiin pois, hän ei nöyrtynyt eikä myöskään pahastunut, vaan
pysyi etäämpänä ikään kuin odotellen, että toinen katuisi tylyyttänsä.
Sellainen hän oli minuakin kohtaan, mutta kaksi kokonaista
kuukautta kului, ennenkuin minun ylpeyteni lannistui ja minä käsitin,
miten paljon parempi hän oli meitä muita.

Oli kirkas, kaunis kesäpäivä. Innokkaan ja väsyttävän pallipelin


jälkeen menin minä pihasta pieneen puutarhaan, joka oli koulun
oma, ja näin Pasinkovin istuvan penkillä korkean sireenipensaan
alla.

Hän luki kirjaa. Astuessani hänen ohitsensa katsahdin kirjan


kansiin ja luin saranoista nimen "Schillers Werke". Minä pysähdyin.

"Osaatteko te saksaa, te?" kysyin minä.

Minua hävettää vielä tänäkin päivänä, kun muistan, miten kopeaa


ylpeyttä ja halveksimista oli ääneni kaiussa.

Pasinkov katsoi minuun pienillä, mutta paljon sanovilla silmillään ja


vastasi:

"Kyllä, kyllä minä osaan. Entä te?"

"Enkö minä sitä osaisi!" vastasin minä.

Minä olin melkein pahastunut tuosta hänen kysymyksestään ja


aioin astua edelleen, mutta olipa siinä kuitenkin jotain,
käsittämätöntä itsellenikin, mitä se oli, joka minua pidätti lähtemästä.

"No, mitä Schillerin teosta te luette sitte?" kysyin minä samalla


ylpeällä äänellä.

"Nyt minä luen Mielenmalttia. Se on erinomaisen kaunis kappale.


Jos tahdotte, niin luen sen teille. Käykää istumaan tähän viereeni
penkille."

Minä vitkastelin vähän, mutta kävin sentään istumaan. Pasinkov


alkoi lukea.

Hän ilmeisesti osasi saksaa paljon paremmin kuin minä ja


monessa paikassa täytyi hänen selittää, ajatusta minulle. Mutta minä
en enää hävennyt omaa taitamattomuuttani enkä hänen
taitavammuuttansa.

Siitä päivästä, siitä yhteisestä lukemisesta sireenein varjossa


rakastin minä Pasinkovia koko nuoren sydämmeni innolla, liityin
häneen ja katselin ylös häneen kaikessa, joka oli hyvää ja oikeata.

Muistanpa vielä tänäkin päivänä hyvin elävästi, minkä näköinen


hän siiloin oli. Vähänpä hänen muotonsa muuttuikin vuosien
kuluessa. Hän oli pitkä ja laiha ja jotenkin kömpelö, kapeat olkapäät
ja syvälle painunut rinta tekivät hänet sairaan näköiseksi, vaikka
hänellä ei ollut mitään syytä valitella pahoinvointia. Suuri, yläpuolelta
aivan pyöreä pää oli aina vähän kallellaan toiselle puolelle ja
pehmoinen vaalea tukka riippui ohuina kiehkuroina hänen hoikalla
kaulallansa. Kasvot eivät olleet kauniit, vaan melkein naurettavat
pitkän, paksun ja punaisen nenän tähden, joka riippui leveäin
suorien huulien päällä. Mutta erinomaisen kaunis oli hänen avoin,
kirkas otsansa, ja kun hän hymyili, loistivat hänen pienet, harmaat
silmänsä niin lempeän sydämmellisesti ja ystävällisesti, että kun vain
niihin katsoi, sydän oikein lämpeni ja ilostui.

Minä muistan myöskin varsin hyvin hänen hiljaisen ja tasaisen


äänensä, joka oli hiukan käheä, mutta ei vastenmielisesti. Hän puhui
yleensä vähän ja nähtävästi vaivalloisesti, mutta milloin hän hiukan
lämpeni ja vilkastui, sujui puhe helposti ja vapaasti, ja — varsin
kummallista katsella — hänen äänensä silloin hiljeni hiljenemistään,
katse muuttui yhä enemmin sisälliseksi ja ikään kuin sammuvaksi ja
koko muoto hiukan punastui. Sanoilla sellaisilla kuin "totuus",
"hyvyys", "elämä", "tiede", "rakkaus" ei koskaan ollut mitään väärää
kaikua Pasinkovin huulilla, lausuipa hän ne kuinka suurella
innostuksella hyvänsä. Pakotta, ponnistuksetta nousi hänen
henkensä ylös ihanteiden maailmaan. Hänen puhdas sielunsa oli
joka hetki valmis astumaan "kauneuden pyhyyteen". Se odotti vain
tulotervehdystä, sisällistä yhteyttä toisen sielun kanssa.

Pasinkov oli romantikko, viimeisiä romantikkoja kuin minä olen


kohdannut matkallani. Nykyaikaan ovat kuten tietty romantikot
melkein kokonaan kadonneet. Ainakaan niitä ei ole yhtään nykyajan
nuorisossa. Sitä pahempi tälle nykyajan nuorisolle!

Sillä tavalla vietin minä kolme vuolta paraimmassa ystävyydessä


Pasinkovin kanssa. Joka ajatuksen, jokaisen tunteen ilmoitimme me
toinen toisellemme, me olimme, kuten sanotaan, yksi sydän ja yksi
sielu. Niinpä minä sainkin eräänä päivänä tiedon hänen
ensimmäisestä rakkaudestaan, ja minä muistan vielä, miten
kiitollisen ja ihastuneen myötätuntoisesti minä kuuntelin hänen
tunnustustansa.

Hänen kainon rakkautensa esine oli herra Winterkellerin


sisarentytär, sievä, valkoverinen saksalaistyttö, jolla oli pienet
pyöreät lapsenkasvot ja lempeät uskolliset sinisilmät. Hän oli hyvin
hyvä ja tunteellinen tyttö, ihasteli Mattissonia, Ulandia ja Schilleriä ja
saneli heidän runojaan varsin viehättävästi hennolla vaan kirkkaalla
äänellä.

Pasinkovin rakkaus oli niin platoninen kuin mahdollista. Hän tapasi


lemmittyänsä ainoastaan pyhäpäivinä, jolloin hän aina tuli
panttileikkisille Winterkellerin lasten kanssa, ja silloinkin hän puhui
hyvin vähän tytön kanssa. Ja kun tyttö kerran sanoi hänelle: "rakas
herra Jakov", hän ei saanut unta koko seuraavana yönä pelkän
onnentunteen tähden. Hän ei tullut hetkeäkään ajatelleeksi, että tyttö
puhutteli kaikkia muitakin hänen kumppanejansa samalla tavalla:
"rakas herra Se tai Se."

Muistan minä myöskin hänen surunsa ja murheensa, kun eräänä


päivänä se uutinen kerrottiin koulussa, että neiti Fredrika — se oli
tytön nimi — oli mennyt suuren teurastuslaitoksen ja lihakaupan
omistajalle, herra Kniftukselle, joka oli sangen kaunis ja sivistynyt
nuori mies, ja että hän ei ollut sitä tehnyt yksistään
tottelevaisuudesta vanhempiansa kohtaan, vaan totisesta
rakkaudesta.

Se oli kova isku minun ystäväparalleni, ja varsinkin oli hänelle


katkera se päivä, jolloin nuorikot ensi kerran kävivät tervehtimässä
eno Winterkelleriä. Entinen neiti, nykyinen rouva Fredrika esitteli
miehellensä Pasinkovin, sanoen häntä nytkin "rakkaaksi herra
Jakoviksi". Herra Kniftuksessa loisti ja paistoi kaikki tyyni, silmät,
otsa ja hampaat, komeasti kammattu musta tukka, frakin
metallinapit, kultavitjat, jotka riippuivat kauniissa kaaressa liivillä,
yksinpä saappaatkin hänen suurehkoissa ja hyvin ulos päin
pyrkivissä jaloissaan.
Pasinkov puristi hänen kättänsä ja toivotti täydestä sydämmestä
— siitä olen ihan varma — hänelle pitkää häiriytymätöntä onnea.

Se tapahtui minun läsnä ollessani. Muistanpa, miten osaaottavasti


ihmetellen minä katselin ystävääni. Hän näytti minusta oikealta
sankarilta! Ja kun sitte jäimme kahden kesken, miten surumieliset
olivatkaan kaikki meidän sanamme ja ajatuksemme!

"Etsi lohdutusta taiteesta!" sanoin minä hänelle.

"Niin", vastasi hän, "taiteesta ja runoudesta."

"Ja ystävyydestä!" virkoin minä hellästi.

"Niin, ystävyydestä!" toisti hän liikutettuna.

Mitkä viattoman, lapsellisen onnen päivät!

Ero Pasinkovista oli ensimmäinen katkera suru minun elämässäni.


Muutamia viikkoja ennen minun lähtöäni oli hän, kärsittyään paljon
huolia ja vastuksia, pitkän, monesti aivan naurettavankin
kirjeenvaihdon jälkeen monen asianomaisen viraston kanssa,
viimeinkin saanut paperinsa selville, niin että pääsi yliopistoon.
Hyväsydäminen saksalainen kustansi häntä ylioppilaanakin yhä
edelleen, mutta vanhojen sadekappanuttujen ja housujen sijaan sai
hän nyt kunnolliset vaatteet korvaukseksi monenlaisten ainetten
opetuksesta kasvatusisänsä koulun nuorille oppilaille.

Minun seurusteluni hänen kanssansa jatkui aivan samalla tavalla


kuin ennenkin aina viimeiseen hetkeen asti, kuin minä oleskelin
herra Winterkellerin luona, vaikka meidän ikämme ero nyt tuli
enemmin näkyviin kuin ennen ja vaikka minä aloin vähän kadehtia
muutamia hänen uusia ylioppilaskumppanejansa. Hänen
vaikutuksensa minuun oli aina ollut parasta lajia, mutta kovaksi
onneksi sitä ei kestänyt kauan. Minä kerron vain yhden esimerkin
siitä, minkä muutoksen parempaan päin hänen esimerkkinsä voi
saada aikaan minussa. Lapsena olin minä tottunut valehtelemaan.
Mutta Jakovin läsnä ollessa, jopa häntä vain muistellessanikin oli
minun mahdoton saada kieltäni kääntymään valheesen.

Erityinen nautinto oli minusta kävellä hänen kanssansa pitkät


matkat taikka vain astua hänen vieressään edes takaisin huoneessa
ja kuunnella, mitenkä hän minuun katsomatta saneli runoja
hiljaisella, sointuvalla äänellään. Minusta tuntui silloin, kuin me
molemmat olisimme hitaasti ja vähitellen päässeet vapaaksi kaikista
maallisista siteistä ja liidelleet kauas pois johonkin ihmeelliseen,
salaperäisestä kauneudesta säteilevään seutuun.

Erittäin muistan minä erään yön.

Me istuimme yhdessä penkillä sireenipensaan alla; se oli aina


tuosta ensikohtauksesta asti ollut meidän lempipaikkamme. Kaikki
muut makasivat ja nukkuivat. Ääneti ja hiljaa olimme me nousseet
ylös, pukeutuneet puolipimeässä ja hiipineet hiljaa ulos
haaveksimaan. Ulkona taivasalla oli sangen lämmin, mutta tuon
tuostakin tuli raitis tuulenpuuska ja me lähennyimme silloin vielä
lähemmäksi toisiamme. Me puhuimme molemmat paljon ja
innokkaasti, niin että me usein keskeytimme toisemme puhetta,
mutta emme kiistelleet koskaan. Meidän yllämme loisti lukematon
tähtijoukko. Jakov nosti silmänsä tummaa yötaivasta kohti, puristi
minun kättäni ja saneli hiljaa vapisevalla äänellä:

Ylhäällä avaruuden teillä


Täht'joukot ijät' kiertelevät —
Ja kaikki hoitaa Luojan valpas silmä.
Harras vavistus väräytti koko minun nuorta olentoani. Vavisten
kuin vilusta kiersin minä käteni ystäväni kaulaan ja itkin. Sydämmeni
oli täynnä yli taitojensa.

Mihinkä on paennut se nuori, haaveksiva innostus? Sinne pois,


jonne nuoruuden aikakin on mennyt ja josta ei mikään enää palaa
takaisin!

*****

Kahdeksan vuoden kuluttua tapasin minä Pasinkovin Pietarissa.


Minä olin silloin vähän ennen päättänyt antautua virkamiesuralle, ja
eräs sukulainen, jolla oli jonkin verta vaikutusvaltaa, oli hankkinut
minulle pienen paikan eräästä hallintovirastosta.

Meidän jälleen yhtymisemme tuli oikeaksi ilojuhlaksi. Minä en voi


koskaan unhottaa sitä hetkeä. Eräänä päivänä keskitalvella istuen
yksin huoneessani kuulin hänen äänensä tampuurista. Miten minä
vavahdin sen rakkaan äänen kaiusta, miten sydämmeni sykki, kuin
juoksin hänelle kaulaan, antamatta hänelle aikaa riisua turkkiansa tai
edes päästää vyötäkään vyöltänsä! Miten innokkaasti minä häntä
katselin kyynelien lävitse, jotka liikutuksesta vasten tahtoani nousivat
pimittämään silmiäni!

Hän oli vähän vanhennut seitsemän viime vuoden kuluessa.


Otsassa oli koko joukko hienoja ryppyjä, posket syvälle painuneet ja
tukka harvennut, multa partaa ei ollut kasvanut ja hymy oli vielä
ennallaan. Ja hänen naurunsa, tuo omituinen minulle niin rakas
sisällinen, melkein nyyhkyttävä nauru oli myöskin sama kuin ennen.

Olipa meillä sinä päivänä puhumista, kyselemistä ja kertomista


keskenämme! Miten paljon vanhoja lempirunoelmia me luimme
toinen toisellemme!

Minä pyysin häntä muuttamaan minun luokseni asumaan, mutta


siihen hän ei suostunut. Sen sijaan lupasi hän käydä tervehtimässä
minua joka päivä ja sen lupauksensa hän myöskin piti.

Ei Pasinkov ollut sisällisestikään muuttunut. Hän oli yhä vielä


sama romantikko kuin ennenkin. Vaikka elämän halla, kokemuksen
kylmä viima oli viileksinyt hänen olemustansa sisäisimpiin
komeroihin asti, niin se kaunis kukka, joka oli jo aikaisin alkanut
juurtua hänen sydämmeensä, kuitenkin oli säilyttänyt hennon, raittiin
kauneutensa kokonaisena, ihan eheänä. Minä en voinut hänessä
huomata surua enkä huolia. Hän oli kuten ennenkin hiljainen ja
äänetön, mutta aina hyväsydämminen ja ystävällinen kaikkia kohti.

Pietarissa eli hän kuin erämaassa, ei huolehtinut vähääkään


vastaisesta elämästänsä eikä seurustellut juuri kenenkään kanssa.

Minä vein hänet Slotnitskin perheesen ja sitte kävi hän siellä


sangen usein. Hän ei ollut itserakas, ei arka eikä kaino, mutta
sielläkin, kuten kaikkialla muualla, oli hän yleensä hyvin äänetön ja
hiljainen. Kuitenkin häntä mielellään nähtiin siellä vieraana. Ei
ainoastaan Tatjana Vasiljevna, joka samoin oli hyvin hiljainen, vaan
myöskin hänen vanha miehensä, jonka kanssa ei juuri ollut helppo
seurustella, otti aina hänet ystävällisesti vastaan, ja molemmat
harvapuheiset tytöt myöskin tottuivat kohta hänen hiljaiseen,
ystävälliseen käytökseensä.

Usein oli hänellä tullessaan muutamia äsken ilmestyneitä


runoelmia pitkän aina nuuskanruskean takkinsa takataskussa.
Pitkään aikaan hän ei saa ottaneeksi esille kirjaansa, vaan istuu ja
ojentelee päätänsä joka taholle kuin lintu, katsellakseen, oliko
missään sopivaa nurkkaa, johon hän voisi vetäytyä syrjään. Hän
yleensä mielellään istuu aina nurkassa. Löydettyään viimein pikku
paikan jostakin sopukasta ottaa hän esiin kirjan ja alkaa lukea ensin
hiljaa, melkein kuiskaavalla äänellä, sille vähitellen yhä kovemmin,
keskeyttäen siiloin tällöin itseään jollakin lyhyellä huomautuksella tai
huudahduksella.

Minä panin huomiooni, että sellaisissa tapauksissa Varvara


mieluisemmin kuin hänen sisarensa lähestyi häntä ja kuunteli hänen
lukemistansa, vaikka hän tosin ei ymmärtänytkään kaikkea. Yleensä
Varvara hyvin vähän harrasti kirjallisuutta. Hän tavallisesti kävi
istumaan juuri Pasinkovin eteen, laski leukansa käsien nojaan ja
katseli häntä keskelle kasvoja eikä silmiin. Koko lukemisen aikana
hän ei lausunut sanaakaan, mutta välistä veti syvän huokauksen.

Iltasilla, varsinkin pyhä- ja juhlapäivinä me olimme panttisilla.


Silloin tuli tavallisesti lisäksi myöskin kaksi nuorta tyttöä, Slotnitskien
sisaria ja etäisempiä sukulaisia sekä pari kadettia tai muita nuoria
poikia. Tytöt olivat sievänlaiset, lyhyehköt, hyvin iloiset ja herkät
nauramaan. Pojat varsin siivot ja käytökseltään siistit, ja silloin oli
varsin iloista ja hupaista muuten niin äänettömässä ja hiljaisessa
huoneessa.

Näiden leikkien aikana istui Pasinkov aina Tatjana Vasiljevnan


vieressä. Heidän molempain tuli ajatella, "mitä sen piti tehdä, joka
tunsi pantin omakseen", eikä se ollut mikään helppo tehtävä.

Sofia ei pitänyt suuteloista eikä muista hellyyden osoituksista, joilla


pantti tavallisesti lunastetaan, ja Varvara suuttui milloin hänen piti
etsiä tai arvata jotakin.
Molemmat nuoret sukulaiset nauroivat lakkaamatta, huolimatta
mistään. Mitä ihmettä heillä saattoi ollakaan nauraa niin
herkeämättä! Välistä minä oikein pahastuin heitä katsellessani,
mutta Pasinkov vain hymyili ystävällisesti ja nyykytti päätänsä.

Ukko Slotnitski ei ottanut osaa meidän leikkeihimme, vaan istui


huoneessaan ja katseli äreästi ja tyytymättömästi meitä avonaisesta
ovesta. Mutta kerran sattui, että hän ihan yht'äkkiä kenenkään
aavistamatta tuli ulos ja ehdotti, että se, joka tunsi pantin omakseen,
tanssisi hänen kanssansa valssin. Tietysti ehdotus hyväksyttiin.
Tatjana Vasiljevnan pantti tuli näkyviin. Hän joutui hyvin hämilleen ja
punastui kuin viisitoista vuotinen tyttö; mutta hänen miehensä käski
Sofiaa soittamaan, kumarsi rouvalleen ja tanssi hänen kanssansa
vanhaan tapaan kolmen neljäsosan tahdissa kaksi kertaa salin
ympäri.

Muistan varsin hyvin, miten hänen mustaveriset, kellertävät


kasvonsa terävine pikku silmineen, joissa ei muuten koskaan
näkynyt hymyä, milloin oli näkyvissä, milloin piilossa, hänen hitaasti
pyöriessään, unhottamatta koskaan tavallista ankaruuttansa, joka
hänen muodossansa asui. Tanssissa hän harppasi pitkiä askelia ja
vähän hypähti joka uuden tahdin alussa, mutta hänen rouvansa
liikutteli jalkojaan sukkelaan ja sievästi sekä ikään kuin pelosta
painoi kasvojaan hänen rintaansa vasten.

Valssin loputtua vei hän hänet takaisin istuinpaikalleen, kumarsi,


meni huoneesensa jälleen ja veti oven jälkeensä kiinni.

Sofia aikoi nyt nousta pois pianon edestä. Mutta Varvara pyysi
häntä soittamaan edelleen, meni Pasinkovin luo ja ojentaen hänelle
kätensä, sanoi hämillään hymyillen:
"Tahdotteko?"

Pasinkov näytti hyvin kummastuneelta, mutta nousi heti, hän kun


aina oli erinomaisen kohtelias, ja laski kätensä Varvaran vyötäisille.
Vaan ensi askeleella hän jo lipesi ja kaatui, ja koettaessaan äkisti
irrottautua naisestaan sysäsi hän kyynyspäällään sitä, pikku pöytää,
jolla papukaijan häkki oli.

Häkki putosi lattialle, papukaija peljästyi ja alkoi huutaa: "kivääri


käteen!" Siitä syntyi yleinen nauru. Ukko Slotnitski näyttäytyi
huoneensa kynnyksellä, katsahti tyytymättömästi tuota
epäjärjestystä ja paiskasi kiivaasti oven jäljestään kiinni. Aina siitä
asti ei tarvittu muuta kuin mainita sitä tapausta Varvaran
läsnäollessa, niin hän heti alkoi nauraa ja katsoa Pasinkoviin, ikään
kuin hän olisi tahtonut sanoa, että kerrassaan mahdoton oli keksiä
mitään hauskempaa, kuin Pasinkov silloin teki.

Pasinkov rakasti suuresti musiikkia. Usein pyysi hän Sofia


Nikolajevnaa soittamaan jotakin ja istui silloin nurkassa kuunnellen ja
hiljaa hyräillen mukaan tuntehikkaimmissa paikoissa. Varsinkin
ihasteli hän Schubertin "Tähtitaivasta". Hän vakuutti, että hänestä
sitä kappaletta kuunnellessa aina tuntui, kuin yht'aikaa sävelien
kanssa pitkät siniset valosäteet ampuisivat korkeudesta suorastaan
häntä rintaan. Ja nyt minä katsellessani pilvetöntä tähtikirkasta
yötaivasta en voi olla muistelematta Pasinkovia ja Schubertin
säveliä.

Viimeksi johtuu minulle mieleen huvimatka, jonka teimme


Slotnitskin perheen kanssa Pargalaan [suuren, kaunisseutuisen
järven rannalle, joka on 1 1/2 peninkulman päässä Pietarista
Viipuriin piin].
Me ajoimme koko seura kaksissa neljän istuttavissa ajurin
vaunuissa, joissa oli c:n muotoiset vieterit, korkeat kuskinistuimet ja
heinillä täytetyt istuintyynyt. Ruunit, kivulloiset hevoset, jotka ontuivat
jokainen eri jalkaa, veivät meidät hitaassa juoksussa perille.

Me kävelimme kauan kauneissa hongikoissa, joimme maitoa


suurista savipulloista ja söimme mansikoita sokurin kanssa. Ilma oli
ihana. Varvara yleensä ei mielellään kävellyt paljoa, hän kun pian
väsyi, mutta tällä kertaa hän ei jäänyt jäljelle meistä muista. Hän oli
ottanut hatun päästään, tukka riippui vapaana, hitaisuus oli
muuttunut elävyydeksi ja kasvoja kaunisti raitis puna. Tavattuaan
metsässä kaksi pientä talonpoikaistyttöä istahti hän heti alas
maahan, huusi tytöt luoksensa ja asetti heidät istumaan viereensä,
mutta muuten ei osoittanut heille mitään ystävyyttä.

Sofia, jolla seurakumppanina oli herra Asanov, katsahti heihin


kylmäkiskoisesti hymyillen, mutta ei huolinut heistä sen enempää.
Ukko Slotnitski huomautti, että Varvara oli oikea "pesäkana", ja
silloin Varvara heti nousi ylös ja astui edelleen. Pari kertaa tällä
kävelyretkellä metsässä meni hän Pasinkovin luo ja sanoi:

"Jakov Ivanits, minulla on jotakin sanomista teille." Mutta mitä


hänellä oli sanottavaa, Pasinkov ei saanut koskaan tietää.

Vaan jopa on aika palata keskeytyneesen kertomukseeni takaisin.


V.

Minä ilostuin hyvin Pasinkovin tulosta, mutta kun ajattelin, mitä olin
tehnyt edellisenä päivänä, jouduin niin häpeihini, että käännyin
jälleen seinään päin, sanomatta hänelle sanaakaan.

Odoteltuaan hetkisen vaiti, kysyi Pasinkov, enkö minä voinut


hyvin.

"Kyllä, kiitos kysymyksestäsi", mutisin minä hammasten välistä,


"minun vain vähän kivistää päätäni."

Jakov ei enää kysellyt mitään, vaan otti kirjan, istahti nurkkaan ja


rupesi lukemaan.

Siten kului toista tuntia. Minä jo olin ihan ryhtymässä kertomaan


hänelle kaikki tyyni, kuin äkisti tampuurin kello soi, ilmoittaen jonkun
tulevan.

Tampuurin ovi aukesi. Minä kuuntelin, Asanovin ääni kysyi minun


palvelijaltani, olinko minä kotona.

Pasinkov nousi. Hän ei pitänyt Asanovista, jonka tähden hän


minulle kuiskasi menevänsä sisähuoneesen ja käyvänsä minun
sänkyyni odottamaan, ja hän meni.

Juuri samassa astui sisään Asanov.

Jo hänen kiihkosta punaisten kasvojensa muodosta sekä lyhyestä


ja äreästä tervehdyksestään minä aavistin, että hän ei suinkaan ollut
tullut vain huviksensa. "Mitähän tästäkin nyt tulee?" ajattelin minä
itsekseni vähän levottomana.

"Hyvä herra", alkoi Asanov, käyden nojatuoliin istumaan, "minä


tulin teidän luoksenne, että te saisitte tilaisuuden haihduttaa minulta
eräitä epäilyksiä."

"Vai niin, todellako?"

"Niin, juuri niin. Minä tahdon tietää, oletteko te kunniallinen mies."

"Mitä te niillä sanoilla tarkoitatte?" kysyin minä kiivastuen.

"Niin, minä tarkoitan yhtä tosi asiaa", vastasi hän pannen eri
painoa joka sanalle. "Eilen minä näytin teille lompakkoani, jossa oli
erään henkilön kirjeitä minulle. Tänään te olette nenäkkäästi ja
sopimattomasti nuhdellen — huomatkaa tarkkaan: nenäkkäästi ja
sopimattomasti nuhdellen — maininneet samalle henkilölle
muutamia sanoja niistä kirjeistä, vaikka teillä ei ole ollut mitään
oikeuden tapaistakaan sellaiseen, lievimmiten sanoen, kömpelöön
käytökseen. Minä haluan sen tähden kuulla, miten te aiotte selittää
tuon kaikin puolin moitittavan käytöksenne."

"Ja minä haluan tietää, mikä oikeus teillä on tällä tavoin tutkistella
minua", vastasin minä, vavisten sekä häpeästä että kiukusta. "Jos te
huviksenne sopimattomasti kerskailette ylhäisistä tuttavuuksistanne
ja huvittavasta kirjeenvaihdostanne, mitä se minuun koskee? Vai
eivätkö ehkä kaikki kirjeenne teillä enää ole tallella?"

"Kirjeet minulla kyllä on tallella, mutta minä olin eilisiltana


sellaisessa tilassa, että te varsin helposti saatoitte…"

"Lyhyesti puhuen, hyvä herra", keskeytin minä ja puhuin tahallani


niin kovasti kuin mahdollista, "minä pyydän teitä jättämään minua
rauhaan, kuuletteko? Minä en tahdo mitään tietää enkä aio antaa
teille mitään selityksiä käytöksestäni. Saatattehan mennä
tiedustelemaan siltä eräältä henkilöltä, ehkä hän osaa selitellä teille
asiat."

Minä tunsin, miten suuttumus kiehui minussa, ja päätäni pyörrytti.

Asanov katsoi minuun, nähtävästi koettaen tehdä katsettaan


pilkalliseksi ja läpitunkevan teräväksi, siveli viiksiänsä ja nousi
hitaasti seisomaan.

"Minä tiedän nyt, mitä minun tulee ajatella", sanoi hän. "Teidän
muotonne todistaa kyllin selvästi teitä vastaan. Mutta minä sanon
teille, että oikea aatelismies ei tee sillä tavalla. Varkain lukea toisten
kirjeitä ja sitte mennä nuoren, ylhäis-sukuisen naisen luo
häiritsemään hänen rauhaansa…"

"Menkää hiiteen! sanon minä teille", tiuskasin ihan raivoisesti ja


jalkaa polkien. "Lähettäkää tänne sekundanttinne, minä en aio teidän
kanssanne vaihtaa enää sanaakaan."

"Te voitte säästää opetuksenne sellaiselle, joka niitä paremmin


tarvitsee", vastasi Asanov kylmästi. "Minä aioin itsestänikin lähettää
tänne sekundantit."
Hän läksi

Uuvuksissa vaivuin minä sohvalle ja peitin kasvoni käsilläni. Joku


koski minua olkapäähän. Minä katsahdin ylös. Se oli Pasinkov.

"Mitä tämä merkitsee?" kysyi hän. "Onko se tosiaankin totta?


Oletko sinä lukenut toisten kirjeitä?"

Minulla ei ollut voimaa vastata, minä vain nyykäytin päätäni


myöntävästi.

Pasinkov meni ikkunan luo. Seisoen seljin minuun sanoi hän


hitaasti:

"Sinä olet lukenut nuoren tytön kirjeen Asanoville. Kuka se nuori


tyttö on?"

"Sofia Nikolajevna", vastasin minä sellaisella äänellä, kuin syytetty


vastaa tuomarillensa.

Pasinkov seisoi pitkän hetken vaiti ja ajatuksiin vaipuneena.

"Ainoastaan tunteiden kiihko voi olla jonkin verran


puolustuksenasi", sanoi hän viimein. "Rakastatko sinä häntä, sitä
nuorta tyttöä?"

"Rakastan."

Pasinkov oli taas vaiti pitkän ajan.

"Sitä luulinkin. Ja sinä olet tänään käynyt häntä torumassa…"

"Olen, olen, olen", keskeytin minä toivottomasti. "Sinulla on kyllin


syytä halveksia minua."

You might also like