How to store pubsub payloads in DB - xmpp

I am using XMPP pubsub.Everything is working fine.User can create node and interested user can subscribe to that node.But I want to store the publish action into DB.Because in my application many things are handled by pubsub like chat,feeds etc so on page refresh I want to persist chat.So I m looking for any openfire plugin which saves it into DB behind the scenes. Like openfire saves chat in case of MUC (Multiple User Chat).I dont want to manually send ajax request. So is there any way to log the publish items.
Update:
There was a problem in my form configuration in which persist items was set to false by default.So I configured the node as you suggested.But again I am facing some problem on page refresh.I will explain you with an example. In my application user A logs in and create a node and on successful creation it sends request to user B, now user B subscribe to the node created by user A.Now if any user does a page refresh I send an IQ stanza of type get to get all the missed events like the one you mentioned above.But I am getting error 400 subid-required.
<body rid='430432056' xmlns='http://jabber.org/protocol/httpbind' sid='dca8aafc'><iq to='pubsub.abc' type='get' xmlns='jabber:client' id='3408:sendIQ'><pubsub xmlns='http://jabber.org/protocol/pubsub'><items node='3821poU5zq7nhn1'/></pubsub></iq></body>
In response I am getting:
<body xmlns='http://jabber.org/protocol/httpbind'><iq type="error" id="3408:sendIQ" from="pubsub.abc" to="test#abc/dca8aafc"><pubsub xmlns="http://jabber.org/protocol/pubsub"><items node="3821poU5zq7nhn1"/></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></body>
So can help me where I am getting wrong.Also I read the link http://xmpp.org/extensions/xep-0060.html#owner-configure point : 6.5.9.1 which says
If the requesting entity has multiple subscriptions to the node but does not specify a subscription ID, the service MUST return a error to the subscriber.So does it mean that I am subscribing to the same node again?
I checked if thats the case but I am subscribing only once.So just figuring out where things are getting wrong.

Per XMPP's XEP-0060, it is possible for Owner of the PubSub node to make items on the node expire in a very distant future.
When creating a node, you may want to set the following attributes to make items on the node never expire.
<field var='pubsub#persist_items' type='boolean' label='Persist items to storage'>
<value>1</value>
</field>
<field var='pubsub#max_items' type='text-single' label='Max # of items to persist'>
<value>999999</value>
</field>
<field var='pubsub#item_expire' type='text-single' label='Time after which to automatically purge items'>
<value>999999999999</value>
</field>
Source: http://xmpp.org/extensions/xep-0060.html#owner-configure
Then when you want to retrieve all the items, you can probably do this to retrieve the data:
<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>
Source: http://xmpp.org/extensions/xep-0060.html#subscriber-retrieve-requestall
Would this solve your problem?

Related

How to allow and parse FIX message with QuickFIX if Field 55 appears multiple times in FIX incoming message?

This particular broker does not provide a DataDictionary so I have to create my own based on their documentation.
This is how they send a particular message:
FIX.4.4|9=709|35=y|34=53|49=DUMMYBROKER|56=<client_ID>|52=20210211-
12:12:37.358847|55=AUD/CAD|55=AUD/CHF|55=AUD/JPY|55=AUD/NZD|55=AUD/USD|55=
CAD/CHF|55=CAD/JPY|55=CHF/JPY|55=EUR/AUD|55=EUR/CAD|55=EUR/CHF| ...
etc
How can I allow QuickFix a field to appear multiple times?
Once I recieve the message what is the best way to read it? I am using QuickFIX/n.
This would probably provide me the last symbol only:
var symbolstring = message.GetString(Tags.Symbol);
This is how the SecurityList is defined in the DataDictionary:
<message name="SecurityList" msgtype="y" msgcat="app">
<group name="NoMDEntries" required="Y">
<field name="Symbol" required="N"/>
</group>
</message>
I have tried changing "Y"/"N" in all variations, but it still cannot absorb the message properly.
This message is invalid FIX, and is simply not parseable by QuickFIX/n (or any QF engine).
A repeating group must start with a counter field which tells the receiver how many instances of that group will follow. Their message doesn't have that counter field.

How to use FIXT11 function in quickFix/n package

I have a question of using FIXT1.1 xml.
Indeed, I have successfully established the connection by using the transport dictionary (FIXT11.xml) and app dictionary (FIX50SP2.xml) ; However, I would like to do the following action manually:
Resend Request
SequenceReset
I found these two messages available in the transport dictionary:
<fix type='FIXT' major='1' minor='1' servicepack='0'>
...
<message msgcat='admin' msgtype='2' name='ResendRequest'>
<field name='BeginSeqNo' required='Y'/>
<field name='EndSeqNo' required='Y'/>
</message>
<message msgcat='admin' msgtype='4' name='SequenceReset'>
<field name='GapFillFlag' required='N'/>
<field name='NewSeqNo' required='Y'/>
</message>
but I cannot create this message class manually as I used to in FIX44. I've looked through the names spaces in QuickFix.dll but there is no such object know as QuickFix.FIXT11 in the quickfix/n package
Create message directly using QuickFix/n FIX44 object
QuickFix.FIXT11 missing in quickfix/n package
Do you have any recommendation what should I do?

How to get MAM message ID of sent messages?

