Thanks Colin, yep you are right I was missing the ShortString way to
represent arrays. All is fine now, I'm able to connect and execute
MetadataRequest/Responses. Moving to ProducerRequest/Responses now :)


On Mon, Jul 8, 2013 at 5:13 PM, Colin Blower <cblo...@barracuda.com> wrote:

> I had the exact same problem when I started writing code for the new
> protocol. This is an oddity with the way the protocol spec uses EBNF to
> specify arrays.
>
> Checkout the section on protocol primitives, especially arrays.
>
> https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-ProtocolPrimitiveTypes
>
> Essentially, each array is preceded by its length as an int32.
>
> With regards to your specific buffer:
> <Buffer 00 00 00 16 00 03 00 00 00 00 00 00 00 03 66 6f 6f 00 07 6d 79
> 54 6f 70 69 63>
>
> You seem to be missing the clientId as well as the array length. For
> comparison the buffer, with the client I wrote, for clientId
> "perl-kafka" and topics "foo" and "myTopic":
>
> 00 00 00 26 00 03 00 00 00 00 00 2a 00 0a 70 65 72 6c 2d 6b 61 66 6b 61
> 00 00 00 02 00 03 66 6f 6f 00 07 6d 79 54 6f 70 69 63
>
>
> On 07/08/2013 04:12 AM, Vinicius Carvalho wrote:
> > Ok, so I've found out the error: The documentation is outdated, the
> > MetadataRequest BNF should be:
> >
> > NumberOfTopics [TopicList]
> >
> > Had to check the scala source code for that.
> >
> > Is there a place with a most to date doc?
> >
> > Regards
> >
> >
> > On Mon, Jul 8, 2013 at 6:42 AM, Vinicius Carvalho <
> > viniciusccarva...@gmail.com> wrote:
> >
> >> Hi there. I'm building the 0.8 version of a client to nodejs. I never
> >> coded for node and most of my code is following what the prozees guys
> did
> >> (I'm talking to them on updating the lib)
> >>
> >> But, I'm facing some errors when I test a very simple metadata request.
> >> I'm getting this exception on kafka:
> >>
> >> java.nio.BufferUnderflowException
> >> at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:145)
> >>  at java.nio.ByteBuffer.get(ByteBuffer.java:694)
> >> at kafka.api.ApiUtils$.readShortString(ApiUtils.scala:38)
> >>  at
> >>
> kafka.api.TopicMetadataRequest$$anonfun$readFrom$1.apply(TopicMetadataRequest.scala:44)
> >> at
> >>
> kafka.api.TopicMetadataRequest$$anonfun$readFrom$1.apply(TopicMetadataRequest.scala:43)
> >>  at
> scala.collection.immutable.Range$ByOne$class.foreach(Range.scala:282)
> >> at scala.collection.immutable.Range$$anon$2.foreach(Range.scala:265)
> >>  at
> >> kafka.api.TopicMetadataRequest$.readFrom(TopicMetadataRequest.scala:43)
> >> at kafka.api.RequestKeys$$anonfun$4.apply(RequestKeys.scala:37)
> >>  at kafka.api.RequestKeys$$anonfun$4.apply(RequestKeys.scala:37)
> >> at kafka.network.RequestChannel$Request.<init>(RequestChannel.scala:49)
> >>  at kafka.network.Processor.read(SocketServer.scala:345)
> >> at kafka.network.Processor.run(SocketServer.scala:245)
> >>  at java.lang.Thread.run(Thread.java:722)
> >>
> >> My test sends a metadatarequest (api code 3) using a clientId "foo",
> >> correlationId 0 and topicName "myTopic"
> >>
> >> I don't know where I'm missing something. Please find the js code bellow
> >> and also a java counter version that I've created just for the sake of
> my
> >> lack of experience with node and js. I get the same error with the java
> >> version:
> >>
> >> Request.prototype.toBytes = function() {
> >>     var encoded = new BufferMaker()
> >>         .Int16BE(this.apiKey)
> >>         .Int16BE(API_VERSION)
> >>         .Int32BE(this.correlationId)
> >>         .Int16BE(Buffer.byteLength(this.clientId,'UTF-8'))
> >>         .string(this.clientId)
> >>         .string(this.requestMessage.toBytes()).make();
> >>     var bytes = new
> >> BufferMaker().Int32BE(encoded.length).string(encoded).make();
> >>
> >> MetadataRequest.prototype.toBytes = function () {
> >>     var bytes = new
> >>
> BufferMaker().Int16BE(Buffer.byteLength(this.topicName,'UTF-8')).string(this.topicName).make();
> >>      return bytes;
> >> }
> >>
> >> var req = new Request(3,0,"foo",new MetadataRequest("myTopic"));
> >> var status = connection.write(req.toBytes());
> >>
> >> Here's the content of the buffer:
> >>
> >> <Buffer 00 00 00 16 00 03 00 00 00 00 00 00 00 03 66 6f 6f 00 07 6d 79
> 54
> >> 6f 70 69 63>
> >>
> >> And the java version (using vertx netclient):
> >>
> >> Buffer writeBuffer = new Buffer()
> >>
> >>      .appendShort((short) 3) //metadataRequest
> >>
> >>      .appendShort((short) 0) //ApiVersion
> >>
> >>      .appendInt(0) //Correlation
> >>
> >>      .appendShort((short) "foo".getBytes("UTF-8").length).appendString(
> >> "foo", "UTF-8") //ShortString clientId
> >>
> >>      .appendShort((short)
> "myTopic".getBytes("UTF-8").length).appendString
> >> ("myTopic", "UTF-8"); //ShortString topicName
> >>
> >>     Buffer message = new Buffer();
> >>
> >>     message.appendInt(writeBuffer.length()); //add total Message size to
> >> buffer
> >>
> >>     System.out.println(writeBuffer.length());
> >>
> >>     message.appendBuffer(writeBuffer);
> >>
> >>     socket.write(message);
> >>
> >>
> >> --
> >> The intuitive mind is a sacred gift and the
> >> rational mind is a faithful servant. We have
> >> created a society that honors the servant and
> >> has forgotten the gift.
> >>
> >
> >
>
>
> --
> *Colin Blower*
> /Software Engineer/
> Barracuda Networks Inc.
> +1 408-342-5576 (o)
>



-- 
The intuitive mind is a sacred gift and the
rational mind is a faithful servant. We have
created a society that honors the servant and
has forgotten the gift.

Reply via email to