powered by Jive Software

PEPManager isSupported timeout

Smack version 4.3.2 on Android Pie
MongooseIM 3.3.0 server

Code:

PEPManager pepman = PEPManager.getInstanceFor(connection);
boolean supported = pepman.isSupported();

and Smack sent the following:

<iq to='user@example.com' id='hzWso-48' type='get'><query xmlns='http://jabber.org/protocol/disco#info'></query></iq>

Shouldn’t it be the following instead?

<iq to='pubsub.example.com' id='hzWso-48' type='get'><query xmlns='http://jabber.org/protocol/disco#info'></query></iq>

Anyway, it gave up eventually.

org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 60000ms (~60s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=hzWso-48)), : fromFilter (OrFilter: (FromMatchesFilter (full): +601156915186@hetero.io, FromMatchesFilter (full): null)).
    at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:265)
    at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:219)
    at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.discoverInfo(ServiceDiscoveryManager.java:531)
    at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.discoverInfo(ServiceDiscoveryManager.java:505)
    at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.supportsFeatures(ServiceDiscoveryManager.java:738)
    at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.supportsFeatures(ServiceDiscoveryManager.java:734)
    at org.jivesoftware.smackx.pep.PEPManager.isSupported(PEPManager.java:177)
    at io.hetero.communique.pep.SecureChat.publishSecureChatEvent(SecureChat.java:65)
    at io.hetero.communique.connection.Connection.run(Connection.java:713)
    at io.hetero.communique.connection.Connection$3.run(Connection.java:423)
No response received within reply timeout. Timeout was 60000ms (~60s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=hzWso-48)), : fromFilter (OrFilter: (FromMatchesFilter (full): +601156915186@hetero.io, FromMatchesFilter (full): null)).

Please advise. Many thanks in advance.

No, PEP means that the user account acts as PubSub service. See also XEP-0163 § 6.1.

Checked with MongooseIM. There shouldn’t be any node attribute and its presence is causing the non-response.

Please advise.

<iq to='user@example.com' id='U6PXN-52' type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info' node=''></query>
</iq>

I am confused, in your first post you wrote that the IQ request send by smack looks like this

<iq to='user@example.com' id='hzWso-48' type='get'><query xmlns='http://jabber.org/protocol/disco#info'></query></iq>

now here is one with an empty node attribute?

The first one I posted was from

PEPManager pepman = PEPManager.getInstanceFor(connection);
boolean supported = pepman.isSupported();

This one with the unexpected node was from

PEPManager pepman = PEPManager.getInstanceFor(connection);
Item item = new Item();
pepman.publish(item, "");

Sorry for the confusion.

Anyway, I won’t need to call isSupported, but I do need to call publish.

I still need your help on this.

Many thanks in advance.

This is obviously caused by you providing the empty string as node id.

<iq to='user@example.com' id='hzWso-48' type='get'><query xmlns='http://jabber.org/protocol/disco#info'></query></iq>

The stanza above is from the DiscoverInfo class. It has not reached the actual publishing logic yet.

And if I set the node parameter to null, it’d crash with an exception.

PEPManager pepman = PEPManager.getInstanceFor(connection);
Item item = new Item();
pepman.publish(item, null);
06-13 14:56:29.654 2057-2534/io.hetero.communique E/AndroidRuntime: FATAL EXCEPTION: Connection Thread
    Process: io.hetero.communique, PID: 2057
    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
        at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:746)
        at org.jivesoftware.smackx.pubsub.PubSubManager.getNode(PubSubManager.java:233)
        at org.jivesoftware.smackx.pep.PEPManager.publish(PEPManager.java:157)

Please advise.

Many thanks in advance.

You figured that an NPE will be thrown if you use null as argument, and that an more or less invalid IQ request will be send if you use the empty string as argument. So how about using a non-empty String as argument?

Yes, I have tried a non-empty string earlier. The reason I tried with a null parameter is to see if I can remove the node attribute.

Anyway, I’ll try it again:

<iq to='user@example.com' id='RvvQ3-50' type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'
node='http://jabber.org/protocol/tune'>
  </query>
</iq>
org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 60000ms (~60s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=RvvQ3-50)), : fromFilter (OrFilter: (FromMatchesFilter (full): user@example.com, FromMatchesFilter (full): null)).
    at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:265)
    at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:219)
    at org.jivesoftware.smackx.pubsub.PubSubManager.getNode(PubSubManager.java:240)
    at org.jivesoftware.smackx.pep.PEPManager.publish(PEPManager.java:157)

The following example is taken from XEP-0163: Personal Eventing Protocol

<iq from='juliet@capulet.lit/balcony'
    to='juliet@capulet.lit'
    id='disco1'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

As you can see in the example I’ve taken from XEP-0163, there is no node attribute. According to this answer in MongooseIM forum, the presence of node attribute makes it an invalid request. In other words, if the request contains a node attribute, MongooseIM will ignore the request and will not respond. Whether the node attribute is empty or otherwise is irrelevant.

Please advise.

Many thanks in advance.

This particular example is not relevant.

The request Smack sends is valid, c.f. XEP-0060 5.3.

This is the evil root cause, because it violates the spec. (there must always be a response)

The claim that “node” attribute is invalid is wrong, too. Only because there’s no example in XEP-0163 doesn’t mean it’s not allowed.

See https://xmpp.org/extensions/xep-0060.html#entity-info Example 13 and 15.

It probably doesn’t make any sense to info query for a node (in PEP), but IMO the server should just return (or the same as it would return with no node attribute):

<identity category='pubsub' type='pep'/>

Thank you very much. I will check in the MongooseIM forum.

First, It helps to re-use Smack’s existing PubSub implementation. After all PEP is just PubSub on a user account with a well defined mandatory feature set. This alone requires the PEP service to answer the request.

Granted, there are currently no PEP specifications which use mixed Collection- and Leaf-Nodes, but the day will eventually come. And then you need to determine the mode type.

Besides that, it makes the API easier to use and less error prone: Smack will return a different node APO depending on the node type, as collection nodes and lead nodes provide a different set of operations

That was no critic on Smack’s API, but just from a user’s (or use-case) point of view, I see no motivation to pass a node. (for the reasons you mentioned).
PEP API reusing existing PubSub API is obviously the best approach.

1 Like

I did not take it as criticism, just wanted to provide the rationale for the design decissions.

The best course of action for me at the moment is probably not use Smack but to roll my own code to publish PEP.

Modifying MongooseIM to handle this would be more difficult as no one here knows its workings or Erlang. :sweat:

Openfire is certainly a choice.