Re: ProtonJ2 client handling of null message bodies

2024-03-18 Thread Ciaran
On Mon, Mar 18, 2024 at 8:50 PM Timothy Bish  wrote:

> This should now be fixed as part of:
> https://issues.apache.org/jira/browse/PROTON-2809


Thanks Tim, I can confirm that to be the case on my side too! Appreciate
you looking into it for me, thank you.


Re: ProtonJ2 client handling of null message bodies

2024-03-18 Thread Timothy Bish

This should now be fixed as part of:
https://issues.apache.org/jira/browse/PROTON-2809

On 3/15/24 15:42, Ciaran wrote:

On Fri, Mar 15, 2024 at 6:14 PM Timothy Bish  wrote:


On 3/15/24 11:50, Ciaran wrote:

Hi,

I'm attempting to build a resilient client using the protonj2 client and

as

part of my testing I was checking that it would handle messages with null
bodies (specifically my client is only willing to work with strings or

byte

arrays so it rejects any other AMQP message body type). However, when I

put

a null body on the message (i.e. body length of 0), when I de-reference

the

delivery's message's body property (e.g. delivery.message().body) I

receive

an error from the proton engine:

Can you capture a frame trace, I need enough information to try and
create an exact reproducer which can be aided with traces of the
incoming frames to reverse engineer a test. I wouldn't expect and
exception here and its likely something that was missed in the current
test suite.

Code snippets of the sender and receiver bits can help as well.


Hi,

Please find below everything I think you've asked for, the real code is
somewhat distributed
across several different classes, but this should be pretty equivalent:

RECEIVER CODE
-
ConnectionOptions options = constructBasicConnectionOptions();
options.reconnectOptions()
.reconnectEnabled(true)
.useReconnectBackOff(true)
.reconnectDelay(5000)
.maxReconnectDelay(10240001)
.maxReconnectAttempts(12)
.warnAfterReconnectAttempts(1);

