Верблюд - расширить Java DSL? - PullRequest
9 голосов
/ 04 ноября 2011

У меня есть повторяющийся шаблон в моих маршрутах - определенному процессору требуются одни и те же 3 заголовка каждый раз, когда я его вызываю, поэтому в моих маршрутах примерно 10+ раз встречается следующий код:

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

Заголовки каждый раз заполняются по-разному, так что абстрагирование этого в подчиненный маршрут на самом деле ничего не покупает.

Мне нравится иметь подкласс RouteDefinition, чтобы в моем DSL был другой метод, который позволил бы мне сделать это:

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

и в 'bazProcessor' установите заголовки и вызовите процессор.

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

Мне нужно, чтобы они были установлены в качестве заголовков, а не передавались в качестве параметров непосредственно процессору, поскольку эти значения также используются после процессора для маршрутизации.

Есть ли какая-то скрытая возможность для достижения чего-то подобного?

Ответы [ 3 ]

6 голосов
/ 04 ноября 2011

Подклассами RouteDefinition ваше расширение будет видно сразу после from(...). Это может быть ограничением, если вы хотите использовать расширение DSL, например, после filter(...) DSL.

Более простой подход заключается в инкапсуляции логики и ее использовании в классе, реализующем интерфейс org.apache.camel.Processor, а затем вызове перегрузки .process(...) или bean(...) на маршруте для использования логики. На самом деле вы будете очень закрыты для расширения DSL, если вы будете использовать осмысленное имя для экземпляра Processor или метода, который возвращает этот экземпляр Processor. Вот пример предлагаемого подхода . В конце ваш код может выглядеть так:

.whither ()
.process ( setTheHeadersForBaz )
.wh независимо ()

Просто для справки: если вам действительно нужно сделать DSL, есть проект, расширяющий Camel DSL на основе Groovy . Я думаю, что вариант Scala, основанный на Camel Scala DSL, также может быть вариантом.

1 голос
/ 21 июля 2013

Хотя это немного не имеет значения, ниже приведен пример расширения Scala DSL.

Мы можем создать неявные методы для черты DSL через неявный класс.

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)
  }
}

И используйте это так.

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

Подробнее @ http://siliconsenthil.in/blog/2013/07/11/apache-camel-with-scala-extending-dsl/

1 голос
/ 22 ноября 2011

То есть вы устанавливаете заголовки только потому, что хотите, чтобы процессор имел доступ к этим значениям?

Если это так, то простой пример использования фабрики может выглядеть так:

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

Где BazProcessorFactory - это просто оболочка вокруг вашего процессора:

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]);
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...