Статьи

Отличная поездка на верблюде

Apache Camel — это механизм маршрутизации и посредничества, который реализует шаблоны интеграции предприятия . Но не позволяйте словам Enterprise Integration напугать вас. Верблюд разработан, чтобы быть действительно легким и иметь небольшую площадь. Его можно повторно использовать где угодно, будь то в сервлете, в стеке веб-служб, в полном ESB или в автономном приложении обмена сообщениями.

Camel делает реализацию приложений для обмена сообщениями действительно простой. Так что не так много причин, по которым вы не могли бы использовать его в приложениях не для предприятий. Фактически, можно использовать Camel как инструмент, аналогичный тому, как вы используете языки сценариев. Например, вы можете запустить веб-консоль Camel и определить приложение для обмена сообщениями без написания ни одной строки кода.

Эта статья является учебным пособием для начинающих. Как вы уже догадались, я собираюсь использовать Groovy в качестве языка программирования. И программы в этой статье предназначены для запуска с Groovysh, Groovy Shell . Причины:

  • Groovy лаконичен, выразителен и имеет меньше шума, чем Java. Все программы в этой статье занимают всего пару десятков строк, и им должно быть очень легко следовать.
  • Использование Groovysh позволяет читателю взаимодействовать с приложением.

 

 


Я парень из Linux, и я хорошо разбираюсь в VIM и работаю в командной строке.
Так обнажиться со мной.

 

Собираем кусочки

Во-первых, я собираюсь написать простую программу, чтобы убедиться, что я могу поговорить с Camel в Groovy. Я не использую IDE, такую ​​как Eclipse, не создаю проект и не собираюсь использовать инструменты сборки, такие как Maven. Любого текстового редактора будет достаточно. Сохраните следующий код в файл с именем CamelDemo.groovy ( загрузка исходного кода ).

import groovy.grape.Grape
Grape.grab(group:"org.apache.camel", module:"camel-core", version:"2.0.0")

class MyRouteBuilder extends org.apache.camel.builder.RouteBuilder {
void configure() {
from("direct://foo").to("mock://result")
}
}

mrb = new MyRouteBuilder()
ctx = new org.apache.camel.impl.DefaultCamelContext()
ctx.addRoutes mrb
ctx.start()

p = ctx.createProducerTemplate()
p.sendBody "direct:foo", "Camel Ride for beginner"

e = ctx.getEndpoint("mock://result")
ex = e.exchanges.first()
println "INFO> ${ex}"

Эта маленькая программа делает несколько вещей:

  • Импорт в верблюжьего основной Jar с помощью Grape.grab ()
  • Определяет наш пользовательский RouteBuilder, который определяет простой маршрут между точками direct: foo и mock: result.
  • Создает экземпляр CamelContext , добавляет к нему наш пользовательский RouteBuilder и запускает Camel с помощью ctx.start () .
  • Тестируется маршрут, отправив обмен сообщениями с использованием producerTemplate , полученный из CamelContext
  • Выполняет поиск конечной точки mock: result ( ctx.getEndpoint («mock: result») ) и отображает первый Exchange , который должен содержать только что отправленное сообщение.

 

Теперь запустите groovysh в командном окне и загрузите программу:

$ groovysh
groovy:000> load CamelDemo.groovy

Вы должны увидеть кучу выходных данных, а затем вывод из сценария:

INFO> Exchange[Message: Camel Ride for beginner]
===> null
groovy:000>

На данный момент вы можете взаимодействовать с программой через groovysh . Например, ниже показано несколько вещей, которые вы можете сделать.

groovy:000> ctx.routes
===> [EventDrivenConsumerRoute[Endpoint[seda://foo] -> UnitOfWork(Channel[sendTo(Endpoint[mock://result])])]]
groovy:000> ctx.components
===> {mock=org.apache.camel.component.mock.MockComponent@14f2bd7, seda=org.apache.camel.component.seda.SedaComponent@c759f5}
groovy:000> ctx.endpoints
===> [Endpoint[seda://foo], Endpoint[mock://result]]
groovy:000> ctx.endpoints[1].exchanges
===> [Exchange[Message: Camel Ride for beginner]]
groovy:000> ctx.endpoints[1].exchanges[0].in.body
===> Camel Ride for beginner
groovy:000> p.sendBody("seda:foo", "Camel Kicking")
===> null
groovy:000> e.exchanges
===> [Exchange[Message: Camel Ride for beginner], Exchange[Message: Camel Kicking]]

Это для нашей первой программы Groovy / Camel. Для любопытных можно реально модифицировать программу и перезагрузить ее, не прерывая и не перезапуская groovysh .

Верблюд Фондовый Цитата

Это простое приложение котировки акций. Первоначально я планировал провести вас через этапы разработки, от добавления простого компонента в качестве процессора до его преобразования в многоканальное сервисное приложение с несколькими форматами данных.

Но после того, как я закончил разработку программы, оказалось, что это слишком просто, чтобы оправдать такую ​​разработку. Чтобы сэкономить ваше и мое время, я просто покажу вам окончательный вариант прямо здесь. Взгляните на него, и если вы можете понять, что он делает, возможно, вам следует пропустить оставшуюся часть этой статьи ?

Сохраните следующий код в файл с именем StockQuote.groovy ( загрузка исходного кода ).


import groovy.grape.Grape
Grape.grab(group:"org.apache.camel", module:"camel-core", version:"2.0.0")
Grape.grab(group:"org.apache.camel", module:"camel-jetty", version:"2.0.0")
Grape.grab(group:"org.apache.camel", module:"camel-freemarker", version:"2.0.0")

class QuoteServiceBean {
public String usStock(String symbol) {
"${symbol}: 123.50 US\$"
}
public String hkStock(String symbol) {
"${symbol}: 90.55 HK\$"
}
}

class MyRouteBuilder extends org.apache.camel.builder.RouteBuilder {
void configure() {
from("direct://quote").choice()
.when(body().contains(".HK")).bean(QuoteServiceBean.class, "hkStock")
.otherwise().bean(QuoteServiceBean.class, "usStock")
.end().to("mock://result")
from("direct://xmlquote").transform().xpath("//quote/@symbol", String.class).to("direct://quote")
//curl -H "Content-Type: text/xml" http://localhost:8080/quote?symbol=IBM
from('jetty:http://localhost:8080/quote').transform()
.simple('<quote symbol="${header.symbol}"></quote>').to("direct://xmlquote").choice()
.when(header("Content-Type").isEqualTo("text/xml")).to("freemarker:xmlquote.ftl")
.otherwise().to("freemarker:htmlquote.ftl")
.end()
}
}

ctx = new org.apache.camel.impl.DefaultCamelContext()
mrb = new MyRouteBuilder()
ctx.addRoutes mrb
ctx.start()
p = ctx.createProducerTemplate()

//p.sendBody("direct:quote", "00005.HK")
//p.sendBody("direct:xmlquote", "<quote symbol='IBM'/>")
//p.sendBody("direct:xmlquote", "<quote symbol='00005.HK'/>")

e = ctx.getEndpoint("mock://result")
//e.exchanges.each { ex ->
// println "INFO> in.body='${ex.in.body}'"
//}

ОК, ты все еще здесь.

Предполагается, что:

  • У нас есть два провайдера рыночных данных: один для рынка США, другой для рынка Гонконга.
  • Существующий класс QuoteServiceBean был реализован как POJO. У него есть два метода, usStock () и hkStock () . Это часть унаследованной системы, она прекрасно работает, она скрывает основные детали взаимодействия с поставщиками данных. Никто не понимает этого, и никто не осмеливается изменить его.
  • Мы хотели бы использовать существующий QuoteServiceBean для предоставления услуги биржевых котировок, которую можно легко использовать. т.е. многоканальный и мульти-формат данных.

 

Контент-маршрутизатор и транслятор сообщений

 

    from("direct://quote").choice()
.when(body().contains(".HK")).bean(QuoteServiceBean.class, "hkStock")
.otherwise().bean(QuoteServiceBean.class, "usStock")
.end().to("mock://result")

Первый маршрут (начало в строке 17) представлен конечной точкой direct: quote . Он направляет сообщение в соответствии с содержанием тела обмена, которое, как предполагается, содержит символ акции. Когда тело обмена содержит строку «.HK» THE hkStock (строка символов) из QuoteServiceBean называется, в противном случае usStock (строка символов) из QuoteServiceBean называется. Обратите внимание, что маршрут DSL почти читается как обычный английский!

Давайте попробуем это. Сначала запусти groovysh , загрузи программу и отправь два сообщения на прямую: quote endpoint:

jack@localhost tmp]$ groovysh 
Groovy Shell (1.6.6, JVM: 1.6.0_11)
groovy:000> load StockQuote.groovy
..............
groovy:000> p.sendBody("direct:quote", "00001.HK")
===> null
groovy:000> e.exchanges.last()
===> Exchange[Message: 00001.HK: 90.55 HK$]
groovy:000> p.sendBody("direct:quote", "SUNW")
===> null
groovy:000> e.exchanges.last()
===> Exchange[Message: SUNW: 123.50 US$]
groovy:000>

Вот и все, наш простой контентно-ориентированный маршрутизатор успешно направляет запрос в соответствующие методы процессора.

Запрос XML-цитаты, преобразование сообщения

 

    from("direct://xmlquote").transform().xpath("//quote/@symbol", String.class).to("direct://quote")

 

Этот следующий маршрут просто принимает запросы в XML, преобразует запрос и объединяет его в цепочку direct: // quote . Благодаря этому мы добавили возможность принимать запросы в формате XML!


Мы используем
XPath здесь для выражения нашего преобразования. Проверьте хосты
Expression Langauges, поддерживаемые Camel.

Давайте попробуем это:

groovy:000> p.sendBody("direct:xmlquote", "<quote symbol='GOOG'/>")
===> null
groovy:000> e.exchanges.last()
===> Exchange[Message: GOOG: 123.50 US$]
groovy:000>

 

Многоканальное предоставление нескольких форматов данных

 

Grape.grab(group:"org.apache.camel", module:"camel-jetty", version:"2.0.0")
Grape.grab(group:"org.apache.camel", module:"camel-freemarker", version:"2.0.0")
// ........... lines removed for brevity .............
from('jetty:http://localhost:8080/quote').transform()
.simple('<quote symbol="${header.symbol}"></quote>').to("direct://xmlquote").choice()
.when(header("Content-Type").isEqualTo("text/xml")).to("freemarker:xmlquote.ftl")
.otherwise().to("freemarker:htmlquote.ftl")
.end()

 

Здесь мы используем верблюжий причал, чтобы раскрыть причал конечной точки : http: // localhost: 8080 / quote нашему сервису котировок . Обратите внимание, что верблюжья пристань не является частью верблюжьего ядра . Вот почему мы должны включить это в нашу программу.

HTTP-запрос переводится в XML с помощью простого выражения . Обратите внимание, что Camel-Jetty любезно извлек параметры запроса, а также заголовок HTTP и поместил их в заголовок сообщения . Таким образом, символом параметра запроса является доступ как $ {header.symbol} в выражении.

Затем мы просто связываем обмен сообщениями с конечной точкой direct: xmlquote .

Результат от direct: xmlquote прошел через другой перевод, который зависит от типа содержимого исходного HTTP-запроса. Здесь я использую верблюд-свободный маркер для генерации желаемого результата. Итак, нам нужно создать два шаблона Freemarker:

htmlquote.ftl

<html>
<head>
</head>
<body>
<em>${body}</em>
</body>
</html>

xmlquote.ftl

<quote-result symbol='${headers.symbol}'>
${body}
</quote-result>

 

Итак, давайте посмотрим на это в действии, я собираюсь использовать curl для выполнения HTTP-запросов. Сделайте это в другом командном окне:

 

[jack@localhost tmp]$ curl http://localhost:8080/quote?symbol=IBM
<html>
<head>
</head>
<body>
<em>IBM: 123.50 US$</em>
</body>
</html>
[jack@localhost tmp]$ curl http://localhost:8080/quote?symbol=00001.HK
<html>
<head>
</head>
<body>
<em>00001.HK: 90.55 HK$</em>
</body>
</html>
[jack@localhost tmp]$

 

И для запроса содержимого XML:

 

[jack@localhost tmp]$ curl -H "Content-Type: text/xml" http://localhost:8080/quote?symbol=IBM
<quote-result symbol='IBM'>
IBM: 123.50 US$
</quote-result>
[jack@localhost tmp]$

 

Вот и все для нашего многоканального / мульти-форматного обслуживания.

Резюме

В этом уроке я надеялся проиллюстрировать, как Camel поддерживает стиль разработки приложений, основанный на передаче сообщений. Верблюд предоставляет все виды компонентов, которые помогут вам построить конвейеры обработки. Все, что вам нужно, это реализовать свою бизнес-логику в виде простых POJO и позволить Camel обрабатывать все переводы, маршрутизацию, фильтрацию, разбиение и пересылку для вас.

В этом руководстве не показано, как использовать внешние ресурсы и службы из маршрута. Нет пота, это так же просто.

Camel прекрасно интегрируется как с Spring, так и с Guice, но прекрасно работает сам по себе. Это не будет на вашем пути, если вам не нужна поддержка DI в вашем приложении. Как говорится: держи простое легко .

Camel прекрасно работает в среде JBI, такой как ServiceMix и OpenESB. Camel готов к OSGI и отслеживает вновь развернутые пакеты для определений маршрутов во время выполнения. Таким образом, вы можете сделать все, чтобы стать частью корпоративной SOA-инфраструктуры.

Отказ от ответственности, я не опытный пользователь Camel и все еще учусь. Спасибо, что остаетесь со мной.