[
https://issues.apache.org/jira/browse/QPID-7981?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16215719#comment-16215719
]
Gordon Sim commented on QPID-7981:
----------------------------------
{quote}You are viewing this as a request-response protocol... The client is
"requesting" and the broker is "responding". That is not how the protocol is
defined. {quote}
I am aware the protocol is symmetric, however the spec states: "If there is no
pre-existing terminus, and the peer does not wish to create a new one, this is
indicated by setting the
local terminus (source or target as appropriate) to *null*." That wording only
makes sense in the case that the link was initiated by the peer, i.e. where the
local process is 'responding' to a 'request' from the peer.
As the spec says: "a peer MUST take responsibility for verifying that the
remote terminus meets its requirements" and *that* makes perfect sense to me.
The distinction between empty and null does not. If I ask for a remote target
with address Q, whether the peer responds with either null or empty (or even
with a target with address P as you suggest) doesn't seem important, neither
matches my 'requirements'.
As the spec is defined, it never makes sense for the initiator of a link to set
the local terminus to null (rather than empty), so the case of simultaneous
initiation of a link by both peers needs to be detected by actually comparing
fields of the remote terminus as the peer sees it with local expectations, not
by relying on it being null. The only way it will be null is if it is indeed a
response to a request. That is the only 'very specific meaning' of null, as
opposed to empty.
However, having re-read the spec on these points I can see that my
'interpretation' was based on what I think is sensible rather than on what the
spec actually states (though as a minor gripe on formatting, the diagrams use
the character '-' to indicate both an 'empty' target (figure 2.36) and a 'null'
target (figure 2.33) which doesn't help to convey the apparently important
semantic distinction between them).
> [Java Broker] [AMQP1.0] Protocol layer assumes source and target are not null.
> ------------------------------------------------------------------------------
>
> Key: QPID-7981
> URL: https://issues.apache.org/jira/browse/QPID-7981
> Project: Qpid
> Issue Type: Bug
> Components: Java Broker
> Reporter: Keith Wall
> Fix For: qpid-java-broker-7.0.0
>
>
> Testing the Broker against Rhea's {{example/helloworld.js}} shows that the
> AMQP 1.0 protocol layer fails in at least two places.
> The first is if the {{Target}} (not mandatory) is omitted from the incoming
> attach.
> {noformat}
> 2017-10-21 18:13:20,609 DEBUG [IO-/10.211.55.13:52033] (o.a.q.s.p.frame) -
> RECV[/10.211.55.13:52033|0] :
> Attach{name=7e65e0a0-961f-e941-b42b-262380143f76,handle=0,role=receiver,source=Source{address=examples}}
> 2017-10-21 18:13:20,622 DEBUG [IO-/10.211.55.13:52033] (o.a.q.s.p.v.LinkImpl)
> - Error attaching link
> java.lang.NullPointerException: null
> at
> org.apache.qpid.server.protocol.v1_0.SendingLinkEndpoint.createConsumerTarget(SendingLinkEndpoint.java:209)
> at
> org.apache.qpid.server.protocol.v1_0.SendingLinkEndpoint.attachReceived(SendingLinkEndpoint.java:636)
> at
> org.apache.qpid.server.protocol.v1_0.SendingLinkEndpoint.establishLink(SendingLinkEndpoint.java:352)
> at
> org.apache.qpid.server.protocol.v1_0.AbstractLinkEndpoint.receiveAttach(AbstractLinkEndpoint.java:131)
> at
> org.apache.qpid.server.protocol.v1_0.LinkImpl.attach(LinkImpl.java:106)
> at
> org.apache.qpid.server.protocol.v1_0.Session_1_0.receiveAttach(Session_1_0.java:210)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.receiveAttach(AMQPConnection_1_0Impl.java:435)
> at
> org.apache.qpid.server.protocol.v1_0.type.transport.Attach.invoke(Attach.java:366)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.received(AMQPConnection_1_0Impl.java:517)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.lambda$receive$0(AMQPConnection_1_0Impl.java:469)
> at java.security.AccessController.doPrivileged(Native Method)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.receive(AMQPConnection_1_0Impl.java:463)
> at
> org.apache.qpid.server.protocol.v1_0.framing.FrameHandler.parse(FrameHandler.java:211)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.lambda$received$11(AMQPConnection_1_0Impl.java:1316)
> at java.security.AccessController.doPrivileged(Native Method)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.received(AMQPConnection_1_0Impl.java:1291)
> at
> org.apache.qpid.server.transport.MultiVersionProtocolEngine.received(MultiVersionProtocolEngine.java:134)
> at
> org.apache.qpid.server.transport.NonBlockingConnection.processAmqpData(NonBlockingConnection.java:606)
> at
> org.apache.qpid.server.transport.NonBlockingConnectionTLSDelegate.processData(NonBlockingConnectionTLSDelegate.java:136)
> at
> org.apache.qpid.server.transport.NonBlockingConnection.doRead(NonBlockingConnection.java:496)
> at
> org.apache.qpid.server.transport.NonBlockingConnection.doWork(NonBlockingConnection.java:270)
> at
> org.apache.qpid.server.transport.NetworkConnectionScheduler.processConnection(NetworkConnectionScheduler.java:134)
> at
> org.apache.qpid.server.transport.SelectorThread$ConnectionProcessor.processConnection(SelectorThread.java:563)
> at
> org.apache.qpid.server.transport.SelectorThread$SelectionTask.performSelect(SelectorThread.java:354)
> at
> org.apache.qpid.server.transport.SelectorThread$SelectionTask.run(SelectorThread.java:97)
> at
> org.apache.qpid.server.transport.SelectorThread.run(SelectorThread.java:521)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> at
> org.apache.qpid.server.bytebuffer.QpidByteBuffer.lambda$null$0(QpidByteBuffer.java:1396)
> at java.lang.Thread.run(Thread.java:748)
> {noformat}
> The second is if the {{Source}} (again not mandatory) is omitted:
> {noformat}
> 2017-10-21 18:19:52,556 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.p.v.f.FrameHandler) - RECV 89 bytes
> 2017-10-21 18:19:52,557 DEBUG [IO-/10.211.55.13:52035] (o.a.q.s.p.frame) -
> RECV[/10.211.55.13:52035|0] :
> Attach{name=c2c65769-7d3b-5440-b8fb-f00badbddd0d,handle=1,role=sender,target=Target{address=examples},initialDeliveryCount=0}
> 2017-10-21 18:19:52,562 DEBUG [IO-/10.211.55.13:52035] (o.a.q.s.p.frame) -
> SEND[/10.211.55.13:52035|0] :
> Attach{name=c2c65769-7d3b-5440-b8fb-f00badbddd0d,handle=1,role=receiver,target=Target{address=examples,durable=none,capabilities=[REJECT_UNROUTABLE,
>
> DELAYED_DELIVERY]},unsettled={},maxMessageSize=1000000000,offeredCapabilities=[REJECT_UNROUTABLE,
> DELAYED_DELIVERY],properties={}}
> 2017-10-21 18:19:52,565 DEBUG [IO-/10.211.55.13:52035] (o.a.q.s.p.frame) -
> SEND[/10.211.55.13:52035|0] :
> Flow{nextIncomingId=0,incomingWindow=8192,nextOutgoingId=0,outgoingWindow=2048,handle=1,deliveryCount=0,linkCredit=20000,echo=false}
> 2017-10-21 18:19:52,566 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.p.v.f.FrameHandler) - RECV 0 bytes
> 2017-10-21 18:19:52,566 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.t.NonBlockingConnection) - Written 430 bytes
> 2017-10-21 18:19:52,568 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.t.NonBlockingConnection) - Read 0 byte(s)
> 2017-10-21 18:19:52,570 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.t.NonBlockingConnection) - Read 82 byte(s)
> 2017-10-21 18:19:52,571 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.p.v.f.FrameHandler) - RECV 53 bytes
> 2017-10-21 18:19:52,571 DEBUG [IO-/10.211.55.13:52035] (o.a.q.s.p.frame) -
> RECV[/10.211.55.13:52035|0] :
> Transfer{handle=1,deliveryId=0,deliveryTag=\x00,messageFormat=0,settled=false}
> 2017-10-21 18:19:52,580 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.p.QpidServiceLoader) - Found 3 implementations of interface
> org.apache.qpid.server.plugin.MessageFormat
> 2017-10-21 18:19:52,604 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.m.AbstractConfiguredObject) - authorise returned DEFER
> 2017-10-21 18:19:52,604 DEBUG [IO-/10.211.55.13:52035]
> (o.a.q.s.m.AbstractConfiguredObject) - authorise returned DEFER, returing
> default: ALLOWED
> 2017-10-21 18:19:52,608 WARN [IO-/10.211.55.13:52035]
> (o.a.q.s.p.v.f.FrameHandler) - Unexpected exception handling frame
> java.lang.NullPointerException: null
> at
> org.apache.qpid.server.protocol.v1_0.StandardReceivingLinkEndpoint.receiveDelivery(StandardReceivingLinkEndpoint.java:262)
> at
> org.apache.qpid.server.protocol.v1_0.AbstractReceivingLinkEndpoint.receiveTransfer(AbstractReceivingLinkEndpoint.java:163)
> at
> org.apache.qpid.server.protocol.v1_0.Session_1_0.receiveTransfer(Session_1_0.java:572)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.receiveTransfer(AMQPConnection_1_0Impl.java:794)
> at
> org.apache.qpid.server.protocol.v1_0.type.transport.Transfer.invoke(Transfer.java:295)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.received(AMQPConnection_1_0Impl.java:517)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.lambda$receive$0(AMQPConnection_1_0Impl.java:469)
> at java.security.AccessController.doPrivileged(Native Method)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.receive(AMQPConnection_1_0Impl.java:463)
> at
> org.apache.qpid.server.protocol.v1_0.framing.FrameHandler.parse(FrameHandler.java:211)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.lambda$received$11(AMQPConnection_1_0Impl.java:1316)
> at java.security.AccessController.doPrivileged(Native Method)
> at
> org.apache.qpid.server.protocol.v1_0.AMQPConnection_1_0Impl.received(AMQPConnection_1_0Impl.java:1291)
> at
> org.apache.qpid.server.transport.MultiVersionProtocolEngine.received(MultiVersionProtocolEngine.java:134)
> at
> org.apache.qpid.server.transport.NonBlockingConnection.processAmqpData(NonBlockingConnection.java:606)
> at
> org.apache.qpid.server.transport.NonBlockingConnectionTLSDelegate.processData(NonBlockingConnectionTLSDelegate.java:136)
> at
> org.apache.qpid.server.transport.NonBlockingConnection.doRead(NonBlockingConnection.java:496)
> at
> org.apache.qpid.server.transport.NonBlockingConnection.doWork(NonBlockingConnection.java:270)
> at
> org.apache.qpid.server.transport.NetworkConnectionScheduler.processConnection(NetworkConnectionScheduler.java:134)
> at
> org.apache.qpid.server.transport.SelectorThread$ConnectionProcessor.processConnection(SelectorThread.java:563)
> at
> org.apache.qpid.server.transport.SelectorThread$SelectionTask.performSelect(SelectorThread.java:354)
> at
> org.apache.qpid.server.transport.SelectorThread$SelectionTask.run(SelectorThread.java:97)
> at
> org.apache.qpid.server.transport.SelectorThread.run(SelectorThread.java:521)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> at
> org.apache.qpid.server.bytebuffer.QpidByteBuffer.lambda$null$0(QpidByteBuffer.java:1396)
> at java.lang.Thread.run(Thread.java:748)
> {noformat}
> Default source and target to empty objects appears to resolve the problem.
> The protocol tests should be strengthen to cover these cases/
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]