replicate presence from one ejabbered server to a differrent ejabberd server - xmpp

We have a stand-alone server that we can not get under the hood of. (if we could be roo, this would be solved already, but we cant) It has the presence (ie: phone, idle, away, vacation, custom, etc) for 2 dozen users. Let's call this Server A. Let's consider this the server of record (ie: the presence it keeps for each user is correct).
Now, we have our own ejabberd (lets call it server B) running with the same 2 dozen users on it, as well as another 2 dozen users on it, who are not on server A. Everyone uses server B for daily IM with everyone.
Our goal is to replicate the the presence of the 2 dozen users on Server A on to server B.
The use case would be this, user on server A changes presence to "away", this would be pushed on to server B were it would change that person from "available" to "away". Likewise, it would push the presence of "on phone" to server B where it would say that Tim in "on phone".
How can I do this?
Can I "pull" the presence every 60 seconds for each of the users & then (only if there is a change) "push" it in to server B? Can I use something like mod_rest or mod_xmlrpc write the presence to server B?
I will post my results here for all to benefit from once we're done in a few weeks so as to benefit the community.

Related

Persistent XMPP MUC (XEP-45), like WhatsApp groupchats

From the spec —
7.14 Exiting a Room
In order to exit a multi-user chat room, an occupant sends a presence
stanza of type "unavailable" to the <room#service/nick> it is
currently using in the room.
Example 80. Occupant Exits a Room
<presence
from='hag66#shakespeare.lit/pda'
to='coven#chat.shakespeare.lit/thirdwitch'
type='unavailable'/>
This implies that as soon as the user disconnects from the XMPP server, he is removed from the group on the server side. The issue is simple — I don't want this behavior; I want a behavior that is similar to what Whatsapp does, i.e. even if the user goes offline, he is still part of the MUC room (which is configured to be persistent on the server side) and will receive messages from other occupants.
Given the spec and the documentation for XEP-0045 and XMPPFramework for iOS, I have no idea how to accomplish this or if it's possible to accomplish this in the traditional ejabberd server.
XEP-45 was designed more then 10 years ago. Back then, the designers had something like IRC channels in mind. Everything of XEP-45 is designed based on the assumption that a user enters and leaves a room when he/she starts/terminates its client.
WhatsApp Groupchats are different: A user joins a groupchat is is able to view the (complete) history of that chat. Even if the users client is offline/unavailable, he is still considered part of the groupchat.
The XMPP community currently works on a new XEP that provides such functionality. It is called XEP-0369: Mediated Information eXchange. It is the spiritual successor of XEP-0045, providing the features one would expect from modern groupchats.
You could emulate something quite like this by using server-side history of the MUC (Message Archive Management, XEP-0313), so that when a client logs in they're able to request the history of the MUC while they weren't in it.
If you also want to be able to show the offline pseudo-occupants of a room, the easiest way to do this is probably to map a pubsub node per room to store the list of these pseudo-occupants that clients could read to supplement the usual occupancy list.
There are probably other solutions here, but those that come immediately to mind for me involve changing the behaviour of the server in non-standard ways, such as allowing normal occupants to query a membership list, which normally only admins can do.
The Whatsapp model is much simpler than you imagine - they just maintain user session online even if user disconnects, and re-sends messages when he "reattach" session. XEP-0198 introduce similar concept to traditional XMPP sessions. You only need to configure longer inactivity period (typically XEP-0198 assume 300 seconds, but whatsapp-like messengers holds session 24+ hours)
Yes you can make your group persistent by setting its configurations this way:
NSString *var = [field attributeStringValueForName:#"var"];
if ([var isEqualToString:#"muc#roomconfig_persistentroom"])
{
[field removeChildAtIndex:0];
[field addChild:[NSXMLElement elementWithName:#"value" stringValue:#"1"]];
}

Data transfers (from/to server vs from/to client) in non-browser distributed applications

So we have command line scripts (written in Python) that sit on customer machines and send us data in CSV after every 24 hours. Now we are at a point that we actually want to be able to tell the clients to send us data any time. Almost all of the customers are on MS Windows machines and requirement is that we can install very little software on the customer machines (and most people cannot even log on to customer machines, only few people can).
I'm not actually sure as to how to best solve this problem. May be following are three possible ways (but looking for better)
We make a daemon in Python and install it on customer machine.
Daemon talks to our servers and we send back configuration
information. In that configuration information we send back the
"sleep duration". So daemon sends us the data and then goes to sleep
for number of seconds defined in "sleep duration" variable. Once the
limit is over, daemon pings us and again we send back the
configuration information. Rinse and repeat.
We install a script on customer machine and it runs every hour. At
our end, we've stored how often a customer should send us data (24
hours, 12 hours, and etc) and when script talks to us we determine
how much time has passed and if it is time that script should be
sending us data? If it's time, then we tell the script to send us
data.
We install a very small server-side (Django or Flask) application
and it runs on customer machines. Whenever we want data we send a
request to customer machine and our small server-side application
serves us. For that may be we will ask our customers to reserve a
port for us (not sure how many customers will actually allow this)
I'm sure there are better ways possible. Can you kindly let me which of the above methods are most suitable? Or please let me know if there exists a better way.
I really appreciate all insights, thanks for all help in advance.
Option 3 may not work. Most people have their machines behind a
fire-wall or router which does NAT. In such a scenario, a server that is listening for a request to come in would not typically be accessible from the public internet.
If they have static IP addresses and if the server is accessible from the public internet, then port scanners would detect it and potentially attempt to do undesirable things. You really do not someone hacking into your customer systems and wrecking havoc on them. Please avoid this option if possible.
However, it is safe to have a server on a customer system as long as it is the one logging into your server and sending data.
A better solution would be to have an app that is continuously
feeding data to your server as it is generated. Is is relatively
easy to do an equivalent of
tail -f csv_file | send_data_home
where send_data_home is program running on your customer's system.
This way there is minimal impact. The csv file creation is not
affected. The send_data_home logs into your server and sends
data as it is generated.

Biztalk not tracking send/receive ports

It seems that any new send or receive ports that I create do not display any tracking even if I tick all the tracking boxes. I have an existing application and the receive port and orchestration tracking work, but the send port tracking doesn't.
On the same machine I also tried creating a new application. Created a send and a receive port and no tracking at all. I did the same thing on a fresh install of biztalk on another machine and I got tracking so I'm not crazy.
I've tried ...
ticking every box in tracking for the receive, orch, send ports.
creating a new host specifically for tracking
recreating the original host with a different name
sql service is running
reboot system
reboot host instances
restart biztalk services
nothing shows in event logs
all sql jobs ok except for 'monitor biztalk' which complains about 7 orphaned dta.
can't see anything in particular that stands out from mbv except for the above mentioned oraphaned dta.
In addition to Mike's answer:
You need to ensure that at least one of your hosts is enabled for tracking. In BizTalk Administrator, under Platform Settings, Hosts, Select the host, and enable tracking (the list of hosts also shows which host(s) are current tracking enabled).
You can also verify that the tracking SQL Agent job is running by looking directly at the database
select count(*) from BizTalkMsgBoxDb.dbo.Spool (NOLOCK)
select count(*) from BizTalkDTADb.dbo.Tracking_Parts1 (NOLOCK)
Basically, spool should be a fairly low number (< 10 000), and should come back to a static level after a spike in messages, unless your suspended orchs are growing.
And new messages should be copied across from the MessageBox to DtaDb.TrackingParts every minute, so Tracking_Parts1 should grow a few records every 60-120 seconds after processing new messages, although they will be eventually purged / archived in line with your tracking archiving / purge strategy.
In a Dev environment, the more tracking the merrier, as HAT (the orchestration debugger) will give you more information the more you track. However, in a PROD environment, you would typically want to minimize tracking to improve performance and reduce disk overhead. We just track one copy, viz 'before processing' on the receive and 'after processing' on the send ports to our partners, and nothing at all on internal Ports and Orchs. This allows us to provide sufficient evidence of data received and sent.
This post might help some people: http://learningcenter2.eworldtree.net:7090/Lists/Posts/Post.aspx?ID=78
For message tracking to work, among other factors, make sure that the "Message send and receive events" checkbox in the corresponding pipeline is enabled.
Please take a look at these two articles, What is Message Tracking? and Insight into BizTalk Server message tracking. The first article has an item of interest for you and I'll quote it below and the second should just solidify what you're trying to do.
The SQL Server Agent service must be running on all MessageBox databases. The TrackedMessages_Copy_ job makes message bodies available to tracking queries and WMI. To efficiently copy the message bodies, they remain in the MessageBox database and are periodically copied to the BizTalk Tracking (BizTalkDTADb) database by the TrackedMessages_Copy_ job. Having the SQL Server Agent service running is also a prerequisite for the archiving and purging process to work correctly.
Are you using a default pipeline? Have you checked the tracking check boxes on them? There is some bug where the pipeline tracking is disabled for default pipelines.
More info here:
http://blog.ibiz-solutions.se/integration/biztalk-global-pipeline-tracking-disabled-unexpectedly/
Please ensure that required tracking is enbled in the properties of the send pipeline used by your send port. If message body tracking is disabled on the send pipeline, nothing is tracked on the send port as well.

Should MSMQ be on a sender of receiver machine?

I'm wondering if there are any guidelines for which machine MSMQ should be installed on, in a situation in which one machine (A) will be sending messages, and another machine (B) will be receiving them. Are there any factors that would indicate either that it's better to install MSMQ on A (in which case the sender writes messages locally, but the receiver reads them remotely), or to install on B (in which case it's the other way round?)
(If it makes any difference, in our case the sender is a website, and the receiver is an app server machine that sits behind the website, and to which the website sends messages. In the absence of any other advice, I'd have been inclined to install MSMQ on the app server, on the vague principle of keeping as little software as possible on the web server on security grounds, since that server is in the first line of any attack. To complicate matters, the website sits behind a load balancer - so 'machine A' is actually two identical machines, likewise for machine 'B').
MSMQ has to run on all machines that are sending or receiving messages.
It doesn't matter if you "send local/read remote" or "send remote/read local".

Dynamic XMPP rosters?

I'm currently looking into XMPP and I would like to know if there is a way to create dynamic XMPP rosters. I want the contact list of any user be automatically generated by the server / component / plugin.
Can components access and modify rosters?
I know that some servers (like OpenFire) use an external database to store these information but if I modify the database, I don't think the users will be notified in realtime.
Are some people already doing that or do you have an idea how to create it?
Thank you for your time.
In most XMPP servers this is called "shared roster groups".
I can't comment on Openfire in particular because I haven't used it for a long time, but I don't think I know of a server currently in which external roster changes are instantly transmitted to clients. Usually the client will simply pick up the new roster when it next logs in.
It would be possible to push the updates instantly to clients using what XMPP calls "roster pushes". This would require quite some work on the server though to identify what the changes are between what each client knows the roster to be, and what the new roster is, and then transmit just the changes.
If you really need this then a server plugin would probably be the way to go, or pester your server developers for the feature (I know that as a Prosody developer I've already been pestered, and this is something I'm planning to work on).
As for whether components can access users' rosters - this is dependent upon the server implementation and configuration.