Как использовать пользовательский процессор, если он определен (не ноль)? - PullRequest
0 голосов
/ 08 октября 2019

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

Я пытался использовать конструкцию choice() when() otherwise(), но, разумеется, безуспешно. Я новичок в использовании Apache Camel, поэтому я не уверен, как интерпретировать / исправить сообщение об ошибке. Если пользовательский процессор определен, он работает нормально, но если он равен нулю, я получаю сообщение об ошибке ниже.

package test;

import org.apache.camel.CamelContext;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.builder.PredicateBuilder;
import org.apache.camel.impl.DefaultCamelContext;

public class SimpleApp {
  public static final long FIVE_MINUTES = 5 * 60 * 1000;

  public SimpleApp() {
    try {
      CamelContext ctx = new DefaultCamelContext();
      ctx.addRoutes( new SimpleRouteBuilder() );
      ctx.addRoutes(new org.apache.camel.builder.RouteBuilder() {
        @Override
        public void configure() throws Exception {
          Processor proc = new SimpleProcessor();
          // proc = null;
          Predicate useProc = PredicateBuilder.isNotNull( constant( proc ) );

          from("timer://myTimer?period=3000")
          .setBody()
            .simple("Creating a new message at ${header.firedTime}")
          .log(LoggingLevel.WARN,  "Message Generated at ${header.firedTime}")
          .to("stream:out")
          .choice()
            .when(useProc)
              .log(LoggingLevel.WARN, "Using Custom Processor (is not null)")
              .process( proc )
              .to("stream:out")
              .endChoice()
            .otherwise()
              .log(LoggingLevel.WARN, "Skipping Custom Processor (is null)")
              .endChoice()
          .end()
          .log(LoggingLevel.WARN, "Ended choice construct")
          .to("stream:out");
        }
      });
      ctx.start();
      System.out.println("Started....");
      Thread.sleep( FIVE_MINUTES );
      System.out.println("Done waiting, exiting");
      ctx.stop();
    }
    catch( Exception e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    new SimpleApp();
  }

}

Процессор является фиктивным заполнителем, но в любом случае здесь код.

package test;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class SimpleProcessor implements Processor {

  public SimpleProcessor() {
    System.out.println("Running Simple Processor");
  }

  @Override
  public void process(Exchange exchange) throws Exception {
    System.out.println("Processing Exchange");
  }

}

Я ожидал, что сработает, даже если я установлю proc = null, но вместо этого получаю следующее сообщение об ошибке:

19-10-08 11:30:15.710] test.SimpleProcessor:14 [INFO  ] => Running Simple Processor
org.apache.camel.FailedToCreateRouteException: Failed to create route route2 at: >>> Choice[[When[{null is not null} -> [Log[Using Custom Processor (is not null)], process[Processor@0x0], To[stream:out]]]] Otherwise[[Log[Skipping Custom Processor (is null)]]]] <<< in route: Route(route2)[[From[timer://myTimer?period=3000]] -> [SetBod... because of ref must be specified on: process[Processor@0x0]
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1352)
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:212)
    at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:1140)
    at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:3735)
    at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3440)
    at org.apache.camel.impl.DefaultCamelContext$4.call(DefaultCamelContext.java:3248)
    at org.apache.camel.impl.DefaultCamelContext$4.call(DefaultCamelContext.java:3244)
    at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3267)
    at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:3244)
    at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:72)
    at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:3160)
    at test.SimpleApp.<init>(SimpleApp.java:47)
    at test.SimpleApp.main(SimpleApp.java:61)
Caused by: java.lang.IllegalArgumentException: ref must be specified on: process[Processor@0x0]

Ответы [ 2 ]

0 голосов
/ 11 октября 2019

Комментарий от @ hk6279 был действительным, но не тот подход, который мне был нужен, потому что, если мне нужно / нужно более одного процессора, это потребовало бы слишком много условий для определения различных методов.

Я изменилприложение и использует XML-файл и Spring для подключения всех компонентов. Он использует именованные компоненты, и приложение получает их по имени. В моем методе настройки RouteBuilder я получаю объект и создаю Предикат;

Processor reqProc = 
       this.getContext().getRegistry().lookupByNameAndType("requestProcessor", Processor.class);
Predicate useReqProc = PredicateBuilder.isNotNull( constant( reqProc ) );

По любой причине, если я получаю процессор из bean-компонента, определенного в XML, я могу использовать нужную мне конструкцию choice() when() otherwise(). Если я попробую это напрямую, как показано в вопросе, я не смогу. Как только я получил Предикат сверху, я смог сделать следующее:

from( sources.toArray(new String[0]) )
      .split().method(RequestSplitter.class, "splitMessage")
      .choice()
        .when(useReqProc)
          .log(LoggingLevel.INFO, "Found the request processor using it")
          .to("bean:" + "requestProcessor")
        .endChoice()
        .otherwise()
          .log(LoggingLevel.ERROR, "requestProcessor not found, stopping route")
          .stop()
        .endChoice()
      .end()
      .log("Sending the request the ARES URI")
      .recipientList(header(Constants.HDR_TARGET_URI));

Надеюсь, это будет полезно для кого-то еще.

0 голосов
/ 09 октября 2019

Для компонента процессор требуется экземпляр класса java, реализующий интерфейс Java Процессор при создании маршрута. Очевидно, что null не удовлетворяет требованию.

Чтобы обойти его, создайте две функции для возврата RouteBuilder, одну без процессора и одну с процессором (передача по переменной). И затем есть функция, чтобы выбрать, какой RouteBuilder для использования.

// Sample code - function with processor (pass by variable)
protected static RouteBuilder createRouteBuilder(final Processor myProcessor) throws Exception{

    return new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            from("timer://myTimer?period=3000")
                // omit steps
                .process(myProcessor)
                // omit steps
                .to("stream:out");
        }
    };
}
...