简体   繁体   中英

Camel sending byte array to Kafka using ByteArraySerializer Not Working

Preface
I have a parser utility that takes in a valid JSON object from a UDP feed, encodes it, and returns a byte[] . This byte[] is to be sent to Kafka.

Issue at hand
I cannot get the byte[] to send without getting the error. It keeps seeming that I am not setting the body or something. However, for "New Body", I do get a byte[] printed

[INFO ] 2021-02-09 14:30:37 | (SpecialRouter) - New body: [B@526447c2

RouteBuilder

camelContext.addRoutes(new RouteBuilder() {
  public void configure() throws Exception {
    from("netty:udp://0.0.0.0:30244")
        .routeId("Router")
        .convertBodyTo(String.class, "UTF-8")
        .choice()
          .when(simple("${body} contains 'specialWord'"))
            .log("---------- [ Received special message ] ----------")
            .log("${body}")
            .process(new MyProcessor(new MyJsonParser().getInstance()))
            .setHeader(KafkaConstants.KEY, constant("MyProcessor"))
            .log("New body: ${body}")
            .choice()
              .when(body().isEqualTo("skip"))
                .log(">>>>> skipping")
              .when(body().isNotEqualTo("skip"))
                .log("Sending to kafka: ")
//                  .convertBodyTo(byte[].class, "UTF-8")
                .to(generateKafkaEndpoint())
                .log("DONE sending");
  }
});

Kafka Endpoint Generator

private static String generateKafkaEndpoint() {
  final StringBuilder sb = new StringBuilder();

  sb.append("kafka:{{topic_name}}");
  sb.append("?brokers={{kafka_server}}:{{kafka_port}}");
  sb.append("&clientId=TestClient");
  sb.append("&valueSerializer=org.apache.kafka.common.serialization.ByteArraySerializer");
  sb.append("&keySerializer=org.apache.kafka.common.serialization.StringSerializer");
  sb.append("&requestRequiredAcks=all");

  return sb.toString();
}

Processor

class MyProcessor implements Processor {
  private final Parser<byte[], Special> parser;

  public MyProcessor(Parser<byte[], Special> parser) {
    this.parser = parser;
  }

  @Override
  public void process(Exchange exchange) throws Exception {
    String specialJson = exchange.getIn().getBody(String.class);

    Gson gson = new Gson();
    Special wrapper = gson.fromJson(specialJson, Special.class);

    byte[] parsedSpecial = parser.parse(wrapper);

    System.out.println(">>> parsedSpecial: " + new String(parsedSpecial));
    System.out.println(">>> byte[] size: " + parsedSpecial.length);

    if (parsedSpecial.length > 0) {
      // using getMessage() instead of getOut() since getOut() is deprecated
      exchange.getMessage().setBody(parsedSpecial);
    } else {
      exchange.getMessage().setBody("skip");
    }
  }
}

Error

[WARN ] 2021-02-09 14:30:37 | (NettyConsumer) - Caused by: [org.apache.camel.CamelExchangeException - Cannot write response to null. Exchange[07C825B4A7863D1-0000000000000008]. Caused by: [io.netty.handler.codec.EncoderException - DatagramPacketStringEncoder must produce at least one message.]]
org.apache.camel.CamelExchangeException: Cannot write response to null. Exchange[07C825B4A7863D1-0000000000000008]. Caused by: [io.netty.handler.codec.EncoderException - DatagramPacketStringEncoder must produce at least one message.]
        at org.apache.camel.component.netty.handlers.ServerResponseFutureListener.operationComplete(ServerResponseFutureListener.java:53)
        at org.apache.camel.component.netty.handlers.ServerResponseFutureListener.operationComplete(ServerResponseFutureListener.java:35)
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578)
        at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:552)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491)
        at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616)
        at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:609)
        at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117)
        at io.netty.util.internal.PromiseNotificationUtil.tryFailure(PromiseNotificationUtil.java:64)
        at io.netty.channel.AbstractChannelHandlerContext.notifyOutboundHandlerException(AbstractChannelHandlerContext.java:814)
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:719)
        at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764)
        at io.netty.channel.AbstractChannelHandlerContext$WriteTask.run(AbstractChannelHandlerContext.java:1071)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at java.lang.Thread.run(Thread.java:748)
Caused by: io.netty.handler.codec.EncoderException: DatagramPacketStringEncoder must produce at least one message.
        at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:96)
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717)
        ... 8 more

The issue was with the consumer URL. Since the consumer has sync=true by default, this sets it to request-response - meaning it was trying to send a response back to a remote address I didn't have setup (that is what the null was).

So to fix this, all I had to do was add ?sync=false to the URL in the "from" to make it netty:udp://0.0.0.0:30244?sync=false .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM