Add distributed devicestate via the XMPP protocol.
[asterisk/asterisk.git] / doc / distributed_devstate-XMPP.txt
1 ===============================================================================
2 ===
3 === XMPP PubSub Distributed Device State
4 ===
5 === Copyright (C) 2010, Digium, Inc.
6 === Leif Madsen <lmadsen@digium.com>
7 ===
8 ===============================================================================
9
10 -------------------------------------------------------------------------------
11 --- INTRODUCTION
12 -------------------------------------------------------------------------------
13
14 This document describes installing and utilizing XMPP PubSub events to 
15 distribute device state and message waiting indication (MWI) events between
16 servers. The difference between this method and OpenAIS (see 
17 distributed_devstate.txt) is that OpenAIS can only be used in low latency
18 networks; meaning only on the LAN, and not across the internet.
19
20 If you plan on distributing device state or MWI across the internet, then you
21 will require the use of XMPP PubSub events.
22
23 -------------------------------------------------------------------------------
24
25 -------------------------------------------------------------------------------
26 --- Tigase Installation
27 -------------------------------------------------------------------------------
28
29 -- Description --
30
31 Currently the only server supported for XMPP PubSub events is the Tigase open 
32 source XMPP/Jabber environment. This is the server that the various Asterisk
33 servers will connect to in order to distribute the events. The Tigase server can
34 even be clustered in order to provide high availability for your device state;
35 however, that is beyond the scope of this document.
36
37 For more information about Tigase, visit their web site:
38
39     http://www.tigase.org
40
41 -- Download --
42
43 To download the Tigase environment, get the latest version at:
44
45     http://www.tigase.org/en/filebrowser/tigase-server
46
47 -- Install --
48
49 The Tigase server requires a working Java environment, including both a JRE
50 (Java Runtime Environment) and a JDK (Java Development Kit), currently at least
51 version 1.6.
52
53 For more information about how to install Tigase, see the web site:
54
55     http://www.tigase.org/en/content/quick-start
56
57 -------------------------------------------------------------------------------
58
59 -------------------------------------------------------------------------------
60 --- Tigase Configuration
61 -------------------------------------------------------------------------------
62
63 While installing Tigase, be sure you enable the PubSub module. Without it, the
64 PubSub events won't be accepted by the server, and your device state will not be
65 distributed.
66
67 There are a couple of things you need to configure in Tigase before you start it
68 in order for Asterisk to connect. The first thing we need to do is generate the
69 self-signed certificate. To do this we use the keytool application. More
70 information can be found here:
71
72     http://www.tigase.org/en/content/server-certificate
73
74 -- Generating the keystore file --
75
76 Generally, we need to run the following commands to generate a new keystore
77 file.
78
79 # cd /opt/Tigase-4.3.1-b1858/certs
80
81 Be sure to change the 'yourdomain' to your domain.
82
83 # keytool -genkey -alias yourdomain -keystore rsa-keystore \
84       -keyalg RSA -sigalg MD5withRSA
85
86 The keytool application will then ask you for a password. Use the password
87 'keystore' as this is the default password that Tigase will use to load the
88 keystore file.
89
90 You then need to specify your domain as the first value to be entered in the
91 security certificate.
92
93 What is your first and last name?
94   [Unknown]: asterisk.mydomain.tld
95 What is the name of your organizational unit?
96   [Unknown]:
97 What is the name of your organization?
98   [Unknown]:
99 What is the name of your City or Locality?
100   [Unknown]:
101 What is the name of your State or Province?
102   [Unknown]:
103 What is the two-letter country code for this unit?
104   [Unknown]:
105 Is CN=asterisk.mydomain.tld, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
106   [no]: yes
107
108 You will then be asked for another password, in which case you must just press
109 enter for the same password as Tigase will not work without them being the same.
110
111 Enter key password for <mykey>
112              (RETURN if same as keystore password):
113
114
115 -- Configuring init.properties --
116
117 The next step is to configure the init.properties file which is used by Tigase
118 to generate the tigase.xml file. Whenever you change the init.properties file
119 because sure to remove the current tigase.xml file so that it will be
120 regenerated at start up.
121
122 # cd /opt/Tigase-4.3.1-b1858/etc
123
124 Then edit the init.properties file and add the following:
125
126 config-type=--gen-config-def
127 --admins=admin@asterisk.mydomain.tld
128 --virt-hosts=asterisk.mydomain.tld
129 --debug=server
130 --user-db=derby
131 --user-db-uri=jdbc:derby:/opt/Tigase-4.3.1-b1858
132 --comp-name-1=pubsub
133 --comp-class-1=tigase.pubsub.PubSubComponent
134
135 Be sure to change the domain in the --admin and --virt-hosts options. The most
136 important lines are --comp-name-1 and --comp-class-1 which tell Tigase to load
137 the PubSub module.
138
139 -------------------------------------------------------------------------------
140
141 -------------------------------------------------------------------------------
142 --- Running Tigase
143 -------------------------------------------------------------------------------
144
145 You can then start the Tigase server with the tigase.sh script.
146
147 # cd /opt/Tigase-4.3.1-b1858
148 # ./scripts/tigase.sh start etc/tigase.conf
149
150 -------------------------------------------------------------------------------
151
152 -------------------------------------------------------------------------------
153 --- Adding Buddies to Tigase
154 -------------------------------------------------------------------------------
155
156 At this time, Asterisk is not able to automatically register your peers for you,
157 so you'll need to use an external application to do the initial registration.
158
159 Pidgin is an excellent multi-protocol instant messenger application which
160 supports XMPP. It runs on Linux, Windows, and OSX, and is open source. You can
161 get Pidgin from http://www.pidgin.im
162
163 Then add the two buddies we'll use in Asterisk with Pidgin by connecting to
164 the Tigase server. For more information about how to register new buddies, see
165 the Pidgin documentation.
166
167 Once the initial registration is done and loaded into Tigase, you no longer need
168 to worry about using Pidgin. Asterisk will then be able to load the peers into
169 memory at start up.
170
171 The example peers we've used in the following documentation for our two nodes
172 are:
173
174 server1@asterisk.mydomain.tld/astvoip1
175 server2@asterisk.mydomain.tld/astvoip2
176
177 -------------------------------------------------------------------------------
178
179 -------------------------------------------------------------------------------
180 --- Installing Asterisk
181 -------------------------------------------------------------------------------
182
183 Install Asterisk as usual. However, you'll need to make sure you have the
184 res_jabber module compiled, which requires the iksemel development library.
185 Additionally, be sure you have the OpenSSL development library installed so you
186 can connect securly to the Tigase server.
187
188 Make sure you check menuselect that res_jabber is selected so that it will
189 compile.
190
191 # cd asterisk-source
192 # ./configure
193
194 # make menuselect
195   ---> Resource Modules
196
197 If you don't have jabber.conf in your existing configuration, because sure to
198 copy the sample configuration file there.
199
200 # cd configs
201 # cp jabber.conf.sample /etc/asterisk/jabber.conf
202
203 -------------------------------------------------------------------------------
204
205 -------------------------------------------------------------------------------
206 --- Configuring Asterisk
207 -------------------------------------------------------------------------------
208
209 We then need to configure our servers to communicate with the Tigase server. We
210 need to modify the jabber.conf file on the servers. The configurations below are
211 for a 2 server setup, but could be expanded for additional servers easily.
212
213 The key note here is to note that the pubsub_node option needs to start with
214 pubsub, so for example, pubsub.asterisk.mydomain.tld. Without the 'pubsub' your
215 Asterisk system will not be able to distribute events.
216
217 Additionally, you will need to specify each of the servers you need to connec to
218 using the 'buddy' option.
219
220
221 -- Asterisk Server 1 --
222
223 [general]
224 debug=no                                ;;Turn on debugging by default.
225 ;autoprune=yes                          ;;Auto remove users from buddy list. Depending on your
226                                         ;;setup (ie, using your personal Gtalk account for a test)
227                                         ;;you might lose your contacts list. Default is 'no'.
228 autoregister=yes                        ;;Auto register users from buddy list.
229 ;collection_nodes=yes                   ;;Enable support for XEP-0248 for use with
230                                         ;;distributed device state.  Default is 'no'.
231 ;pubsub_autocreate=yes                  ;;Whether or not the PubSub server supports/is using
232                                         ;;auto-create for nodes.  If it is, we have to
233                                         ;;explicitly pre-create nodes before publishing them.
234                                         ;;Default is 'no'.
235
236 [asterisk]
237 type=client
238 serverhost=asterisk.mydomain.tld
239 pubsub_node=pubsub.asterisk.mydomain.tld
240 username=server1@asterisk.mydomain.tld/astvoip1
241 secret=welcome
242 distribute_events=yes
243 status=available
244 usetls=no
245 usesasl=yes
246 buddy=server2@asterisk.mydomain.tld/astvoip2
247
248
249 -- Asterisk Server 2 --
250
251 [general]
252 debug=yes                               ;;Turn on debugging by default.
253 ;autoprune=yes                          ;;Auto remove users from buddy list. Depending on your
254                                         ;;setup (ie, using your personal Gtalk account for a test)
255                                         ;;you might lose your contacts list. Default is 'no'.
256 autoregister=yes                        ;;Auto register users from buddy list.
257 ;collection_nodes=yes                   ;;Enable support for XEP-0248 for use with
258                                         ;;distributed device state.  Default is 'no'.
259 ;pubsub_autocreate=yes                  ;;Whether or not the PubSub server supports/is using
260                                         ;;auto-create for nodes.  If it is, we have to
261                                         ;;explicitly pre-create nodes before publishing them.
262                                         ;;Default is 'no'.
263
264 [asterisk]
265 type=client
266 serverhost=asterisk.mydomain.tld
267 pubsub_node=pubsub.asterisk.mydomain.tld
268 username=server2@asterisk.mydomain.tld/astvoip2
269 secret=welcome
270 distribute_events=yes
271 status=available
272 usetls=no
273 usesasl=yes
274 buddy=server1@asterisk.mydomain.tld/astvoip1
275
276 -------------------------------------------------------------------------------
277
278 -------------------------------------------------------------------------------
279 --- Basic Testing of Asterisk with XMPP PubSub
280 -------------------------------------------------------------------------------
281
282 Once you have Asterisk installed with XMPP PubSub, it is time to test it out.
283
284 We need to start up our first server and make sure we get connected to the XMPP
285 server. We can verify this with an Asterisk console command to determine if
286 we're connected.
287
288 On Asterisk 1 we can run 'jabber show connected' to verify we're connected to
289 the XMPP server.
290
291 *CLI> jabber show connected 
292 Jabber Users and their status:
293        User: server1@asterisk.mydomain.tld/astvoip1     - Connected
294 ----
295    Number of users: 1
296
297 The command above has given us output which verifies we've connected our first
298 server.
299
300 We can then check the state of our buddies with the 'jabber show buddies' CLI
301 command.
302
303 *CLI> jabber show buddies
304 Jabber buddy lists
305 Client: server1@asterisk.mydomain.tld/astvoip1
306         Buddy:  server2@asterisk.mydomain.tld
307                 Resource: None
308         Buddy:  server2@asterisk.mydomain.tld/astvoip2
309                 Resource: None
310
311 The output above tells us we're not connected to any buddies, and thus we're not
312 distributing state to anyone (or getting it from anyone). That makes sense since
313 we haven't yet started our other server.
314
315 Now, let's start the other server and verify the servers are able to establish
316 a connection between each other.
317
318 On Asterisk 2, again we run the 'jabber show connected' command to make sure
319 we've connected successfully to the XMPP server.
320
321 *CLI> jabber show connected 
322 Jabber Users and their status:
323        User: server2@asterisk.mydomain.tld/astvoip2     - Connected
324 ----
325    Number of users: 1
326
327 And now we can check the status of our buddies.
328
329 *CLI> jabber show buddies
330 Jabber buddy lists
331 Client: server2@scooter/astvoip2
332         Buddy:  server1@asterisk.mydomain.tld
333                 Resource: astvoip1
334                         node: http://www.asterisk.org/xmpp/client/caps
335                         version: asterisk-xmpp
336                         Jingle capable: yes
337                 Status: 1
338                 Priority: 0
339         Buddy:  server1@asterisk.mydomain.tld/astvoip1
340                 Resource: None
341
342 Excellent! So we're connected to the buddy on Asterisk 1, and we could run the
343 same command on Asterisk 1 to verify the buddy on Asterisk 2 is seen.
344
345 -------------------------------------------------------------------------------
346
347 -------------------------------------------------------------------------------
348 --- Testing Distributed Device State
349 -------------------------------------------------------------------------------
350
351 The easiest way to test distributed device state is to use the DEVICE_STATE()
352 diaplan function.  For example, you could have the following piece of dialplan
353 on every server:
354
355 [devstate_test]
356
357 exten => 1234,hint,Custom:mystate
358
359 exten => set_inuse,1,Set(DEVICE_STATE(Custom:mystate)=INUSE)
360 exten => set_not_inuse,1,Set(DEVICE_STATE(Custom:mystate)=NOT_INUSE)
361
362 exten => check,1,NoOp(Custom:mystate is ${DEVICE_STATE(Custom:mystate)})
363
364
365 Now, you can test that the cluster-wide state of "Custom:mystate" is what
366 you would expect after going to the CLI of each server and adjusting the state.
367
368 server1*CLI> console dial set_inuse@devstate_test
369    ...
370
371 server2*CLI> console dial check@devstate_test
372     -- Executing [check@devstate_test:1] NoOp("OSS/dsp", "Custom:mystate is INUSE") in new stack
373
374 Various combinations of setting and checking the state on different servers can
375 be used to verify that it works as expected.  Also, you can see the status of
376 the hint on each server, as well, to see how extension state would reflect the
377 state change with distributed device state:
378
379 server2*CLI> core show hints
380     -= Registered Asterisk Dial Plan Hints =-
381                    1234@devstate_test       : Custom:mystate        State:InUse           Watchers  0
382
383
384 One other helpful thing here during testing and debugging is to enable debug
385 logging.  To do so, enable debug on the console in /etc/asterisk/logger.conf.
386 Also, enable debug at the Asterisk CLI.
387
388 *CLI> core set debug 1
389
390 When you have this debug enabled, you will see output during the processing of
391 every device state change.  The important thing to look for is where the known
392 state of the device for each server is added together to determine the overall
393 state.
394
395 -------------------------------------------------------------------------------
396
397 -------------------------------------------------------------------------------
398 --- Notes On Large Installations
399 -------------------------------------------------------------------------------
400
401 On larger installations where you want a fully meshed network of buddies (i.e.
402 all servers have all the buddies of the remote servers), you may want some
403 method of distributing those buddies automatically so you don't need to modify
404 all servers (N+1) every time you add a new server to the cluster.
405
406 The problem there is that you're confined by what's allowed in XEP-0060, and 
407 unfortunately that means modifying affiliations by individual JID (as opposed to
408 the various subscription access models, which are more flexible).
409
410 See here for details:
411 http://xmpp.org/extensions/xep-0060.html#owner-affiliations
412
413 One method for making this slightly easier is to utilize the #exec functionality
414 in configuration files, and dynamically generate the buddies via script that
415 pulls the information from a database, or to #include a file which is 
416 automatically generated on all the servers when you add a new node to the
417 cluster.
418
419 Unfortunately this still requires a reload of res_jabber.so on all the servers,
420 but this could also be solved through the use of the Asterisk Manager Interface
421 (AMI).
422
423 So while this is not the ideal situation, it is programmatically solvable with
424 existing technologies and features found in Asterisk today.
425
426 -------------------------------------------------------------------------------
427
428 -------------------------------------------------------------------------------
429 --- Questions, Comments, and Bug Reports
430 -------------------------------------------------------------------------------
431
432 Please utilize the Asterisk issue tracker for all bug reports at
433 https://issues.asterisk.org