Search code examples
javaamqpqpid

Setting connection's `max_frame_size` in Qpid Proton AMQP 1.0 client library


I would like to simply open an AMQP 1.0 connection with a specific max_frame_size using the Apache Qpid Proton client library. This is inside a testsuite, not a real world application.

The Java library seems more advanced than the C library and its various bindings for other languages, so I started to use the Java one. Unfortunately, I can't find a way to set this parameter, though there must be a way: there is this Transport class which offers to get or set max_frame_size.

I first tried with the Messenger API, then I played with the Engine API. I couldn't figure out how to access the transport instance. In the case of the Engine API, I see there is a Connection.getTransport() and tried that, but it's NULL at the time I call this function.

Here is my last test:

private void do_test_with_frame_size(int frame_size, int payload_size) {
    Connection conn = Connection.Factory.create();

    Transport transport = conn.getTransport();
    transport.setMaxFrameSize(frame_size);

    Session session = conn.session();

    Sender sender = session.sender("sender");
    conn.open();
    session.open();
    sender.open();

    if (sender.getCredit() > 0) {
        String uri = System.getProperty("broker_uri");
        assertNotNull(uri);
        String address = String.format("%s/fragmentation-%d-%d",
          uri, frame_size, payload_size);

        Message message = Proton.message();
        message.setAddress(address);
        message.setBody(new AmqpValue(new byte[payload_size]));

        byte[] msgData = new byte[1024];
        int length;
        while(true) {
            try {
                length = message.encode(msgData, 0, msgData.length);
                break;
            } catch(BufferOverflowException e) {
                msgData = new byte[msgData.length * 2];
            }
        }
        byte[] tag = "0".getBytes();
        Delivery delivery = sender.delivery(tag);
        sender.send(msgData, 0, length);
        delivery.settle();
        sender.advance();
        sender.close();
        sender.getSession().close();
        sender.getSession().getConnection().close();
    }
}

I admit I have very limited knowledge of Java. Could you please confirm it is even possible to set this parameter and, if yes, tell me how to?


Solution

  • You need to create a Transport instance for the connection to use and then bind the transport to the connection instance. A created Connection does not have an implicit Transport bound to it which is why you get a null returned to you currently.

    private final Transport protonTransport = Proton.transport();
    private final Connection protonConnection = Proton.connection();
    
    ...
    
    this.protonTransport.setMaxFrameSize(maxFrameSize);
    this.protonTransport.setChannelMax(CHANNEL_MAX);
    
    this.protonTransport.bind(this.protonConnection);