=doc #3689 Make activator templates for camel samples
* @rkuhn found the problems in the scala camel samples - HttpSample returns scrambled data - CustomRouteSample times out
|
|
@ -312,7 +312,7 @@ to do other work) and resume processing when the response is ready. This is
|
|||
currently the case for a `subset of components`_ such as the `Jetty component`_.
|
||||
All other Camel components can still be used, of course, but they will cause
|
||||
allocation of a thread for the duration of an in-out message exchange. There's
|
||||
also a :ref:`camel-async-example-java` that implements both, an asynchronous
|
||||
also :ref:`camel-examples-java` that implements both, an asynchronous
|
||||
consumer and an asynchronous producer, with the jetty component.
|
||||
|
||||
If the used Camel component is blocking it might be necessary to use a separate
|
||||
|
|
@ -469,116 +469,18 @@ __ https://svn.apache.org/repos/asf/camel/tags/camel-2.8.0/camel-core/src/main/j
|
|||
Examples
|
||||
========
|
||||
|
||||
.. _camel-async-example-java:
|
||||
The `Typesafe Activator <http://typesafe.com/platform/getstarted>`_
|
||||
tutorial named `Akka Camel Samples with Java <http://typesafe.com/activator/template/akka-sample-camel-java>`_
|
||||
contains 3 samples:
|
||||
|
||||
Asynchronous routing and transformation example
|
||||
-----------------------------------------------
|
||||
* Asynchronous routing and transformation - This example demonstrates how to implement consumer and
|
||||
producer actors that support :ref:`camel-asynchronous-routing-java` with their Camel endpoints.
|
||||
|
||||
* Custom Camel route - Demonstrates the combined usage of a ``Producer`` and a
|
||||
``Consumer`` actor as well as the inclusion of a custom Camel route.
|
||||
|
||||
This example demonstrates how to implement consumer and producer actors that
|
||||
support :ref:`camel-asynchronous-routing-java` with their Camel endpoints. The sample
|
||||
application transforms the content of the Akka homepage, http://akka.io, by
|
||||
replacing every occurrence of *Akka* with *AKKA*. To run this example, add
|
||||
a Boot class that starts the actors. After starting
|
||||
the :ref:`microkernel-java`, direct the browser to http://localhost:8875 and the
|
||||
transformed Akka homepage should be displayed. Please note that this example
|
||||
will probably not work if you're behind an HTTP proxy.
|
||||
|
||||
The following figure gives an overview how the example actors interact with
|
||||
external systems and with each other. A browser sends a GET request to
|
||||
http://localhost:8875 which is the published endpoint of the ``HttpConsumer``
|
||||
actor. The ``HttpConsumer`` actor forwards the requests to the ``HttpProducer``
|
||||
actor which retrieves the Akka homepage from http://akka.io. The retrieved HTML
|
||||
is then forwarded to the ``HttpTransformer`` actor which replaces all occurrences
|
||||
of *Akka* with *AKKA*. The transformation result is sent back the HttpConsumer
|
||||
which finally returns it to the browser.
|
||||
|
||||
.. image:: ../images/camel-async-interact.png
|
||||
|
||||
Implementing the example actor classes and wiring them together is rather easy
|
||||
as shown in the following snippet.
|
||||
|
||||
.. includecode:: code/docs/camel/sample/http/HttpConsumer.java#HttpExample
|
||||
.. includecode:: code/docs/camel/sample/http/HttpProducer.java#HttpExample
|
||||
.. includecode:: code/docs/camel/sample/http/HttpTransformer.java#HttpExample
|
||||
.. includecode:: code/docs/camel/sample/http/HttpSample.java#HttpExample
|
||||
|
||||
The `jetty endpoints`_ of HttpConsumer and HttpProducer support asynchronous
|
||||
in-out message exchanges and do not allocate threads for the full duration of
|
||||
the exchange. This is achieved by using `Jetty continuations`_ on the
|
||||
consumer-side and by using `Jetty's asynchronous HTTP client`_ on the producer
|
||||
side. The following high-level sequence diagram illustrates that.
|
||||
|
||||
.. _jetty endpoints: http://camel.apache.org/jetty.html
|
||||
.. _Jetty continuations: http://wiki.eclipse.org/Jetty/Feature/Continuations
|
||||
.. _Jetty's asynchronous HTTP client: http://wiki.eclipse.org/Jetty/Tutorial/HttpClient
|
||||
|
||||
.. image:: ../images/camel-async-sequence.png
|
||||
|
||||
Custom Camel route example
|
||||
--------------------------
|
||||
|
||||
This section also demonstrates the combined usage of a ``Producer`` and a
|
||||
``Consumer`` actor as well as the inclusion of a custom Camel route. The
|
||||
following figure gives an overview.
|
||||
|
||||
.. image:: ../images/camel-custom-route.png
|
||||
|
||||
* A consumer actor receives a message from an HTTP client
|
||||
|
||||
* It forwards the message to another actor that transforms the message (encloses
|
||||
the original message into hyphens)
|
||||
|
||||
* The transformer actor forwards the transformed message to a producer actor
|
||||
|
||||
* The producer actor sends the message to a custom Camel route beginning at the
|
||||
``direct:welcome`` endpoint
|
||||
|
||||
* A processor (transformer) in the custom Camel route prepends "Welcome" to the
|
||||
original message and creates a result message
|
||||
|
||||
* The producer actor sends the result back to the consumer actor which returns
|
||||
it to the HTTP client
|
||||
|
||||
|
||||
The consumer, transformer and
|
||||
producer actor implementations are as follows.
|
||||
|
||||
.. includecode:: code/docs/camel/sample/route/Consumer3.java#CustomRouteExample
|
||||
.. includecode:: code/docs/camel/sample/route/Transformer.java#CustomRouteExample
|
||||
.. includecode:: code/docs/camel/sample/route/Producer1.java#CustomRouteExample
|
||||
.. includecode:: code/docs/camel/sample/route/CustomRouteSample.java#CustomRouteExample
|
||||
|
||||
The producer actor knows where to reply the message to because the consumer and
|
||||
transformer actors have forwarded the original sender reference as well. The
|
||||
application configuration and the route starting from direct:welcome are done in the code above.
|
||||
|
||||
To run the example, add the lines shown in the example to a Boot class and the start the :ref:`microkernel-java` and POST a message to
|
||||
``http://localhost:8877/camel/welcome``.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
curl -H "Content-Type: text/plain" -d "Anke" http://localhost:8877/camel/welcome
|
||||
|
||||
The response should be:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Welcome - Anke -
|
||||
|
||||
Quartz Scheduler Example
|
||||
------------------------
|
||||
|
||||
Here is an example showing how simple is to implement a cron-style scheduler by
|
||||
using the Camel Quartz component in Akka.
|
||||
|
||||
The following example creates a "timer" actor which fires a message every 2
|
||||
seconds:
|
||||
|
||||
.. includecode:: code/docs/camel/sample/quartz/MyQuartzActor.java#QuartzExample
|
||||
.. includecode:: code/docs/camel/sample/quartz/QuartzSample.java#QuartzExample
|
||||
|
||||
For more information about the Camel Quartz component, see here:
|
||||
http://camel.apache.org/quartz.html
|
||||
* Quartz Scheduler Example - Showing how simple is to implement a cron-style scheduler by
|
||||
using the Camel Quartz component
|
||||
|
||||
Additional Resources
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
package docs.camel.sample.http;
|
||||
|
||||
import akka.actor.*;
|
||||
|
||||
public class HttpSample {
|
||||
public static void main(String[] args) {
|
||||
//#HttpExample
|
||||
// Create the actors. this can be done in a Boot class so you can
|
||||
// run the example in the MicroKernel. Just add the three lines below
|
||||
// to your boot class.
|
||||
ActorSystem system = ActorSystem.create("some-system");
|
||||
|
||||
final ActorRef httpTransformer = system.actorOf(
|
||||
Props.create(HttpTransformer.class));
|
||||
|
||||
final ActorRef httpProducer = system.actorOf(
|
||||
Props.create(HttpProducer.class, httpTransformer));
|
||||
|
||||
final ActorRef httpConsumer = system.actorOf(
|
||||
Props.create(HttpConsumer.class, httpProducer));
|
||||
//#HttpExample
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package docs.camel.sample.route;
|
||||
|
||||
//#CustomRouteExample
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Processor;
|
||||
import org.apache.camel.builder.RouteBuilder;
|
||||
|
||||
public class CustomRouteBuilder extends RouteBuilder{
|
||||
public void configure() throws Exception {
|
||||
from("direct:welcome").process(new Processor(){
|
||||
public void process(Exchange exchange) throws Exception {
|
||||
exchange.getOut().setBody(String.format("Welcome %s",
|
||||
exchange.getIn().getBody()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
//#CustomRouteExample
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
package docs.camel.sample.route;
|
||||
|
||||
import akka.actor.*;
|
||||
import akka.camel.CamelExtension;
|
||||
|
||||
public class CustomRouteSample {
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
//#CustomRouteExample
|
||||
// the below lines can be added to a Boot class, so that you can run the
|
||||
// example from a MicroKernel
|
||||
ActorSystem system = ActorSystem.create("some-system");
|
||||
final ActorRef producer = system.actorOf(Props.create(Producer1.class));
|
||||
final ActorRef mediator = system.actorOf(Props.create(Transformer.class, producer));
|
||||
final ActorRef consumer = system.actorOf(Props.create(Consumer3.class, mediator));
|
||||
CamelExtension.get(system).context().addRoutes(new CustomRouteBuilder());
|
||||
//#CustomRouteExample
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package docs.camel.sample.route;
|
||||
//#CustomRouteExample
|
||||
import akka.camel.javaapi.UntypedProducerActor;
|
||||
|
||||
public class Producer1 extends UntypedProducerActor{
|
||||
public String getEndpointUri() {
|
||||
return "direct:welcome";
|
||||
}
|
||||
}
|
||||
//#CustomRouteExample
|
||||
|
|
@ -308,7 +308,7 @@ to do other work) and resume processing when the response is ready. This is
|
|||
currently the case for a `subset of components`_ such as the `Jetty component`_.
|
||||
All other Camel components can still be used, of course, but they will cause
|
||||
allocation of a thread for the duration of an in-out message exchange. There's
|
||||
also a :ref:`camel-async-example` that implements both, an asynchronous
|
||||
also :ref:`camel-examples` that implements both, an asynchronous
|
||||
consumer and an asynchronous producer, with the jetty component.
|
||||
|
||||
If the used Camel component is blocking it might be necessary to use a separate
|
||||
|
|
@ -463,110 +463,19 @@ __ https://svn.apache.org/repos/asf/camel/tags/camel-2.8.0/camel-core/src/main/j
|
|||
Examples
|
||||
========
|
||||
|
||||
.. _camel-async-example:
|
||||
The `Typesafe Activator <http://typesafe.com/platform/getstarted>`_
|
||||
tutorial named `Akka Camel Samples with Scala <http://typesafe.com/activator/template/akka-sample-camel-scala>`_
|
||||
contains 3 samples:
|
||||
|
||||
Asynchronous routing and transformation example
|
||||
-----------------------------------------------
|
||||
* Asynchronous routing and transformation - This example demonstrates how to implement consumer and
|
||||
producer actors that support :ref:`camel-asynchronous-routing` with their Camel endpoints.
|
||||
|
||||
* Custom Camel route - Demonstrates the combined usage of a ``Producer`` and a
|
||||
``Consumer`` actor as well as the inclusion of a custom Camel route.
|
||||
|
||||
This example demonstrates how to implement consumer and producer actors that
|
||||
support :ref:`camel-asynchronous-routing` with their Camel endpoints. The sample
|
||||
application transforms the content of the Akka homepage, http://akka.io, by
|
||||
replacing every occurrence of *Akka* with *AKKA*. To run this example, add
|
||||
a Boot class that starts the actors. After starting
|
||||
the :ref:`microkernel-scala`, direct the browser to http://localhost:8875 and the
|
||||
transformed Akka homepage should be displayed. Please note that this example
|
||||
will probably not work if you're behind an HTTP proxy.
|
||||
* Quartz Scheduler Example - Showing how simple is to implement a cron-style scheduler by
|
||||
using the Camel Quartz component
|
||||
|
||||
The following figure gives an overview how the example actors interact with
|
||||
external systems and with each other. A browser sends a GET request to
|
||||
http://localhost:8875 which is the published endpoint of the ``HttpConsumer``
|
||||
actor. The ``HttpConsumer`` actor forwards the requests to the ``HttpProducer``
|
||||
actor which retrieves the Akka homepage from http://akka.io. The retrieved HTML
|
||||
is then forwarded to the ``HttpTransformer`` actor which replaces all occurrences
|
||||
of *Akka* with *AKKA*. The transformation result is sent back the HttpConsumer
|
||||
which finally returns it to the browser.
|
||||
|
||||
.. image:: ../images/camel-async-interact.png
|
||||
|
||||
Implementing the example actor classes and wiring them together is rather easy
|
||||
as shown in the following snippet.
|
||||
|
||||
.. includecode:: code/docs/camel/HttpExample.scala#HttpExample
|
||||
|
||||
The `jetty endpoints`_ of HttpConsumer and HttpProducer support asynchronous
|
||||
in-out message exchanges and do not allocate threads for the full duration of
|
||||
the exchange. This is achieved by using `Jetty continuations`_ on the
|
||||
consumer-side and by using `Jetty's asynchronous HTTP client`_ on the producer
|
||||
side. The following high-level sequence diagram illustrates that.
|
||||
|
||||
.. _jetty endpoints: http://camel.apache.org/jetty.html
|
||||
.. _Jetty continuations: http://wiki.eclipse.org/Jetty/Feature/Continuations
|
||||
.. _Jetty's asynchronous HTTP client: http://wiki.eclipse.org/Jetty/Tutorial/HttpClient
|
||||
|
||||
.. image:: ../images/camel-async-sequence.png
|
||||
|
||||
Custom Camel route example
|
||||
--------------------------
|
||||
|
||||
This section also demonstrates the combined usage of a ``Producer`` and a
|
||||
``Consumer`` actor as well as the inclusion of a custom Camel route. The
|
||||
following figure gives an overview.
|
||||
|
||||
.. image:: ../images/camel-custom-route.png
|
||||
|
||||
* A consumer actor receives a message from an HTTP client
|
||||
|
||||
* It forwards the message to another actor that transforms the message (encloses
|
||||
the original message into hyphens)
|
||||
|
||||
* The transformer actor forwards the transformed message to a producer actor
|
||||
|
||||
* The producer actor sends the message to a custom Camel route beginning at the
|
||||
``direct:welcome`` endpoint
|
||||
|
||||
* A processor (transformer) in the custom Camel route prepends "Welcome" to the
|
||||
original message and creates a result message
|
||||
|
||||
* The producer actor sends the result back to the consumer actor which returns
|
||||
it to the HTTP client
|
||||
|
||||
|
||||
The consumer, transformer and
|
||||
producer actor implementations are as follows.
|
||||
|
||||
.. includecode:: code/docs/camel/CustomRouteExample.scala#CustomRouteExample
|
||||
|
||||
|
||||
The producer actor knows where to reply the message to because the consumer and
|
||||
transformer actors have forwarded the original sender reference as well. The
|
||||
application configuration and the route starting from direct:welcome are done in the code above.
|
||||
|
||||
To run the example, add the lines shown in the example to a Boot class and the start the :ref:`microkernel-scala` and POST a message to
|
||||
``http://localhost:8877/camel/welcome``.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
curl -H "Content-Type: text/plain" -d "Anke" http://localhost:8877/camel/welcome
|
||||
|
||||
The response should be:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Welcome - Anke -
|
||||
|
||||
Quartz Scheduler Example
|
||||
------------------------
|
||||
|
||||
Here is an example showing how simple is to implement a cron-style scheduler by
|
||||
using the Camel Quartz component in Akka.
|
||||
|
||||
The following example creates a "timer" actor which fires a message every 2
|
||||
seconds:
|
||||
|
||||
.. includecode:: code/docs/camel/QuartzExample.scala#Quartz
|
||||
|
||||
For more information about the Camel Quartz component, see here:
|
||||
http://camel.apache.org/quartz.html
|
||||
|
||||
Additional Resources
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
package docs.camel
|
||||
|
||||
object CustomRouteExample {
|
||||
{
|
||||
//#CustomRouteExample
|
||||
import akka.actor.{ Actor, ActorRef, Props, ActorSystem }
|
||||
import akka.camel.{ CamelMessage, Consumer, Producer, CamelExtension }
|
||||
import org.apache.camel.builder.RouteBuilder
|
||||
import org.apache.camel.{ Exchange, Processor }
|
||||
|
||||
class Consumer3(transformer: ActorRef) extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8877/camel/welcome"
|
||||
|
||||
def receive = {
|
||||
// Forward a string representation of the message body to transformer
|
||||
case msg: CamelMessage ⇒ transformer.forward(msg.bodyAs[String])
|
||||
}
|
||||
}
|
||||
|
||||
class Transformer(producer: ActorRef) extends Actor {
|
||||
def receive = {
|
||||
// example: transform message body "foo" to "- foo -" and forward result
|
||||
// to producer
|
||||
case msg: CamelMessage ⇒
|
||||
producer.forward(msg.mapBody((body: String) ⇒ "- %s -" format body))
|
||||
}
|
||||
}
|
||||
|
||||
class Producer1 extends Actor with Producer {
|
||||
def endpointUri = "direct:welcome"
|
||||
}
|
||||
|
||||
class CustomRouteBuilder extends RouteBuilder {
|
||||
def configure {
|
||||
from("direct:welcome").process(new Processor() {
|
||||
def process(exchange: Exchange) {
|
||||
// Create a 'welcome' message from the input message
|
||||
exchange.getOut.setBody("Welcome %s" format exchange.getIn.getBody)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// the below lines can be added to a Boot class, so that you can run the
|
||||
// example from a MicroKernel
|
||||
val system = ActorSystem("some-system")
|
||||
val producer = system.actorOf(Props[Producer1])
|
||||
val mediator = system.actorOf(Props(classOf[Transformer], producer))
|
||||
val consumer = system.actorOf(Props(classOf[Consumer3], mediator))
|
||||
CamelExtension(system).context.addRoutes(new CustomRouteBuilder)
|
||||
//#CustomRouteExample
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package docs.camel
|
||||
|
||||
object HttpExample {
|
||||
|
||||
{
|
||||
//#HttpExample
|
||||
import org.apache.camel.Exchange
|
||||
import akka.actor.{ Actor, ActorRef, Props, ActorSystem }
|
||||
import akka.camel.{ Producer, CamelMessage, Consumer }
|
||||
import akka.actor.Status.Failure
|
||||
|
||||
class HttpConsumer(producer: ActorRef) extends Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8875/"
|
||||
|
||||
def receive = {
|
||||
case msg ⇒ producer forward msg
|
||||
}
|
||||
}
|
||||
|
||||
class HttpProducer(transformer: ActorRef) extends Actor with Producer {
|
||||
def endpointUri = "jetty://http://akka.io/?bridgeEndpoint=true"
|
||||
|
||||
override def transformOutgoingMessage(msg: Any) = msg match {
|
||||
case msg: CamelMessage ⇒ msg.copy(headers = msg.headers ++
|
||||
msg.headers(Set(Exchange.HTTP_PATH)))
|
||||
}
|
||||
|
||||
override def routeResponse(msg: Any) { transformer forward msg }
|
||||
}
|
||||
|
||||
class HttpTransformer extends Actor {
|
||||
def receive = {
|
||||
case msg: CamelMessage ⇒
|
||||
sender ! (msg.mapBody { body: Array[Byte] ⇒
|
||||
new String(body).replaceAll("Akka ", "AKKA ")
|
||||
})
|
||||
case msg: Failure ⇒ sender ! msg
|
||||
}
|
||||
}
|
||||
|
||||
// Create the actors. this can be done in a Boot class so you can
|
||||
// run the example in the MicroKernel. Just add the three lines below
|
||||
// to your boot class.
|
||||
val system = ActorSystem("some-system")
|
||||
val httpTransformer = system.actorOf(Props[HttpTransformer])
|
||||
val httpProducer = system.actorOf(Props(classOf[HttpProducer], httpTransformer))
|
||||
val httpConsumer = system.actorOf(Props(classOf[HttpConsumer], httpProducer))
|
||||
//#HttpExample
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package docs.camel
|
||||
|
||||
object QuartzExample {
|
||||
//#Quartz
|
||||
import akka.actor.{ ActorSystem, Props }
|
||||
|
||||
import akka.camel.{ Consumer }
|
||||
|
||||
class MyQuartzActor extends Consumer {
|
||||
|
||||
def endpointUri = "quartz://example?cron=0/2+*+*+*+*+?"
|
||||
|
||||
def receive = {
|
||||
|
||||
case msg ⇒ println("==============> received %s " format msg)
|
||||
|
||||
} // end receive
|
||||
|
||||
} // end MyQuartzActor
|
||||
|
||||
object MyQuartzActor {
|
||||
|
||||
def main(str: Array[String]) {
|
||||
val system = ActorSystem("my-quartz-system")
|
||||
system.actorOf(Props[MyQuartzActor])
|
||||
} // end main
|
||||
|
||||
} // end MyQuartzActor
|
||||
//#Quartz
|
||||
}
|
||||
17
akka-samples/akka-sample-camel-java/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
*#
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
*.pyc
|
||||
*.tm.epoch
|
||||
*.vim
|
||||
*-shim.sbt
|
||||
.idea/
|
||||
/project/plugins/project
|
||||
project/boot
|
||||
target/
|
||||
/logs
|
||||
.cache
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
13
akka-samples/akka-sample-camel-java/LICENSE
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Copyright 2013 Typesafe, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
4
akka-samples/akka-sample-camel-java/activator.properties
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
name=akka-sample-camel-java
|
||||
title=Akka Camel Samples with Java
|
||||
description=Akka Camel Samples with Java
|
||||
tags=akka,camel,java,sample
|
||||
14
akka-samples/akka-sample-camel-java/build.sbt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
name := "akka-sample-camel-java"
|
||||
|
||||
version := "1.0"
|
||||
|
||||
scalaVersion := "2.10.3"
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.typesafe.akka" %% "akka-camel" % "2.3-SNAPSHOT",
|
||||
"org.apache.camel" % "camel-jetty" % "2.10.3",
|
||||
"org.apache.camel" % "camel-quartz" % "2.10.3",
|
||||
"org.slf4j" % "slf4j-api" % "1.7.2",
|
||||
"ch.qos.logback" % "logback-classic" % "1.0.7"
|
||||
)
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
sbt.version=0.13.0
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
package docs.camel.sample.http;
|
||||
package sample.camel.http;
|
||||
|
||||
import akka.actor.ActorRef;
|
||||
import akka.camel.javaapi.UntypedConsumerActor;
|
||||
|
||||
//#HttpExample
|
||||
public class HttpConsumer extends UntypedConsumerActor{
|
||||
public class HttpConsumer extends UntypedConsumerActor {
|
||||
|
||||
private ActorRef producer;
|
||||
|
||||
public HttpConsumer(ActorRef producer){
|
||||
public HttpConsumer(ActorRef producer) {
|
||||
this.producer = producer;
|
||||
}
|
||||
|
||||
|
|
@ -20,4 +19,3 @@ public class HttpConsumer extends UntypedConsumerActor{
|
|||
producer.forward(message, getContext());
|
||||
}
|
||||
}
|
||||
//#HttpExample
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package docs.camel.sample.http;
|
||||
package sample.camel.http;
|
||||
|
||||
import akka.actor.ActorRef;
|
||||
import akka.camel.CamelMessage;
|
||||
|
|
@ -8,8 +8,7 @@ import org.apache.camel.Exchange;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
//#HttpExample
|
||||
public class HttpProducer extends UntypedProducerActor{
|
||||
public class HttpProducer extends UntypedProducerActor {
|
||||
private ActorRef transformer;
|
||||
|
||||
public HttpProducer(ActorRef transformer) {
|
||||
|
|
@ -17,9 +16,13 @@ public class HttpProducer extends UntypedProducerActor{
|
|||
}
|
||||
|
||||
public String getEndpointUri() {
|
||||
// bridgeEndpoint=true makes the producer ignore the Exchange.HTTP_URI header,
|
||||
// and use the endpoint's URI for request
|
||||
return "jetty://http://akka.io/?bridgeEndpoint=true";
|
||||
}
|
||||
|
||||
// before producing messages to endpoints, producer actors can pre-process
|
||||
// them by overriding the onTransformOutgoingMessage method
|
||||
@Override
|
||||
public Object onTransformOutgoingMessage(Object message) {
|
||||
if (message instanceof CamelMessage) {
|
||||
|
|
@ -27,12 +30,14 @@ public class HttpProducer extends UntypedProducerActor{
|
|||
Set<String> httpPath = new HashSet<String>();
|
||||
httpPath.add(Exchange.HTTP_PATH);
|
||||
return camelMessage.withHeaders(camelMessage.getHeaders(httpPath));
|
||||
} else return super.onTransformOutgoingMessage(message);
|
||||
} else
|
||||
return super.onTransformOutgoingMessage(message);
|
||||
}
|
||||
|
||||
// instead of replying to the initial sender, producer actors can implement custom
|
||||
// response processing by overriding the onRouteResponse method
|
||||
@Override
|
||||
public void onRouteResponse(Object message) {
|
||||
transformer.forward(message, getContext());
|
||||
}
|
||||
}
|
||||
//#HttpExample
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package sample.camel.http;
|
||||
|
||||
import akka.actor.*;
|
||||
|
||||
public class HttpSample {
|
||||
public static void main(String[] args) {
|
||||
ActorSystem system = ActorSystem.create("some-system");
|
||||
|
||||
final ActorRef httpTransformer = system.actorOf(Props.create(HttpTransformer.class));
|
||||
|
||||
final ActorRef httpProducer = system.actorOf(Props.create(HttpProducer.class, httpTransformer));
|
||||
|
||||
final ActorRef httpConsumer = system.actorOf(Props.create(HttpConsumer.class, httpProducer));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,18 @@
|
|||
package docs.camel.sample.http;
|
||||
package sample.camel.http;
|
||||
|
||||
import akka.actor.Status;
|
||||
import akka.actor.UntypedActor;
|
||||
import akka.camel.CamelMessage;
|
||||
import akka.dispatch.Mapper;
|
||||
import akka.japi.Function;
|
||||
|
||||
//#HttpExample
|
||||
public class HttpTransformer extends UntypedActor{
|
||||
public class HttpTransformer extends UntypedActor {
|
||||
public void onReceive(Object message) {
|
||||
if (message instanceof CamelMessage) {
|
||||
CamelMessage camelMessage = (CamelMessage) message;
|
||||
CamelMessage replacedMessage =
|
||||
camelMessage.mapBody(new Mapper<Object, String>(){
|
||||
CamelMessage replacedMessage = camelMessage.mapBody(new Mapper<Object, String>() {
|
||||
@Override
|
||||
public String apply(Object body) {
|
||||
String text = new String((byte[])body);
|
||||
String text = new String((byte[]) body);
|
||||
return text.replaceAll("Akka ", "AKKA ");
|
||||
}
|
||||
});
|
||||
|
|
@ -26,4 +23,3 @@ public class HttpTransformer extends UntypedActor{
|
|||
unhandled(message);
|
||||
}
|
||||
}
|
||||
//#HttpExample
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package docs.camel.sample.quartz;
|
||||
//#QuartzExample
|
||||
package sample.camel.quartz;
|
||||
|
||||
import akka.camel.CamelMessage;
|
||||
import akka.camel.javaapi.UntypedConsumerActor;
|
||||
|
||||
public class MyQuartzActor extends UntypedConsumerActor{
|
||||
public class MyQuartzActor extends UntypedConsumerActor {
|
||||
public String getEndpointUri() {
|
||||
return "quartz://example?cron=0/2+*+*+*+*+?";
|
||||
}
|
||||
|
|
@ -11,10 +11,8 @@ public class MyQuartzActor extends UntypedConsumerActor{
|
|||
public void onReceive(Object message) {
|
||||
if (message instanceof CamelMessage) {
|
||||
CamelMessage camelMessage = (CamelMessage) message;
|
||||
String body = camelMessage.getBodyAs(String.class, getCamelContext());
|
||||
System.out.println(String.format("==============> received %s ", body));
|
||||
System.out.println(String.format("==============> received %s ", camelMessage));
|
||||
} else
|
||||
unhandled(message);
|
||||
}
|
||||
}
|
||||
//#QuartzExample
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
package docs.camel.sample.quartz;
|
||||
//#QuartzExample
|
||||
package sample.camel.quartz;
|
||||
|
||||
import akka.actor.ActorSystem;
|
||||
import akka.actor.Props;
|
||||
|
||||
|
|
@ -9,4 +9,3 @@ public class QuartzSample {
|
|||
system.actorOf(Props.create(MyQuartzActor.class));
|
||||
}
|
||||
}
|
||||
//#QuartzExample
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package sample.camel.route;
|
||||
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Processor;
|
||||
import org.apache.camel.builder.RouteBuilder;
|
||||
|
||||
public class CustomRouteBuilder extends RouteBuilder {
|
||||
public void configure() throws Exception {
|
||||
from("direct:welcome").process(new Processor() {
|
||||
public void process(Exchange exchange) throws Exception {
|
||||
exchange.getOut().setBody(String.format("Welcome %s", exchange.getIn().getBody()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package sample.camel.route;
|
||||
|
||||
import akka.actor.*;
|
||||
import akka.camel.CamelExtension;
|
||||
|
||||
public class CustomRouteSample {
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
ActorSystem system = ActorSystem.create("some-system");
|
||||
final ActorRef producer = system.actorOf(Props.create(RouteProducer.class));
|
||||
final ActorRef mediator = system.actorOf(Props.create(RouteTransformer.class, producer));
|
||||
final ActorRef consumer = system.actorOf(Props.create(RouteConsumer.class, mediator));
|
||||
CamelExtension.get(system).context().addRoutes(new CustomRouteBuilder());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
package docs.camel.sample.route;
|
||||
package sample.camel.route;
|
||||
|
||||
//#CustomRouteExample
|
||||
import akka.actor.ActorRef;
|
||||
import akka.camel.CamelMessage;
|
||||
import akka.camel.javaapi.UntypedConsumerActor;
|
||||
|
||||
public class Consumer3 extends UntypedConsumerActor{
|
||||
public class RouteConsumer extends UntypedConsumerActor {
|
||||
private ActorRef transformer;
|
||||
|
||||
public Consumer3(ActorRef transformer){
|
||||
public RouteConsumer(ActorRef transformer) {
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
|
|
@ -26,4 +25,3 @@ public class Consumer3 extends UntypedConsumerActor{
|
|||
unhandled(message);
|
||||
}
|
||||
}
|
||||
//#CustomRouteExample
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package sample.camel.route;
|
||||
|
||||
import akka.camel.javaapi.UntypedProducerActor;
|
||||
|
||||
public class RouteProducer extends UntypedProducerActor {
|
||||
public String getEndpointUri() {
|
||||
return "direct:welcome";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,14 @@
|
|||
package docs.camel.sample.route;
|
||||
//#CustomRouteExample
|
||||
package sample.camel.route;
|
||||
|
||||
import akka.actor.ActorRef;
|
||||
import akka.actor.UntypedActor;
|
||||
import akka.camel.CamelMessage;
|
||||
import akka.dispatch.Mapper;
|
||||
import akka.japi.Function;
|
||||
|
||||
public class Transformer extends UntypedActor {
|
||||
public class RouteTransformer extends UntypedActor {
|
||||
private ActorRef producer;
|
||||
|
||||
public Transformer(ActorRef producer) {
|
||||
public RouteTransformer(ActorRef producer) {
|
||||
this.producer = producer;
|
||||
}
|
||||
|
||||
|
|
@ -18,16 +17,14 @@ public class Transformer extends UntypedActor {
|
|||
// example: transform message body "foo" to "- foo -" and forward result
|
||||
// to producer
|
||||
CamelMessage camelMessage = (CamelMessage) message;
|
||||
CamelMessage transformedMessage =
|
||||
camelMessage.mapBody(new Mapper<String, String>(){
|
||||
@Override
|
||||
public String apply(String body) {
|
||||
return String.format("- %s -",body);
|
||||
}
|
||||
});
|
||||
CamelMessage transformedMessage = camelMessage.mapBody(new Mapper<String, String>() {
|
||||
@Override
|
||||
public String apply(String body) {
|
||||
return String.format("- %s -", body);
|
||||
}
|
||||
});
|
||||
producer.forward(transformedMessage, getContext());
|
||||
} else
|
||||
unhandled(message);
|
||||
}
|
||||
}
|
||||
//#CustomRouteExample
|
||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
163
akka-samples/akka-sample-camel-java/tutorial/index.html
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
<!-- <html> -->
|
||||
<head>
|
||||
<title>Akka Camel Samples with Java</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
This tutorial contains 3 samples of
|
||||
<a href="http://doc.akka.io/docs/akka/2.3-SNAPSHOT/java/camel.html" target="_blank">Akka Camel</a>.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Asynchronous routing and transformation</li>
|
||||
<li>Custom Camel route</li>
|
||||
<li>Quartz scheduler</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<h2>Asynchronous routing and transformation</h2>
|
||||
|
||||
<p>
|
||||
This example demonstrates how to implement consumer and producer actors that
|
||||
support
|
||||
<a href="http://doc.akka.io/docs/akka/2.3-SNAPSHOT/java/camel.html#Asynchronous_routing" target="_blank">
|
||||
Asynchronous routing</a> with their Camel endpoints. The sample
|
||||
application transforms the content of the Akka homepage, <a href="http://akka.io" target="_blank">http://akka.io</a>,
|
||||
by replacing every occurrence of *Akka* with *AKKA*.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To run this example, go to the <a href="#run" class="shortcut">Run</a>
|
||||
tab, and start the application main class <code>sample.camel.http.HttpExample</code> if it's not already started.
|
||||
Then direct the browser to <a href="http://localhost:8875" target="_blank">http://localhost:8875</a> and the
|
||||
transformed Akka homepage should be displayed. Please note that this example will probably not work if you're
|
||||
behind an HTTP proxy.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following figure gives an overview how the example actors interact with
|
||||
external systems and with each other. A browser sends a GET request to
|
||||
http://localhost:8875 which is the published endpoint of the
|
||||
<a href="#code/src/main/java/sample/camel/http/HttpConsumer.java" class="shortcut">HttpConsumer</a>
|
||||
actor. The <code>HttpConsumer</code>actor forwards the requests to the
|
||||
<a href="#code/src/main/java/sample/camel/http/HttpProducer.java" class="shortcut">HttpProducer.java</a>
|
||||
actor which retrieves the Akka homepage from http://akka.io. The retrieved HTML
|
||||
is then forwarded to the
|
||||
<a href="#code/src/main/java/sample/camel/http/HttpTransformer.java" class="shortcut">HttpTransformer.java</a>
|
||||
actor which replaces all occurrences of *Akka* with *AKKA*. The transformation result is sent back the HttpConsumer
|
||||
which finally returns it to the browser.
|
||||
</p>
|
||||
|
||||
<img src="tutorial/camel-async-interact.png" width="400" />
|
||||
|
||||
<p>
|
||||
Implementing the example actor classes and wiring them together is rather easy
|
||||
as shown in <a href="#code/src/main/java/sample/camel/http/HttpConsumer.java" class="shortcut">HttpConsumer.java</a>,
|
||||
<a href="#code/src/main/java/sample/camel/http/HttpProducer.java" class="shortcut">HttpProducer.java</a> and
|
||||
<a href="#code/src/main/java/sample/camel/http/HttpTransformer.java" class="shortcut">HttpTransformer.java</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
The <a href="http://camel.apache.org/jetty.html" target="_blank">jetty endpoints</a> of HttpConsumer and
|
||||
HttpProducer support asynchronous in-out message exchanges and do not allocate threads for the full duration of
|
||||
the exchange. This is achieved by using <a href="http://wiki.eclipse.org/Jetty/Feature/Continuations" target="_blank">Jetty continuations</a>
|
||||
on the consumer-side and by using <a href="http://wiki.eclipse.org/Jetty/Tutorial/HttpClient" target="_blank">Jetty's asynchronous HTTP client</a>
|
||||
on the producer side. The following high-level sequence diagram illustrates that.
|
||||
</p>
|
||||
|
||||
<img src="tutorial/camel-async-sequence.png" width="400" />
|
||||
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<h2>Custom Camel route example</h2>
|
||||
|
||||
<p>
|
||||
This section also demonstrates the combined usage of a
|
||||
<a href="#code/src/main/java/sample/camel/route/RouteProducer.java" class="shortcut">RouteProducer</a> and a
|
||||
<a href="#code/src/main/java/sample/camel/route/RouteConsumer.java" class="shortcut">RouteConsumer</a>
|
||||
actor as well as the inclusion of a
|
||||
<a href="#code/src/main/java/sample/camel/route/CustomRouteSample.java" class="shortcut">custom Camel route</a>.
|
||||
The following figure gives an overview.
|
||||
</p>
|
||||
|
||||
<img src="tutorial/camel-custom-route.png" width="400" />
|
||||
|
||||
<ul>
|
||||
<li>A consumer actor receives a message from an HTTP client</li>
|
||||
|
||||
<li>It forwards the message to another actor that transforms the message (encloses
|
||||
the original message into hyphens)</li>
|
||||
|
||||
<li>The transformer actor forwards the transformed message to a producer actor</li>
|
||||
|
||||
<li>The producer actor sends the message to a custom Camel route beginning at the
|
||||
<code>direct:welcome</code> endpoint</li>
|
||||
|
||||
<li>A processor (transformer) in the custom Camel route prepends "Welcome" to the
|
||||
original message and creates a result message</li>
|
||||
|
||||
<li>The producer actor sends the result back to the consumer actor which returns
|
||||
it to the HTTP client</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
The producer actor knows where to reply the message to because the consumer and
|
||||
transformer actors have forwarded the original sender reference as well. The
|
||||
application configuration and the route starting from direct:welcome are done in the code above.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To run this example, go to the <a href="#run" class="shortcut">Run</a>
|
||||
tab, and start the application main class <code>sample.camel.route.CustomRouteExample</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
POST a message to <code>http://localhost:8877/camel/welcome</code>.
|
||||
</p>
|
||||
|
||||
<pre><code>
|
||||
curl -H "Content-Type: text/plain" -d "Anke" http://localhost:8877/camel/welcome
|
||||
</code></pre>
|
||||
|
||||
<p>
|
||||
The response should be:
|
||||
</p>
|
||||
|
||||
<pre><code>
|
||||
Welcome - Anke -
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<h2>Quartz Scheduler Example</h2>
|
||||
|
||||
<p>
|
||||
Here is an example showing how simple it is to implement a cron-style scheduler by
|
||||
using the Camel Quartz component in Akka.
|
||||
</p>
|
||||
<p>
|
||||
Open <a href="#code/src/main/java/sample/camel/quartz/MyQuartzActor.java" class="shortcut">MyQuartzActor.java</a>.
|
||||
</p>
|
||||
<p>
|
||||
The example creates a "timer" actor which fires a message every 2
|
||||
seconds.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information about the Camel Quartz component, see here:
|
||||
<a href="http://camel.apache.org/quartz.html" target="_blank">http://camel.apache.org/quartz.html</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
17
akka-samples/akka-sample-camel-scala/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
*#
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
*.pyc
|
||||
*.tm.epoch
|
||||
*.vim
|
||||
*-shim.sbt
|
||||
.idea/
|
||||
/project/plugins/project
|
||||
project/boot
|
||||
target/
|
||||
/logs
|
||||
.cache
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
13
akka-samples/akka-sample-camel-scala/LICENSE
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Copyright 2013 Typesafe, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
name=akka-sample-camel-scala
|
||||
title=Akka Camel Samples with Scala
|
||||
description=Akka Camel Samples with Scala
|
||||
tags=akka,camel,scala,sample
|
||||
14
akka-samples/akka-sample-camel-scala/build.sbt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
name := "akka-sample-camel-scala"
|
||||
|
||||
version := "1.0"
|
||||
|
||||
scalaVersion := "2.10.3"
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.typesafe.akka" %% "akka-camel" % "2.3-SNAPSHOT",
|
||||
"org.apache.camel" % "camel-jetty" % "2.10.3",
|
||||
"org.apache.camel" % "camel-quartz" % "2.10.3",
|
||||
"org.slf4j" % "slf4j-api" % "1.7.2",
|
||||
"ch.qos.logback" % "logback-classic" % "1.0.7"
|
||||
)
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
sbt.version=0.13.0
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package sample.camel
|
||||
|
||||
import org.apache.camel.Exchange
|
||||
import org.apache.camel.Processor
|
||||
import org.apache.camel.builder.RouteBuilder
|
||||
import akka.actor.Actor
|
||||
import akka.actor.ActorRef
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.Props
|
||||
import akka.camel.CamelExtension
|
||||
import akka.camel.CamelMessage
|
||||
import akka.camel.Consumer
|
||||
import akka.camel.Producer
|
||||
|
||||
object CustomRouteExample {
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
val system = ActorSystem("some-system")
|
||||
val producer = system.actorOf(Props[RouteProducer])
|
||||
val mediator = system.actorOf(Props(classOf[RouteTransformer], producer))
|
||||
val consumer = system.actorOf(Props(classOf[RouteConsumer], mediator))
|
||||
CamelExtension(system).context.addRoutes(new CustomRouteBuilder)
|
||||
}
|
||||
|
||||
class RouteConsumer(transformer: ActorRef) extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8877/camel/welcome"
|
||||
|
||||
def receive = {
|
||||
// Forward a string representation of the message body to transformer
|
||||
case msg: CamelMessage => transformer.forward(msg.withBodyAs[String])
|
||||
}
|
||||
}
|
||||
|
||||
class RouteTransformer(producer: ActorRef) extends Actor {
|
||||
def receive = {
|
||||
// example: transform message body "foo" to "- foo -" and forward result
|
||||
// to producer
|
||||
case msg: CamelMessage =>
|
||||
producer.forward(msg.mapBody((body: String) => "- %s -" format body))
|
||||
}
|
||||
}
|
||||
|
||||
class RouteProducer extends Actor with Producer {
|
||||
def endpointUri = "direct:welcome"
|
||||
}
|
||||
|
||||
class CustomRouteBuilder extends RouteBuilder {
|
||||
def configure {
|
||||
from("direct:welcome").process(new Processor() {
|
||||
def process(exchange: Exchange) {
|
||||
// Create a 'welcome' message from the input message
|
||||
exchange.getOut.setBody("Welcome %s" format exchange.getIn.getBody)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package sample.camel
|
||||
|
||||
import org.apache.camel.Exchange
|
||||
import akka.actor.Actor
|
||||
import akka.actor.ActorRef
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.Props
|
||||
import akka.actor.Status.Failure
|
||||
import akka.actor.actorRef2Scala
|
||||
import akka.camel.CamelMessage
|
||||
import akka.camel.Consumer
|
||||
import akka.camel.Producer
|
||||
|
||||
object HttpExample {
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
val system = ActorSystem("some-system")
|
||||
val httpTransformer = system.actorOf(Props[HttpTransformer])
|
||||
val httpProducer = system.actorOf(Props(classOf[HttpProducer], httpTransformer))
|
||||
val httpConsumer = system.actorOf(Props(classOf[HttpConsumer], httpProducer))
|
||||
}
|
||||
|
||||
class HttpConsumer(producer: ActorRef) extends Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8875/"
|
||||
|
||||
def receive = {
|
||||
case msg => producer forward msg
|
||||
}
|
||||
}
|
||||
|
||||
class HttpProducer(transformer: ActorRef) extends Actor with Producer {
|
||||
// bridgeEndpoint=true makes the producer ignore the Exchange.HTTP_URI header,
|
||||
// and use the endpoint's URI for request
|
||||
def endpointUri = "jetty://http://akka.io/?bridgeEndpoint=true"
|
||||
|
||||
// before producing messages to endpoints, producer actors can pre-process
|
||||
// them by overriding the transformOutgoingMessage method
|
||||
override def transformOutgoingMessage(msg: Any) = msg match {
|
||||
case camelMsg: CamelMessage => camelMsg.copy(headers =
|
||||
camelMsg.headers(Set(Exchange.HTTP_PATH)))
|
||||
}
|
||||
|
||||
// instead of replying to the initial sender, producer actors can implement custom
|
||||
// response processing by overriding the routeResponse method
|
||||
override def routeResponse(msg: Any) { transformer forward msg }
|
||||
}
|
||||
|
||||
class HttpTransformer extends Actor {
|
||||
def receive = {
|
||||
case msg: CamelMessage =>
|
||||
sender ! (msg.mapBody { body: Array[Byte] =>
|
||||
new String(body).replaceAll("Akka ", "AKKA ")
|
||||
})
|
||||
case msg: Failure => sender ! msg
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package sample.camel
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.Props
|
||||
import akka.camel.Consumer
|
||||
|
||||
object QuartzExample {
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
val system = ActorSystem("my-quartz-system")
|
||||
system.actorOf(Props[MyQuartzActor])
|
||||
}
|
||||
|
||||
class MyQuartzActor extends Consumer {
|
||||
|
||||
def endpointUri = "quartz://example?cron=0/2+*+*+*+*+?"
|
||||
|
||||
def receive = {
|
||||
|
||||
case msg => println("==============> received %s " format msg)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 21 KiB |
161
akka-samples/akka-sample-camel-scala/tutorial/index.html
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<!-- <html> -->
|
||||
<head>
|
||||
<title>Akka Camel Samples with Scala</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
This tutorial contains 3 samples of
|
||||
<a href="http://doc.akka.io/docs/akka/2.3-SNAPSHOT/scala/camel.html" target="_blank">Akka Camel</a>.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Asynchronous routing and transformation</li>
|
||||
<li>Custom Camel route</li>
|
||||
<li>Quartz scheduler</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<h2>Asynchronous routing and transformation</h2>
|
||||
|
||||
<p>
|
||||
This example demonstrates how to implement consumer and producer actors that
|
||||
support
|
||||
<a href="http://doc.akka.io/docs/akka/2.3-SNAPSHOT/scala/camel.html#Asynchronous_routing" target="_blank">
|
||||
Asynchronous routing</a> with their Camel endpoints. The sample
|
||||
application transforms the content of the Akka homepage, <a href="http://akka.io" target="_blank">http://akka.io</a>,
|
||||
by replacing every occurrence of *Akka* with *AKKA*.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To run this example, go to the <a href="#run" class="shortcut">Run</a>
|
||||
tab, and start the application main class <code>sample.camel.HttpExample</code> if it's not already started.
|
||||
Then direct the browser to <a href="http://localhost:8875" target="_blank">http://localhost:8875</a> and the
|
||||
transformed Akka homepage should be displayed. Please note that this example will probably not work if you're
|
||||
behind an HTTP proxy.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following figure gives an overview how the example actors interact with
|
||||
external systems and with each other. A browser sends a GET request to
|
||||
http://localhost:8875 which is the published endpoint of the
|
||||
<a href="#code/src/main/scala/sample/camel/HttpExample.scala" class="shortcut">HttpConsumer</a>
|
||||
actor. The <code>HttpConsumer</code> actor forwards the requests to the
|
||||
<a href="#code/src/main/scala/sample/camel/HttpExample.scala" class="shortcut">HttpProducer</a>
|
||||
actor which retrieves the Akka homepage from http://akka.io. The retrieved HTML
|
||||
is then forwarded to the
|
||||
<a href="#code/src/main/scala/sample/camel/HttpExample.scala" class="shortcut">HttpTransformer</a>
|
||||
actor which replaces all occurrences of *Akka* with *AKKA*. The transformation result is sent back the HttpConsumer
|
||||
which finally returns it to the browser.
|
||||
</p>
|
||||
|
||||
<img src="tutorial/camel-async-interact.png" width="400" />
|
||||
|
||||
<p>
|
||||
Implementing the example actor classes and wiring them together is rather easy
|
||||
as shown in <a href="#code/src/main/scala/sample/camel/HttpExample.scala" class="shortcut">HttpExample.scala</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
The <a href="http://camel.apache.org/jetty.html" target="_blank">jetty endpoints</a> of HttpConsumer and
|
||||
HttpProducer support asynchronous in-out message exchanges and do not allocate threads for the full duration of
|
||||
the exchange. This is achieved by using <a href="http://wiki.eclipse.org/Jetty/Feature/Continuations" target="_blank">Jetty continuations</a>
|
||||
on the consumer-side and by using <a href="http://wiki.eclipse.org/Jetty/Tutorial/HttpClient" target="_blank">Jetty's asynchronous HTTP client</a>
|
||||
on the producer side. The following high-level sequence diagram illustrates that.
|
||||
</p>
|
||||
|
||||
<img src="tutorial/camel-async-sequence.png" width="400" />
|
||||
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<h2>Custom Camel route example</h2>
|
||||
|
||||
<p>
|
||||
This section also demonstrates the combined usage of a
|
||||
<a href="#code/src/main/scala/sample/camel/CustomRouteExample.scala" class="shortcut">RouteProducer</a>
|
||||
and a <a href="#code/src/main/scala/sample/camel/CustomRouteExample.scala" class="shortcut">RouteConsumer</a>
|
||||
actor as well as the inclusion of a
|
||||
<a href="#code/src/main/scala/sample/camel/CustomRouteExample.scala" class="shortcut">custom Camel route</a>.
|
||||
The following figure gives an overview.
|
||||
</p>
|
||||
|
||||
<img src="tutorial/camel-custom-route.png" width="400" />
|
||||
|
||||
<ul>
|
||||
<li>A consumer actor receives a message from an HTTP client</li>
|
||||
|
||||
<li>It forwards the message to another actor that transforms the message (encloses
|
||||
the original message into hyphens)</li>
|
||||
|
||||
<li>The transformer actor forwards the transformed message to a producer actor</li>
|
||||
|
||||
<li>The producer actor sends the message to a custom Camel route beginning at the
|
||||
<code>direct:welcome</code> endpoint</li>
|
||||
|
||||
<li>A processor (transformer) in the custom Camel route prepends "Welcome" to the
|
||||
original message and creates a result message</li>
|
||||
|
||||
<li>The producer actor sends the result back to the consumer actor which returns
|
||||
it to the HTTP client</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
The producer actor knows where to reply the message to because the consumer and
|
||||
transformer actors have forwarded the original sender reference as well. The
|
||||
application configuration and the route starting from direct:welcome are done in the code above.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To run this example, go to the <a href="#run" class="shortcut">Run</a>
|
||||
tab, and start the application main class <code>sample.camel.CustomRouteExample</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
POST a message to <code>http://localhost:8877/camel/welcome</code>.
|
||||
</p>
|
||||
|
||||
<pre><code>
|
||||
curl -H "Content-Type: text/plain" -d "Anke" http://localhost:8877/camel/welcome
|
||||
</code></pre>
|
||||
|
||||
<p>
|
||||
The response should be:
|
||||
</p>
|
||||
|
||||
<pre><code>
|
||||
Welcome - Anke -
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<h2>Quartz Scheduler Example</h2>
|
||||
|
||||
<p>
|
||||
Here is an example showing how simple it is to implement a cron-style scheduler by
|
||||
using the Camel Quartz component in Akka.
|
||||
</p>
|
||||
<p>
|
||||
Open <a href="#code/src/main/scala/sample/camel/QuartzExample.scala" class="shortcut">QuartzExample.scala</a>.
|
||||
</p>
|
||||
<p>
|
||||
The example creates a "timer" actor which fires a message every 2
|
||||
seconds.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information about the Camel Quartz component, see here:
|
||||
<a href="http://camel.apache.org/quartz.html" target="_blank">http://camel.apache.org/quartz.html</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
Camel Sample
|
||||
============
|
||||
|
||||
This sample is meant to be used by studying the code; it does not perform any
|
||||
astounding functions when running it. If you want to run it, check out the akka
|
||||
sources on your local hard drive, follow the [instructions for setting up Akka
|
||||
with SBT](http://doc.akka.io/docs/akka/current/intro/getting-started.html).
|
||||
When you start SBT within the checked-out akka source directory, you can run
|
||||
this sample by typing
|
||||
|
||||
akka-sample-camel/run
|
||||
|
||||
and then choose which of the demonstrations you would like to run.
|
||||
|
||||
You can read more in the [Akka docs](http://akka.io/docs).
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
import akka.actor.Status.Failure
|
||||
import akka.actor.{ Actor, ActorRef, Props, ActorSystem }
|
||||
import akka.camel.{ Producer, CamelMessage, Consumer }
|
||||
import org.apache.camel.{ Exchange }
|
||||
|
||||
/**
|
||||
* Asynchronous routing and transformation example
|
||||
*/
|
||||
object AsyncRouteAndTransform extends App {
|
||||
val system = ActorSystem("rewriteAkkaToAKKA")
|
||||
val httpTransformer = system.actorOf(Props[HttpTransformer], "transformer")
|
||||
val httpProducer = system.actorOf(Props(classOf[HttpProducer], httpTransformer), "producer")
|
||||
val httpConsumer = system.actorOf(Props(classOf[HttpConsumer], httpProducer), "consumer")
|
||||
}
|
||||
|
||||
class HttpConsumer(producer: ActorRef) extends Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8875/"
|
||||
def receive = {
|
||||
case msg ⇒ producer forward msg
|
||||
}
|
||||
}
|
||||
|
||||
class HttpProducer(transformer: ActorRef) extends Actor with Producer {
|
||||
def endpointUri = "jetty://http://akka.io/?bridgeEndpoint=true"
|
||||
|
||||
override def transformOutgoingMessage(msg: Any) = msg match {
|
||||
case msg: CamelMessage ⇒ msg.copy(headers = msg.headers(Set(Exchange.HTTP_PATH)))
|
||||
}
|
||||
|
||||
override def routeResponse(msg: Any) {
|
||||
transformer forward msg
|
||||
}
|
||||
}
|
||||
|
||||
class HttpTransformer extends Actor {
|
||||
def receive = {
|
||||
case msg: CamelMessage ⇒
|
||||
val transformedMsg = msg.mapBody {
|
||||
(body: Array[Byte]) ⇒
|
||||
new String(body).replaceAll("Akka", "<b>AKKA</b>")
|
||||
// just to make the result look a bit better.
|
||||
.replaceAll("href=\"/resources", "href=\"http://akka.io/resources")
|
||||
.replaceAll("src=\"/resources", "src=\"http://akka.io/resources")
|
||||
}
|
||||
sender ! transformedMsg
|
||||
case msg: Failure ⇒ sender ! msg
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import akka.actor.{ Props, ActorSystem }
|
||||
import akka.camel.{ CamelMessage, Consumer }
|
||||
import java.io.File
|
||||
import org.apache.camel.Exchange
|
||||
|
||||
object SimpleFileConsumer extends App {
|
||||
val subDir = "consume-files"
|
||||
val tmpDir = System.getProperty("java.io.tmpdir")
|
||||
val consumeDir = new File(tmpDir, subDir)
|
||||
consumeDir.mkdirs()
|
||||
val tmpDirUri = "file://%s/%s" format (tmpDir, subDir)
|
||||
|
||||
val system = ActorSystem("consume-files")
|
||||
val fileConsumer = system.actorOf(Props(classOf[FileConsumer], tmpDirUri), "fileConsumer")
|
||||
println(String.format("Put a text file in '%s', the consumer will pick it up!", consumeDir))
|
||||
}
|
||||
|
||||
class FileConsumer(uri: String) extends Consumer {
|
||||
def endpointUri = uri
|
||||
def receive = {
|
||||
case msg: CamelMessage ⇒
|
||||
println("Received file %s with content:\n%s".format(msg.headers(Exchange.FILE_NAME), msg.bodyAs[String]))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
name=akka-sample-main-java
|
||||
title=Akka Main in Java
|
||||
description=Actor based version of obligatory Hello World program using the generic launcher class akka.Main.
|
||||
tags=Basics,akka,java,java,starter
|
||||
tags=Basics,akka,java,starter
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
name=akka-sample-main-scala
|
||||
title=Akka Main in Scala
|
||||
description=Actor based version of obligatory Hello World program using the generic launcher class akka.Main.
|
||||
tags=Basics,akka,java,scala,starter
|
||||
tags=Basics,akka,scala,starter
|
||||
|
|
|
|||
|
|
@ -446,12 +446,19 @@ object AkkaBuild extends Build {
|
|||
id = "akka-samples",
|
||||
base = file("akka-samples"),
|
||||
settings = parentSettings,
|
||||
aggregate = Seq(camelSample, fsmSample, mainSampleJava, mainSampleScala, helloKernelSample, remoteSample, persistenceSample, clusterSample, multiNodeSample, osgiDiningHakkersSample)
|
||||
aggregate = Seq(camelSampleJava, camelSampleScala, fsmSample, mainSampleJava, mainSampleScala, helloKernelSample, remoteSample, persistenceSample, clusterSample, multiNodeSample, osgiDiningHakkersSample)
|
||||
)
|
||||
|
||||
lazy val camelSample = Project(
|
||||
id = "akka-sample-camel",
|
||||
base = file("akka-samples/akka-sample-camel"),
|
||||
lazy val camelSampleJava = Project(
|
||||
id = "akka-sample-camel-java",
|
||||
base = file("akka-samples/akka-sample-camel-java"),
|
||||
dependencies = Seq(actor, camel),
|
||||
settings = sampleSettings ++ Seq(libraryDependencies ++= Dependencies.camelSample)
|
||||
)
|
||||
|
||||
lazy val camelSampleScala = Project(
|
||||
id = "akka-sample-camel-scala",
|
||||
base = file("akka-samples/akka-sample-camel-scala"),
|
||||
dependencies = Seq(actor, camel),
|
||||
settings = sampleSettings ++ Seq(libraryDependencies ++= Dependencies.camelSample)
|
||||
)
|
||||
|
|
|
|||