I am using eJabberd server (MAM enabled) with client library Strophe.js. Client app is storing fixed amount of the messages in local storage.
All the messages, that I receive from the server include elements <archived/> and <stanza-id/>, which provide server-side generated IDs:
<message
xmlns="jabber:client" to="aaa#example.net/8667085700924567016834" from="aaa#example.net">
<result
xmlns="urn:xmpp:mam:2" id="1520510373346685">
<forwarded
xmlns="urn:xmpp:forward:0">
<message
xmlns="jabber:client" xml:lang="en" to="bbb#example.net" from="aaa#example.net/60965696931000870402419" type="chat">
<archived
xmlns="urn:xmpp:mam:tmp" by="aaa#example.net" id="1520510373346685"/>
<stanza-id
xmlns="urn:xmpp:sid:0" by="aaa#example.net" id="1520510373346685"/>
<body>asdf</body>
</message>
<delay
xmlns="urn:xmpp:delay" from="example.net" stamp="2018-03-08T11:59:33.346685Z"/>
</forwarded>
</result>
</message>
I use these IDs to get fixed amount of messages on each MAM call (using RSM paging - before/after/max attributes). For example:
params = {
"before": "1520510373346685",
"max": 10,
onMessage: <some handler>,
onComplete: <some handler>,
}
this.connection.mam.query(Strophe.getBareJidFromJid(this.myJid), params);
This gets me 10 messages before the message with stanza-id 1520510373346685.
However, the messages I send inherently do not have this ID, until I send them and retrieve from MAM.
I did not find any examples on getting the currently sent message ID from the server, and the Strophe does not provide any callbacks after the message was sent from the client and received by the server.
So, the question - is there any way to get the server-generated message ID (stanza-id/archived) for the currently sent message?
Maybe my own approach is wrong - should I generate my own IDs and add it to each message from the client?
There is currently no mechanism specified besides querying the archive. One prominent idea within the XMPP community to solve this in the future is to reflect the send carbon back to the original sender, which would include a stanza-id element with the ID assigned by the archive.

Simultanous sending and receiving

I am trying to send and receive message to and from JMS topics.
<testcase name="DeliveryToPT3PLIT">
...
<actions>
...
<send endpoint="fromEndpoint">
<message>
<resource file="com/roche/icc/citrus/messages/input/PT-3PLWoBatchSplit.xml"/>
</message>
<header>
...
</header>
</send>
<receive endpoint="toEndpoint">
<description>Receive asynchronous message from topic</description>
<message>
<resource file="com/roche/icc/citrus/messages/output/PT-3PLWoBatchSplit.xml"/>
</message>
<header>
...
</header>
</receive>
</actions>
</testcase>
It seems that these operations go one after another. The problem is that my application works really fast and when I send a message to first topic it appears on "toEndpoint" almost immediately. So the receive operation does not manage to catch appropriate message since it has been already processed.
Is there any way to make this operations simultaneously?
Regards
There is one thing to note about using JMS topics, because they work in a publish/subscribe manner, you have to subscribe first in order to receive the message.
That means you need to subscribe to the topic before a message is going to be published. Also, if you say that your application is fast, you may need to wait a few millis before sending the message. Here is a Java DSL example of what I think may work for you. (Note: I have tested this example with a JMS topic)
parallel().actions(
sequential().actions( // Thread #1
...
receive(action -> action.endpoint(toEndpoint).payload("message to be received"))),
sequential().actions( // Thread #2
sleep(500),
send(action -> action.endpoint(fromEndpoint).payload("message to be sent"))));
Notice the parallel() action container. It will execute every action inside it in a separate thread. Each sequential() represents a series of actions that allows you to group them together. Because both sequential() containers are inside the parallel(), the actions inside each of them will be executed on different threads.
So what happens here: you split your actions on two threads. On the first thread you wait for a message. On the second thread, you make it sleep for 500 millis first, after which you send the message.
I'm sorry that I don't have an XML example, but I hope this helps anyway.
Also don't forget to set the pub-sub-domain property to true on your endpoints. See the Citrus documentation on JMS topics: here.

Flow Vars getting lost after Facebook Authorize in MuleStudio

I have a simple Flow to authorize to Facebook and then to post a Message.
<flow name="drupal-esbFlow2" doc:name="drupal-esbFlow2">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" doc:name="HTTP"/>
<set-variable variableName="facebookMSG" value="#[message.inboundProperties['msg']]" doc:name="Variable"/>
<facebook:authorize config-ref="Facebook" doc:name="Authorize"/>
<set-session-variable variableName="accessTokenId" value="#[flowVars['OAuthAccessTokenId']]" doc:name="Get OAuthAccessTokenId"/>
<facebook:publish-message config-ref="Facebook" msg="#[flowVars['facebookMSG']]" profile_id="100001574667695" accessTokenId="#[sessionVars['accessTokenId']]" doc:name="Publish Message"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
The Idea is that i want to hit the endpoint localhost:8082?msg=myMessage. Then i want to safe the inboundProperties['msg'] in a Flow Variable and use this in the Facebook Connector. But it seems that the Variables gets lost in the Transport...
I have read that this is an known issue (mule facebook - flow variable), but is there no walk around or something?
Well as the answer sort of alludes to, it seems the authorize mp is intended to be called in complete isolation of any other logic and simply return the access token id via an http:response-builder. The client is then responsible for sending the access token id to another flow for any other processing:
<flow name="authorizationAndAuthenticationFlow">
<http:inbound-endpoint host="localhost" port="8080" path="oauth-authorize"/>
<facebook:authorize/>
<http:response-builder status="200">
<http:set-cookie name="accessTokenId" value="#[flowVars['OAuthAccessTokenId']]"/>
<set-payload value="You have successfully authorized the connector. You access token id is #[flowVars['OAuthAccessTokenId']]"/>
</http:response-builder>
</flow>
I can sort of see why, but makes you architect your app in a very specific way.
The other options is to use the "state" parameter. But this depends on on what types of data you're in your flow vars. Example:
<facebook:authorize state="#[flowVars.myvalue]"/>
This will then get returned in the callback as an inbound property that can be retrieved via:
#[message.inboundProperties['state']]
etc.
Alternatively you could look at persisting certain values, possibly in the mule object-store.