Client client= Client.create();
Connection connection = client.connect("host", 1234, options);
ReceiverOptions ro = new ReceiverOptions();
ro.autoAccept(false);
Receiver receiver = connection.openReceiver( "queue", ro )) {

Delivery delivery = receiver.tryReceive();
if( delivery != null ) {
Message message= delivery.message();
// Exception occurs here.
Object body= message.body();
}

SENDER CODE
---
final Client client = Client.create();
final ConnectionOptions options = new ConnectionOptions();
options.sslOptions().sslEnabled(true);
options.user("MY_USER");
options.password("MY_PASSWORD");

Connection connection = client.connect(serverHost, serverPort, options);
Sender sender = connection.openSender(address);
sender.send(Message.create((byte[])null));

FRAME TRACE

-> SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] SaslMechanisms{saslServerMechanisms=[MSSBCBS, PLAIN,
ANONYMOUS, EXTERNAL]}
19:36:21,633  WARN SaslMechanismSelector:130 - Caught exception while
trying to create SASL mechanism MSSBCBS: No Matching SASL Mechanism with
name: MSSBCBS
-> SASL:[269961536:0] SaslInit{mechanism=PLAIN,
initialResponse="\x00MY_USER\x00MY_PASSWORD"...(truncated), hostname='
MY_HOST.servicebus.windows.net'}
<- SASL:[269961536:0] SaslOutcome{code=OK, additionalData="Welcome!"}
-> AMQP:[269961536:0] AMQP,0,1,0,0
<- AMQP:[269961536:0] AMQP,0,1,0,0
-> AMQP:[269961536:0] Open{
containerId='ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2', hostname='
MY_HOST.servicebus.windows.net', maxFrameSize=65536, channelMax=65535,
idleTimeOut=6, outgoingLocales=null, incomingLocales=null,
offeredCapabilities=null, desiredCapabilities=[ANONYMOUS-RELAY],
properties=null}
-> AMQP:[269961536:0] Begin{remoteChannel=null, nextOutgoingId=0,
incomingWindow=1600, outgoingWindow=2147483647, handleMax=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',
handle=0, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='testq', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='testq', durable=NONE, expiryPolicy=SESSION_END,
timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null},
unsettled=null, incompleteUnsettled=null, initialDeliveryCount=null,
maxMessageSize=null, offeredCapabilities=null, desiredCapabilities=null,
properties=null}
-> AMQP:[269961536:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=0, deliveryCount=null,
linkCredit=10, available=null, drain=false, echo=null, properties=null}
<- AMQP:[269961536:0] Open{
containerId='af1bcb999146429ea0a245db6affd5e4_G60', hostname='null',
maxFrameSize=65536, channelMax=4999, idleTimeOut=12,
outgoingLocales=null, incomingLocales=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0] Begin{remoteChannel=0, nextOutgoingId=1,
incomingWindow=5000, outgoingWindow=1600, handleMax=255,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0

Re: ProtonJ2 client handling of null message bodies

2024-03-15 Thread Timothy Bish

On 3/15/24 15:42, Ciaran wrote:

On Fri, Mar 15, 2024 at 6:14 PM Timothy Bish  wrote:


On 3/15/24 11:50, Ciaran wrote:

Hi,

I'm attempting to build a resilient client using the protonj2 client and

as

part of my testing I was checking that it would handle messages with null
bodies (specifically my client is only willing to work with strings or

byte

arrays so it rejects any other AMQP message body type). However, when I

put

a null body on the message (i.e. body length of 0), when I de-reference

the

delivery's message's body property (e.g. delivery.message().body) I

receive

an error from the proton engine:

Can you capture a frame trace, I need enough information to try and
create an exact reproducer which can be aided with traces of the
incoming frames to reverse engineer a test. I wouldn't expect and
exception here and its likely something that was missed in the current
test suite.

Code snippets of the sender and receiver bits can help as well.


Hi,

Please find below everything I think you've asked for, the real code is
somewhat distributed
across several different classes, but this should be pretty equivalent:

RECEIVER CODE
-
ConnectionOptions options = constructBasicConnectionOptions();
options.reconnectOptions()
.reconnectEnabled(true)
.useReconnectBackOff(true)
.reconnectDelay(5000)
.maxReconnectDelay(10240001)
.maxReconnectAttempts(12)
.warnAfterReconnectAttempts(1);

Client client= Client.create();
Connection connection = client.connect("host", 1234, options);
ReceiverOptions ro = new ReceiverOptions();
ro.autoAccept(false);
Receiver receiver = connection.openReceiver( "queue", ro )) {

Delivery delivery = receiver.tryReceive();
if( delivery != null ) {
Message message= delivery.message();
// Exception occurs here.
Object body= message.body();
}

SENDER CODE
---
final Client client = Client.create();
final ConnectionOptions options = new ConnectionOptions();
options.sslOptions().sslEnabled(true);
options.user("MY_USER");
options.password("MY_PASSWORD");

Connection connection = client.connect(serverHost, serverPort, options);
Sender sender = connection.openSender(address);
sender.send(Message.create((byte[])null));

FRAME TRACE

-> SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] SaslMechanisms{saslServerMechanisms=[MSSBCBS, PLAIN,
ANONYMOUS, EXTERNAL]}
19:36:21,633  WARN SaslMechanismSelector:130 - Caught exception while
trying to create SASL mechanism MSSBCBS: No Matching SASL Mechanism with
name: MSSBCBS
-> SASL:[269961536:0] SaslInit{mechanism=PLAIN,
initialResponse="\x00MY_USER\x00MY_PASSWORD"...(truncated), hostname='
MY_HOST.servicebus.windows.net'}
<- SASL:[269961536:0] SaslOutcome{code=OK, additionalData="Welcome!"}
-> AMQP:[269961536:0] AMQP,0,1,0,0
<- AMQP:[269961536:0] AMQP,0,1,0,0
-> AMQP:[269961536:0] Open{
containerId='ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2', hostname='
MY_HOST.servicebus.windows.net', maxFrameSize=65536, channelMax=65535,
idleTimeOut=6, outgoingLocales=null, incomingLocales=null,
offeredCapabilities=null, desiredCapabilities=[ANONYMOUS-RELAY],
properties=null}
-> AMQP:[269961536:0] Begin{remoteChannel=null, nextOutgoingId=0,
incomingWindow=1600, outgoingWindow=2147483647, handleMax=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',
handle=0, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='testq', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='testq', durable=NONE, expiryPolicy=SESSION_END,
timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null},
unsettled=null, incompleteUnsettled=null, initialDeliveryCount=null,
maxMessageSize=null, offeredCapabilities=null, desiredCapabilities=null,
properties=null}
-> AMQP:[269961536:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=0, deliveryCount=null,
linkCredit=10, available=null, drain=false, echo=null, properties=null}
<- AMQP:[269961536:0] Open{
containerId='af1bcb999146429ea0a245db6affd5e4_G60', hostname='null',
maxFrameSize=65536, channelMax=4999, idleTimeOut=12,
outgoingLocales=null, incomingLocales=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0] Begin{remoteChannel=0, nextOutgoingId=1,
incomingWindow=5000, outgoingWindow=1600, handleMax=255,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',
handle=0, role

Re: ProtonJ2 client handling of null message bodies

2024-03-15 Thread Ciaran
On Fri, Mar 15, 2024 at 6:14 PM Timothy Bish  wrote:

> On 3/15/24 11:50, Ciaran wrote:
> > Hi,
> >
> > I'm attempting to build a resilient client using the protonj2 client and
> as
> > part of my testing I was checking that it would handle messages with null
> > bodies (specifically my client is only willing to work with strings or
> byte
> > arrays so it rejects any other AMQP message body type). However, when I
> put
> > a null body on the message (i.e. body length of 0), when I de-reference
> the
> > delivery's message's body property (e.g. delivery.message().body) I
> receive
> > an error from the proton engine:
>
> Can you capture a frame trace, I need enough information to try and
> create an exact reproducer which can be aided with traces of the
> incoming frames to reverse engineer a test. I wouldn't expect and
> exception here and its likely something that was missed in the current
> test suite.
>
> Code snippets of the sender and receiver bits can help as well.
>
>
> Hi,
Please find below everything I think you've asked for, the real code is
somewhat distributed
across several different classes, but this should be pretty equivalent:

RECEIVER CODE
-
ConnectionOptions options = constructBasicConnectionOptions();
options.reconnectOptions()
   .reconnectEnabled(true)
   .useReconnectBackOff(true)
   .reconnectDelay(5000)
   .maxReconnectDelay(10240001)
.maxReconnectAttempts(12)
.warnAfterReconnectAttempts(1);

Client client= Client.create();
Connection connection = client.connect("host", 1234, options);
ReceiverOptions ro = new ReceiverOptions();
ro.autoAccept(false);
Receiver receiver = connection.openReceiver( "queue", ro )) {

Delivery delivery = receiver.tryReceive();
if( delivery != null ) {
Message message= delivery.message();
// Exception occurs here.
Object body= message.body();
}

SENDER CODE
---
final Client client = Client.create();
final ConnectionOptions options = new ConnectionOptions();
options.sslOptions().sslEnabled(true);
options.user("MY_USER");
options.password("MY_PASSWORD");

Connection connection = client.connect(serverHost, serverPort, options);
Sender sender = connection.openSender(address);
sender.send(Message.create((byte[])null));

FRAME TRACE

-> SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] SaslMechanisms{saslServerMechanisms=[MSSBCBS, PLAIN,
ANONYMOUS, EXTERNAL]}
19:36:21,633  WARN SaslMechanismSelector:130 - Caught exception while
trying to create SASL mechanism MSSBCBS: No Matching SASL Mechanism with
name: MSSBCBS
-> SASL:[269961536:0] SaslInit{mechanism=PLAIN,
initialResponse="\x00MY_USER\x00MY_PASSWORD"...(truncated), hostname='
MY_HOST.servicebus.windows.net'}
<- SASL:[269961536:0] SaslOutcome{code=OK, additionalData="Welcome!"}
-> AMQP:[269961536:0] AMQP,0,1,0,0
<- AMQP:[269961536:0] AMQP,0,1,0,0
-> AMQP:[269961536:0] Open{
containerId='ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2', hostname='
MY_HOST.servicebus.windows.net', maxFrameSize=65536, channelMax=65535,
idleTimeOut=6, outgoingLocales=null, incomingLocales=null,
offeredCapabilities=null, desiredCapabilities=[ANONYMOUS-RELAY],
properties=null}
-> AMQP:[269961536:0] Begin{remoteChannel=null, nextOutgoingId=0,
incomingWindow=1600, outgoingWindow=2147483647, handleMax=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',
handle=0, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='testq', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='testq', durable=NONE, expiryPolicy=SESSION_END,
timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null},
unsettled=null, incompleteUnsettled=null, initialDeliveryCount=null,
maxMessageSize=null, offeredCapabilities=null, desiredCapabilities=null,
properties=null}
-> AMQP:[269961536:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=0, deliveryCount=null,
linkCredit=10, available=null, drain=false, echo=null, properties=null}
<- AMQP:[269961536:0] Open{
containerId='af1bcb999146429ea0a245db6affd5e4_G60', hostname='null',
maxFrameSize=65536, channelMax=4999, idleTimeOut=12,
outgoingLocales=null, incomingLocales=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0] Begin{remoteChannel=0, nextOutgoingId=1,
incomingWindow=5000, outgoingWindow=1600, handleMax=255,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',

Re: ProtonJ2 client handling of null message bodies

2024-03-15 Thread Timothy Bish

On 3/15/24 11:50, Ciaran wrote:

Hi,

I'm attempting to build a resilient client using the protonj2 client and as
part of my testing I was checking that it would handle messages with null
bodies (specifically my client is only willing to work with strings or byte
arrays so it rejects any other AMQP message body type). However, when I put
a null body on the message (i.e. body length of 0), when I de-reference the
delivery's message's body property (e.g. delivery.message().body) I receive
an error from the proton engine:


Can you capture a frame trace, I need enough information to try and 
create an exact reproducer which can be aided with traces of the 
incoming frames to reverse engineer a test. I wouldn't expect and 
exception here and its likely something that was missed in the current 
test suite.


Code snippets of the sender and receiver bits can help as well.




Caused by: org.apache.qpid.protonj2.client.exceptions.ClientException:
Index 1 out of bounds for length 1

at
org.apache.qpid.protonj2.client.impl.ClientExceptionSupport.createNonFatalOrPassthrough(
ClientExceptionSupport.java:103)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:170)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:152)

at org.apache.qpid.protonj2.client.impl.ClientDelivery.message(
ClientDelivery.java:79)

at
com.thisisnumero.smartagent.gateway.inbound.sources.background.amqp.AMQPMessageConsumerImpl.internalConsumeMessages(
AMQPMessageConsumerImpl.java:53)

... 4 more

Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds
for length 1

at
org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.findChunkWithIndex(
ProtonCompositeBufferImpl.java:1530)

at org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.copyInto(
ProtonCompositeBufferImpl.java:387)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:85)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:40)

at org.apache.qpid.protonj2.codec.decoders.ProtonDecoder.readObject(
ProtonDecoder.java:192)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:168)

... 7 more

My expectation from the comments on the 'body()' method is that I should
expect it to return null in this scenario? Should I be trapping this
exception and rejecting the messages to avoid poisoning my queue? (I was
planning on rejecting them anyway, but it seems weird to have to catch the
exception first.)

For reference, I'm putting messages onto the queue with the following
protonj2 calls:
sender.send(Message.create((byte[])null));
sender.send(Message.create((*String*)null));

Thank you (and sorry for the bombardment of things)



--
Tim Bish


-
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org



ProtonJ2 client handling of null message bodies

2024-03-15 Thread Ciaran
Hi,

I'm attempting to build a resilient client using the protonj2 client and as
part of my testing I was checking that it would handle messages with null
bodies (specifically my client is only willing to work with strings or byte
arrays so it rejects any other AMQP message body type). However, when I put
a null body on the message (i.e. body length of 0), when I de-reference the
delivery's message's body property (e.g. delivery.message().body) I receive
an error from the proton engine:

