Jan 14, 2010 8:16 AM
400 bad request when retrieving pubsub messages
-
Like (0)
Hi. I am trying to use the smack api and pubsub to retrieve persisted pubsub messages but I am getting a 400 bad request error instead of the list of messages. I have a node named theNode created that has a number of messages associated with it. I have verified that the node and messages exists on the openfire server using the xml console in psi. I am using the latest svn of the smack api and the latest binary release of openfire. I am using the following code.
import java.util.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.pubsub.ConfigureForm;
import org.jivesoftware.smackx.pubsub.AccessModel;
import org.jivesoftware.smackx.pubsub.FormType;
import org.jivesoftware.smackx.pubsub.LeafNode;
import org.jivesoftware.smackx.pubsub.PubSubManager;
import org.jivesoftware.smackx.pubsub.Node;
import org.jivesoftware.smackx.pubsub.listener.*;
import org.jivesoftware.smackx.pubsub.*;
import org.jivesoftware.smackx.pubsub.PayloadItem;
import org.jivesoftware.smackx.pubsub.Node;
import org.jivesoftware.smackx.packet.DiscoverItems;
import org.jivesoftware.smackx.packet.DiscoverItems.Item;
ConnectionConfiguration config = new ConnectionConfiguration("mymachine", 5222);
XMPPConnection connection = new XMPPConnection(config);
connection.connect();
connection.login("notify@mymachine", "");
PubSubManager manager = new PubSubManager(connection, "pubsub.mymachine");
LeafNode myNode = (LeafNode) manager.getNode("theNode");
Collection<? extends org.jivesoftware.smackx.pubsub.Item> items = myNode.getItems();
<iq id="B9tI0-4" to="pubsub.mymachine" type="get"><query xmlns="http://jabber.org/protocol/disco#info" node="theNode"></query></iq>
<iq id="B9tI0-5" to="pubsub.mymachine" type="get"><pubsub xmlns="http://jabber.org/protocol/pubsub"><items node='theNode'/></pubsub></iq><iq type='get'
from='notifyserver@mymachine'
to='pubsub.mymachine'
id='items1'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='theNode'/>
</iq>Can you post the full reply stanza. It will have reasons as to why it failed.
This method is used many times within the testcases for pubsub included within the Smack source code, and it runs fine there.
This is the stanza (as per the spec) for retrieving the items from a node.
<iq type='get'
from='francisco@denmark.lit/barracks'
to='pubsub.shakespeare.lit'
id='items1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='princely_musings'/>
</pubsub>
</iq>
The example you gave is for the generic discovery mechanism, which will also retrieve the list of items from the node as disco items, which is a standardized format for information defined in the Service Discovery specification. The results of this will not include pubsub item specifics, like the payload. The LeafNode.discoverItems() is what actually sends that particular stanza.
<iq type='get'
from='notifyserver@mymachine'
to='pubsub.mymachine'
id='testhere'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='theNode' subid="lXgiAsweVdJWOq1s0XqWP9QjYfrDVE32p7vHTHHH"/>
</pubsub>
</iq>
<iq type='get'
from='notifyserver@mymachine'
to='pubsub.mymachine'
id='subscriptions1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscriptions/>
</pubsub>
</iq>
That's because discoverItems doesn't require an id, but getItems does when there is more than 1 subscription. What you want to use is the LeafNode.getItems(Collection ids) method.
<iq id="65xFT" to="pubsub.mymachine" type="get"><pubsub xmlns="http://jabber.org/protocol/pubsub">
<items node='theNode'><item id='xsrrzmkDfK02sB701W9aiofpGwp4B'/></items></pubsub></iq>
<iq type="error" id="PklEW-5" from="pubsub.mymachine" to="notify@mymachine/Smack">
<pubsub xmlns="http://jabber.org/protocol/pubsub"><items node="theNode">
<item id="theNode"/></items>
</pubsub>
<error code="400" type="modify">
<bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<subid-required xmlns="http://jabber.org/protocol/pubsub#errors"/>
</error></iq>
OK, I don't know what I was smoking when I gave you that last answer ![]()
The method I referred to is for retrieving specific items by their id's, it has nothing to do with subscriptions. That functionality is missing so I have added issue
SMACK-289 to track it. I am going to try and fix a couple of these issues over the weekend.
Sorry for leading you down the wrong path.
This issue has been fixed in trunk.
No problem at all. Thanks very much for offering to help resolve this. Out of curiosity I also tried to turn off the system property xmpp.pubsub.multiple-subscriptions in the Openfire admin console to see if I could stop Openfire from requiring the subscription id. However, I could not turn this feature off. I tried setting it to both false and 0 but it still stayed active. I also restarted the server a number of times but still the feature was reported as on when I queried the features. I am not sure why it is even sending the subid back because I do not have a person subscribed to the node in multiple ways. I even verified this by deleting my entire Openfire installation and starting over from scratch.
OK, I logged that issue under
OF-338. I am assuming that you mean the subId is in the message when you say the subId is sent back, even though you do not have multiple subscriptions.
I have noticed that when a node is created, the owner is automatically subscribed. So if you create a node and then subscribe to it, I am pretty sure you will end up being subscribed twice. This is already logged as
OF-8.