1
2
3
4
5 package net.sf.asterisk.manager;
6
7 import java.io.IOException;
8 import java.util.*;
9
10 import net.sf.asterisk.manager.action.*;
11 import net.sf.asterisk.manager.event.*;
12 import net.sf.asterisk.util.Log;
13 import net.sf.asterisk.util.LogFactory;
14
15 /***
16 * @author PY
17 */
18 public class MultiAsterisksManager implements AsteriskManager, ManagerEventHandler
19 {
20 private final Log log = LogFactory.getLog(this.getClass());
21 /***
22 * A map of all Asterisk servers connections by their unique hostname.
23 */
24 private Map managerConnections;
25
26 /***
27 * A map of all active channel by theirs hostname of connection and unique id. keyMap ->
28 * "hostname:uniqueId"
29 */
30 private Map channels;
31 private Map queues;
32 private List queuedEvents;
33
34 /***
35 * A map of all "Initiallize flag" per connection. keyMap -> "hostname"
36 */
37 private Map initialized;
38
39 public MultiAsterisksManager()
40 {
41 this.channels = Collections.synchronizedMap(new HashMap());
42 this.queues = Collections.synchronizedMap(new HashMap());
43 this.queuedEvents = Collections.synchronizedList(new ArrayList());
44 this.managerConnections = Collections.synchronizedMap(new HashMap());
45 this.initialized = Collections.synchronizedMap(new HashMap());
46 }
47
48 public void addManagerConnection(ManagerConnection connection)
49 {
50 managerConnections.put(connection.getAsteriskServer(), connection);
51
52 Hashtable initializedBoolean = new Hashtable(3, 1);
53 initializedBoolean.put("channelsInitialized", new Boolean(false));
54
55 initializedBoolean.put("queuesInitialized", new Boolean(true));
56 initializedBoolean.put("initialized", new Boolean(false));
57
58 initialized.put(connection.getAsteriskServer(), initializedBoolean);
59
60 }
61
62 public void initialize() throws TimeoutException, IOException, AuthenticationFailedException
63 {
64 Iterator iterConnect = managerConnections.values().iterator();
65 while (iterConnect.hasNext())
66 {
67 ManagerConnection connection = (ManagerConnection) iterConnect.next();
68 connection.addEventHandler(this);
69 connection.login();
70 connection.sendAction(new StatusAction());
71 connection.sendAction(new QueueStatusAction());
72 }
73 }
74
75 /***
76 * Returns a map of all active channel by their unique id: "hostname:ChannelId".
77 */
78 public Map getChannels()
79 {
80 return channels;
81 }
82
83 public Map getQueues()
84 {
85 return queues;
86 }
87
88 /***
89 * Handles all events received from the asterisk server.<br>
90 * Events are queued until channels and queues are initialized and then delegated to the
91 * dispatchEvent method.
92 */
93 public void handleEvent(ManagerEvent event)
94 {
95 System.out.println("received: " + event);
96
97 Hashtable initializedBoolean = (Hashtable) initialized.get((AsteriskServer) event.getSource());
98
99 if (!((Boolean) initializedBoolean.get("initialized")).booleanValue())
100 {
101 if (event instanceof StatusEvent)
102 {
103 handleStatusEvent((StatusEvent) event);
104 }
105 else if (event instanceof StatusCompleteEvent)
106 {
107 handleStatusCompleteEvent((StatusCompleteEvent) event);
108 }
109 else if (event instanceof QueueParamsEvent)
110 {
111 handleQueueParamsEvent((QueueParamsEvent) event);
112 }
113 else if (event instanceof QueueMemberEvent)
114 {
115 handleQueueMemberEvent((QueueMemberEvent) event);
116 }
117 else if (event instanceof QueueEntryEvent)
118 {
119 handleQueueEntryEvent((QueueEntryEvent) event);
120 }
121 else
122 {
123 queuedEvents.add(event);
124 }
125
126 if (((Boolean) initializedBoolean.get("channelsInitialized")).booleanValue()
127 && ((Boolean) initializedBoolean.get("queuesInitialized")).booleanValue())
128 {
129 Iterator i = queuedEvents.iterator();
130
131 while (i.hasNext())
132 {
133 ManagerEvent queuedEvent = (ManagerEvent) i.next();
134 dispatchEvent(queuedEvent);
135 i.remove();
136 }
137
138 initializedBoolean.put("initialized", new Boolean(true));
139 }
140 }
141 else
142 {
143 dispatchEvent(event);
144 }
145 }
146
147 protected void dispatchEvent(ManagerEvent event)
148 {
149 if (event instanceof NewChannelEvent)
150 {
151 handleNewChannelEvent((NewChannelEvent) event);
152 }
153 else if (event instanceof NewExtenEvent)
154 {
155 handleNewExtenEvent((NewExtenEvent) event);
156 }
157 else if (event instanceof NewStateEvent)
158 {
159 handleNewStateEvent((NewStateEvent) event);
160 }
161 else if (event instanceof LinkEvent)
162 {
163 handleLinkEvent((LinkEvent) event);
164 }
165 else if (event instanceof UnlinkEvent)
166 {
167 handleUnlinkEvent((UnlinkEvent) event);
168 }
169 else if (event instanceof RenameEvent)
170 {
171 handleRenameEvent((RenameEvent) event);
172 }
173 else if (event instanceof HangupEvent)
174 {
175 handleHangupEvent((HangupEvent) event);
176 }
177 }
178
179 protected void addChannel(Channel channel)
180 {
181 channels.put(channel.getAsteriskServer().getHostname() + "/" + channel.getId(), channel);
182 }
183
184 protected void removeChannel(Channel channel)
185 {
186 channels.remove(channel.getAsteriskServer().getHostname() + "/" + channel.getId());
187 }
188
189 protected void addQueue(Queue queue)
190 {
191 queues.put(queue.getName(), queue);
192 }
193
194 protected void removeQueue(Queue queue)
195 {
196 queues.remove(queue.getName());
197 }
198
199 protected void handleStatusEvent(StatusEvent event)
200 {
201 Channel channel;
202 boolean isNew = false;
203
204 channel = (Channel) channels
205 .get(((AsteriskServer) event.getSource()).getHostname() + "/" + event.getUniqueId());
206 if (channel == null)
207 {
208 channel = new Channel(event.getChannel(), event.getUniqueId(), (AsteriskServer) event.getSource());
209 if (event.getSeconds() != null)
210 {
211 channel
212 .setDateOfCreation(new Date(System.currentTimeMillis() - (event.getSeconds().intValue() * 1000)));
213 }
214 isNew = true;
215 }
216
217 synchronized (channel)
218 {
219 channel.setCallerId(event.getCallerId());
220 channel.setAccount(event.getAccount());
221 channel.setState(ChannelStateEnum.getEnum(event.getState()));
222
223 if (event.getLink() != null)
224 {
225 Channel linkedChannel = getChannelByName(event.getLink());
226 if (linkedChannel != null)
227 {
228 channel.setLinkedChannel(linkedChannel);
229 synchronized (linkedChannel)
230 {
231 linkedChannel.setLinkedChannel(channel);
232 }
233 }
234 }
235 }
236
237 if (isNew)
238 {
239 log.info("Adding new channel " + channel.getName() + ", from server "
240 + channel.getAsteriskServer().getHostname());
241 addChannel(channel);
242 }
243 }
244
245 protected void handleStatusCompleteEvent(StatusCompleteEvent event)
246 {
247 log.info("Channels are now initialized");
248 Hashtable initializedBoolean = (Hashtable) initialized.get((AsteriskServer) event.getSource());
249 initializedBoolean.put("channelsInitialized", new Boolean(true));
250 }
251
252 protected void handleQueueParamsEvent(QueueParamsEvent event)
253 {
254 Queue queue;
255 boolean isNew = false;
256
257 queue = (Queue) queues.get(event.getQueue());
258
259 if (queue == null)
260 {
261 queue = new Queue(event.getQueue());
262 isNew = true;
263 }
264
265 synchronized (queue)
266 {
267 queue.setMax(event.getMax());
268 }
269
270 if (isNew)
271 {
272 log.info("Adding new queue " + queue.getName());
273 addQueue(queue);
274 }
275 }
276
277 protected void handleQueueMemberEvent(QueueMemberEvent event)
278 {
279
280 }
281
282 protected void handleQueueEntryEvent(QueueEntryEvent event)
283 {
284 Queue queue = (Queue) queues.get(event.getQueue());
285 Channel channel = getChannelByName(event.getChannel());
286
287 if (queue == null)
288 {
289 log.error("ignored QueueEntryEvent for unknown queue " + event.getQueue());
290 return;
291 }
292 if (channel == null)
293 {
294 log.error("ignored QueueEntryEvent for unknown channel " + event.getChannel());
295 return;
296 }
297
298 if (!queue.getEntries().contains(channel))
299 {
300 queue.addEntry(channel);
301 }
302 }
303
304 /***
305 * Returns a channel by its name.
306 *
307 * @param name name of the channel to return
308 * @return the channel with the given name
309 */
310 private Channel getChannelByName(String name)
311 {
312
313 Channel channel = null;
314 Iterator channelIterator = channels.values().iterator();
315 while (channelIterator.hasNext())
316 {
317 Channel tmp = (Channel) channelIterator.next();
318 if (tmp.getName() != null && tmp.getName().equals(name))
319 {
320 channel = tmp;
321 }
322 }
323 return channel;
324 }
325
326 protected void handleNewChannelEvent(NewChannelEvent event)
327 {
328 Channel channel = new Channel(event.getChannel(), event.getUniqueId(), (AsteriskServer) event.getSource());
329
330 channel.setCallerId(event.getCallerId());
331 channel.setState(ChannelStateEnum.getEnum(event.getState()));
332
333 log.info("Adding channel " + channel.getName() + ", on server " + channel.getAsteriskServer().getHostname());
334 addChannel(channel);
335 }
336
337 protected void handleNewExtenEvent(NewExtenEvent event)
338 {
339 Channel channel = (Channel) channels.get(((AsteriskServer) event.getSource()).getHostname() + "/"
340 + event.getUniqueId());
341 if (channel == null)
342 {
343 log.error("Ignored NewExtenEvent for unknown channel " + event.getChannel());
344 return;
345 }
346
347 synchronized (channel)
348 {
349
350 }
351 }
352
353 protected void handleNewStateEvent(NewStateEvent event)
354 {
355 Channel channel = (Channel) channels.get(((AsteriskServer) event.getSource()).getHostname() + "/"
356 + event.getUniqueId());
357 if (channel == null)
358 {
359 log.error("Ignored NewStateEvent for unknown channel " + event.getChannel());
360 return;
361 }
362
363 channel.setState(ChannelStateEnum.getEnum(event.getState()));
364 }
365
366 protected void handleHangupEvent(HangupEvent event)
367 {
368 Channel channel = (Channel) channels.get(((AsteriskServer) event.getSource()).getHostname() + "/"
369 + event.getUniqueId());
370 if (channel == null)
371 {
372 log.error("Ignored HangupEvent for unknown channel " + event.getChannel());
373 return;
374 }
375
376 synchronized (channel)
377 {
378 channel.setState(ChannelStateEnum.HUNGUP);
379 }
380
381 log.info("Removing channel " + channel.getName() + " due to hangup");
382 removeChannel(channel);
383 }
384
385 protected void handleLinkEvent(LinkEvent event)
386 {
387 Channel channel1 = (Channel) channels.get(((AsteriskServer) event.getSource()).getHostname() + "/"
388 + event.getUniqueId1());
389 Channel channel2 = (Channel) channels.get(((AsteriskServer) event.getSource()).getHostname() + "/"
390 + event.getUniqueId2());
391
392 if (channel1 == null)
393 {
394 log.error("Ignored LinkEvent for unknown channel " + event.getChannel1());
395 return;
396 }
397 if (channel2 == null)
398 {
399 log.error("Ignored LinkEvent for unknown channel " + event.getChannel2());
400 return;
401 }
402
403 log.info("Linking channels " + channel1.getName() + " and " + channel2.getName());
404 synchronized (this)
405 {
406 channel1.setLinkedChannel(channel2);
407 channel2.setLinkedChannel(channel1);
408 }
409 }
410
411 protected void handleUnlinkEvent(UnlinkEvent event)
412 {
413 Channel channel1 = getChannelByName(event.getChannel1());
414 Channel channel2 = getChannelByName(event.getChannel2());
415
416 if (channel1 == null)
417 {
418 log.error("Ignored UnlinkEvent for unknown channel " + event.getChannel1());
419 return;
420 }
421 if (channel2 == null)
422 {
423 log.error("Ignored UnlinkEvent for unknown channel " + event.getChannel2());
424 return;
425 }
426
427 log.info("Unlinking channels " + channel1.getName() + " and " + channel2.getName());
428 synchronized (channel1)
429 {
430 channel1.setLinkedChannel(null);
431 }
432
433 synchronized (channel2)
434 {
435 channel2.setLinkedChannel(null);
436 }
437 }
438
439 protected void handleRenameEvent(RenameEvent event)
440 {
441 Channel channel = (Channel) channels.get(((AsteriskServer) event.getSource()).getHostname() + "/"
442 + event.getUniqueId());
443
444 log.info("Renaming channel '" + channel.getName() + "' to '" + event.getNewname() + "'");
445 channel.setName(event.getNewname());
446 }
447
448
449
450
451
452
453 public Call originateCall(Originate originate) throws TimeoutException, IOException
454 {
455
456 return null;
457 }
458
459 public int[] getVersion(String file)
460 {
461 throw new UnsupportedOperationException();
462 }
463
464 public String getVersion()
465 {
466 throw new UnsupportedOperationException();
467 }
468 }