2011-11-04 17 views
6

Tengo un patrón que se repite en mis rutas - un cierto procesador necesita los mismos 3 cabeceras configuradas cada vez que llamo, por lo que tengo el siguiente código en mis rutas sobre 10+ veces:Camel - extender Java DSL?

.whatever() 
.setHeader("foo1", "bar1") 
.setHeader("foo2", "bar2") 
.setHeader("foo3", "bar3") 
.processRef("processorBazThatNeedsHeaders") 
.whatever() 

Los encabezados están ocupados de manera diferente cada vez, por lo que abstraer esto en una subroute realmente no me compra nada.

Lo que me gusta ser capaz de hacer es RouteDefinition subclase tener otro método en mi DSL que permita que haga esto:

.whatever() 
.bazProcessor("bar1", "bar2", "bar3") 
.whatever() 

y en 'bazProcessor', establezca las cabeceras y llamar al procesador .

He intentado hacer esto pero parece que solo es posible con una cirugía seria que probablemente no sea a prueba de futuro, y parece que others have had similar luck.

Necesito que se establezcan como encabezados en lugar de pasarlos como parámetros directamente al procesador porque los valores también se usan después del procesador para el enrutamiento.

¿Hay alguna facilidad oculta para lograr algo como esto?

Respuesta

6

Al subclasificar el RouteDefinition su extensión solo será visible directamente después de from(...). Esto podría ser una limitación si desea utilizar la extensión DSL, por ejemplo, después del filter(...) DSL.

Un enfoque más sencillo sería para encapsular la lógica en alguna parte, y utilizarlo en una clase que implementa la interfaz org.apache.camel.Processor, y luego llamar a una sobrecarga de .process(...) o bean(...) en la ruta a usar la lógica. De hecho, estará muy cerca de una extensión DSL si usa un nombre significativo para la instancia Processor o un método, que devuelve esa instancia Processor. Aquí hay un example of the suggested approach. Al final, el código podría ser:

.whatever()
.Proceso (setTheHeadersForBaz)
.whatever()

Sólo como referencia: si realmente necesita hacer un DSL, hay un proyecto que extiende el Camel DSL based on Groovy. Supongo que una forma Scala basada en el DSL Camel Scala podría ser también una opción.

+0

Esta es una buena idea. Lo que necesito es * un poco * diferente pero creo que este es un buen comienzo. Le daré una oportunidad y responderé. –

+0

¿Puede por favor detallar su respuesta? No lo entendí :( – Edmondo1984

1

Entonces, ¿solo configura los encabezados porque quiere que el procesador tenga acceso a esos valores?

Si es así, un simple ejemplo usando un fábrica podría tener este aspecto:

whatever() 
    .process(BazProcessorFactory.instance("bar1", "bar2", "bar3")) 
    .whatever() 

Cuando el BazProcessorFactory es sólo un envoltorio alrededor de su procesador:

public class BazProcessorFactory { 
    public Processor instance(final String...vals) { 
    return new Processor() { 
     @Override 
     public void process(Exchange exchange) throws Exception { 
     //access your array of values here 
     System.out.println("Foo1 = "+vals[0]); 
     } 
    } 
    } 
} 
+0

Gracias, Damo. De hecho, necesito que se configuren como encabezados: el procesador los utiliza, pero también se usan después del procesador para manejar algunas rutas. Lo agregaré como una nota a la pregunta original. –

1

Aunque un poco irrelevante, siguiente es un ejemplo de extender Scala DSL.

Podemos crear un método implícito para el rasgo DSL a través de una clase implícita.

object DSLImplicits { 
    implicit class RichDSL(val dsl: DSL) { 
    def get = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.GET.name) 

    def post = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.POST.name) 
    } 
} 

Y úsala así.

import DSLImplicits.RichDSL 
//---------------------------- 
from("someWhere") 
    //Do some processing 
    .get.to("http://somewhere.com") 

Más detalles @ http://siliconsenthil.in/blog/2013/07/11/apache-camel-with-scala-extending-dsl/

+0

@kleopatra: Gracias .. hecho. :) – siliconsenthil