Caused by: org.apache.qpid.protonj2.client.exceptions.ClientException:
Index 1 out of bounds for length 1

at
org.apache.qpid.protonj2.client.impl.ClientExceptionSupport.createNonFatalOrPassthrough(
ClientExceptionSupport.java:103)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:170)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:152)

at org.apache.qpid.protonj2.client.impl.ClientDelivery.message(
ClientDelivery.java:79)

at
com.thisisnumero.smartagent.gateway.inbound.sources.background.amqp.AMQPMessageConsumerImpl.internalConsumeMessages(
AMQPMessageConsumerImpl.java:53)

... 4 more

Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds
for length 1

at
org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.findChunkWithIndex(
ProtonCompositeBufferImpl.java:1530)

at org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.copyInto(
ProtonCompositeBufferImpl.java:387)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:85)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:40)

at org.apache.qpid.protonj2.codec.decoders.ProtonDecoder.readObject(
ProtonDecoder.java:192)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:168)

... 7 more

My expectation from the comments on the 'body()' method is that I should
expect it to return null in this scenario? Should I be trapping this
exception and rejecting the messages to avoid poisoning my queue? (I was
planning on rejecting them anyway, but it seems weird to have to catch the
exception first.)

For reference, I'm putting messages onto the queue with the following
protonj2 calls:
sender.send(Message.create((byte[])null));
sender.send(Message.create((*String*)null));

Thank you (and sorry for the bombardment of things)