1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.asteriskjava.live.internal;
18
19 import org.asteriskjava.live.*;
20 import org.asteriskjava.manager.*;
21 import org.asteriskjava.manager.action.*;
22 import org.asteriskjava.manager.event.*;
23 import org.asteriskjava.manager.response.*;
24 import org.asteriskjava.util.DateUtil;
25 import org.asteriskjava.util.Log;
26 import org.asteriskjava.util.LogFactory;
27 import org.asteriskjava.util.AstUtil;
28 import org.asteriskjava.config.ConfigFile;
29 import org.asteriskjava.AsteriskVersion;
30
31 import java.util.*;
32 import java.util.concurrent.atomic.AtomicLong;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35
36
37
38
39
40
41
42 public class AsteriskServerImpl implements AsteriskServer, ManagerEventListener
43 {
44 private static final String ACTION_ID_PREFIX_ORIGINATE = "AJ_ORIGINATE_";
45 private static final String SHOW_VERSION_COMMAND = "show version";
46 private static final String SHOW_VERSION_1_6_COMMAND = "core show version";
47 private static final String SHOW_VERSION_FILES_COMMAND = "show version files";
48 private static final String SHOW_VERSION_FILES_1_6_COMMAND = "core show file version";
49 private static final Pattern SHOW_VERSION_FILES_PATTERN = Pattern.compile("^([\\S]+)\\s+Revision: ([0-9\\.]+)");
50 private static final String SHOW_VOICEMAIL_USERS_COMMAND = "show voicemail users";
51 private static final String SHOW_VOICEMAIL_USERS_1_6_COMMAND = "voicemail show users";
52 private static final Pattern SHOW_VOICEMAIL_USERS_PATTERN = Pattern.compile("^(\\S+)\\s+(\\S+)\\s+(.{25})");
53
54 private final Log logger = LogFactory.getLog(this.getClass());
55
56
57
58
59 private ManagerConnection eventConnection;
60 private ManagerEventListener eventListener = null;
61 private ManagerEventListenerProxy managerEventListenerProxy = null;
62
63 private boolean initialized = false;
64
65
66
67
68 private final ManagerConnectionPool connectionPool;
69
70 private final List<AsteriskServerListener> listeners;
71
72 private final ChannelManager channelManager;
73 private final MeetMeManager meetMeManager;
74 private final QueueManager queueManager;
75 private final AgentManager agentManager;
76
77
78
79
80
81
82 private String version;
83
84
85
86
87
88
89
90
91
92 private Map<String, String> versions;
93
94
95
96
97 private final Map<String, OriginateCallbackData> originateCallbacks;
98
99 private final AtomicLong idCounter;
100
101
102
103
104
105
106
107 private boolean skipQueues;
108
109
110
111
112
113 private boolean asyncEventHandling = true;
114
115
116
117
118 public AsteriskServerImpl()
119 {
120 connectionPool = new ManagerConnectionPool(1);
121 idCounter = new AtomicLong();
122 listeners = new ArrayList<AsteriskServerListener>();
123 originateCallbacks = new HashMap<String, OriginateCallbackData>();
124 channelManager = new ChannelManager(this);
125 agentManager = new AgentManager(this);
126 meetMeManager = new MeetMeManager(this, channelManager);
127 queueManager = new QueueManager(this, channelManager);
128 }
129
130
131
132
133
134
135
136 public AsteriskServerImpl(ManagerConnection eventConnection)
137 {
138 this();
139 setManagerConnection(eventConnection);
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153
154 public void setSkipQueues(boolean skipQueues)
155 {
156 this.skipQueues = skipQueues;
157 }
158
159 public void setManagerConnection(ManagerConnection eventConnection)
160 {
161 if (this.eventConnection != null)
162 {
163 throw new IllegalStateException("ManagerConnection already set.");
164 }
165
166 this.eventConnection = eventConnection;
167 this.connectionPool.clear();
168 this.connectionPool.add(eventConnection);
169 }
170
171 public ManagerConnection getManagerConnection()
172 {
173 return eventConnection;
174 }
175
176 public void initialize() throws ManagerCommunicationException
177 {
178 initializeIfNeeded();
179 }
180
181 private synchronized void initializeIfNeeded() throws ManagerCommunicationException
182 {
183 if (initialized)
184 {
185 return;
186 }
187
188 if (eventConnection.getState() == ManagerConnectionState.INITIAL
189 || eventConnection.getState() == ManagerConnectionState.DISCONNECTED)
190 {
191 try
192 {
193 eventConnection.login();
194 }
195 catch (Exception e)
196 {
197 throw new ManagerCommunicationException("Unable to login: " + e.getMessage(), e);
198 }
199 }
200
201 channelManager.initialize();
202 agentManager.initialize();
203 meetMeManager.initialize();
204 if (!skipQueues)
205 {
206 queueManager.initialize();
207 }
208
209 if (asyncEventHandling && managerEventListenerProxy == null)
210 {
211 managerEventListenerProxy = new ManagerEventListenerProxy(this);
212 eventConnection.addEventListener(managerEventListenerProxy);
213 }
214 else if (!asyncEventHandling && eventListener == null)
215 {
216 eventListener = this;
217 eventConnection.addEventListener(eventListener);
218 }
219 logger.info("Initializing done");
220 initialized = true;
221 }
222
223
224
225 public AsteriskChannel originateToExtension(String channel, String context,
226 String exten, int priority, long timeout)
227 throws ManagerCommunicationException, NoSuchChannelException
228 {
229 return originateToExtension(channel, context, exten, priority, timeout, null, null);
230 }
231
232 public AsteriskChannel originateToExtension(String channel, String context,
233 String exten, int priority, long timeout, CallerId callerId,
234 Map<String, String> variables)
235 throws ManagerCommunicationException, NoSuchChannelException
236 {
237 final OriginateAction originateAction;
238
239 originateAction = new OriginateAction();
240 originateAction.setChannel(channel);
241 originateAction.setContext(context);
242 originateAction.setExten(exten);
243 originateAction.setPriority(priority);
244 originateAction.setTimeout(timeout);
245 if (callerId != null)
246 {
247 originateAction.setCallerId(callerId.toString());
248 }
249 originateAction.setVariables(variables);
250
251 return originate(originateAction);
252 }
253
254 public AsteriskChannel originateToApplication(String channel,
255 String application, String data, long timeout)
256 throws ManagerCommunicationException, NoSuchChannelException
257 {
258 return originateToApplication(channel, application, data, timeout, null, null);
259 }
260
261 public AsteriskChannel originateToApplication(String channel,
262 String application, String data, long timeout, CallerId callerId,
263 Map<String, String> variables)
264 throws ManagerCommunicationException, NoSuchChannelException
265 {
266 final OriginateAction originateAction;
267
268 originateAction = new OriginateAction();
269 originateAction.setChannel(channel);
270 originateAction.setApplication(application);
271 originateAction.setData(data);
272 originateAction.setTimeout(timeout);
273 if (callerId != null)
274 {
275 originateAction.setCallerId(callerId.toString());
276 }
277 originateAction.setVariables(variables);
278
279 return originate(originateAction);
280 }
281
282 public AsteriskChannel originate(OriginateAction originateAction) throws ManagerCommunicationException, NoSuchChannelException
283 {
284 final ResponseEvents responseEvents;
285 final Iterator<ResponseEvent> responseEventIterator;
286 String uniqueId;
287 AsteriskChannel channel = null;
288
289
290 originateAction.setAsync(Boolean.TRUE);
291
292 initializeIfNeeded();
293
294
295 responseEvents = sendEventGeneratingAction(originateAction, originateAction.getTimeout() + 2000);
296
297 responseEventIterator = responseEvents.getEvents().iterator();
298 if (responseEventIterator.hasNext())
299 {
300 ResponseEvent responseEvent;
301
302 responseEvent = responseEventIterator.next();
303 if (responseEvent instanceof OriginateResponseEvent)
304 {
305 uniqueId = ((OriginateResponseEvent) responseEvent).getUniqueId();
306 logger.debug(responseEvent.getClass().getName() + " received with uniqueId " + uniqueId);
307 channel = getChannelById(uniqueId);
308 }
309 }
310
311 if (channel == null)
312 {
313 throw new NoSuchChannelException("Channel '" + originateAction.getChannel() + "' is not available");
314 }
315
316 return channel;
317 }
318
319 public void originateToExtensionAsync(String channel, String context,
320 String exten, int priority, long timeout, OriginateCallback cb)
321 throws ManagerCommunicationException
322 {
323 originateToExtensionAsync(channel, context, exten, priority, timeout, null, null, cb);
324 }
325
326 public void originateToExtensionAsync(String channel, String context,
327 String exten, int priority, long timeout, CallerId callerId,
328 Map<String, String> variables, OriginateCallback cb)
329 throws ManagerCommunicationException
330 {
331 final OriginateAction originateAction;
332
333 originateAction = new OriginateAction();
334 originateAction.setChannel(channel);
335 originateAction.setContext(context);
336 originateAction.setExten(exten);
337 originateAction.setPriority(priority);
338 originateAction.setTimeout(timeout);
339 if (callerId != null)
340 {
341 originateAction.setCallerId(callerId.toString());
342 }
343 originateAction.setVariables(variables);
344
345 originateAsync(originateAction, cb);
346 }
347
348 public void originateToApplicationAsync(String channel, String application,
349 String data, long timeout, OriginateCallback cb)
350 throws ManagerCommunicationException
351 {
352 originateToApplicationAsync(channel, application, data, timeout, null, null, cb);
353 }
354
355 public void originateToApplicationAsync(String channel, String application,
356 String data, long timeout, CallerId callerId,
357 Map<String, String> variables, OriginateCallback cb)
358 throws ManagerCommunicationException
359 {
360 final OriginateAction originateAction;
361
362 originateAction = new OriginateAction();
363 originateAction.setChannel(channel);
364 originateAction.setApplication(application);
365 originateAction.setData(data);
366 originateAction.setTimeout(timeout);
367 if (callerId != null)
368 {
369 originateAction.setCallerId(callerId.toString());
370 }
371 originateAction.setVariables(variables);
372
373 originateAsync(originateAction, cb);
374 }
375
376 public void originateAsync(OriginateAction originateAction,
377 OriginateCallback cb) throws ManagerCommunicationException
378 {
379 final Map<String, String> variables;
380 final String traceId;
381
382 traceId = ACTION_ID_PREFIX_ORIGINATE + idCounter.getAndIncrement();
383 if (originateAction.getVariables() == null)
384 {
385 variables = new HashMap<String, String>();
386 }
387 else
388 {
389 variables = new HashMap<String, String>(originateAction.getVariables());
390 }
391
392
393 variables.put("__" + Constants.VARIABLE_TRACE_ID, traceId);
394 originateAction.setVariables(variables);
395
396
397 originateAction.setAsync(Boolean.TRUE);
398 originateAction.setActionId(traceId);
399
400 if (cb != null)
401 {
402 final OriginateCallbackData callbackData;
403
404 callbackData = new OriginateCallbackData(originateAction, DateUtil.getDate(), cb);
405
406 synchronized (originateCallbacks)
407 {
408 originateCallbacks.put(traceId, callbackData);
409 }
410 }
411
412 initializeIfNeeded();
413 sendActionOnEventConnection(originateAction);
414 }
415
416 public Collection<AsteriskChannel> getChannels() throws ManagerCommunicationException
417 {
418 initializeIfNeeded();
419 return channelManager.getChannels();
420 }
421
422 public AsteriskChannel getChannelByName(String name) throws ManagerCommunicationException
423 {
424 initializeIfNeeded();
425 return channelManager.getChannelImplByName(name);
426 }
427
428 public AsteriskChannel getChannelById(String id) throws ManagerCommunicationException
429 {
430 initializeIfNeeded();
431 return channelManager.getChannelImplById(id);
432 }
433
434 public Collection<MeetMeRoom> getMeetMeRooms() throws ManagerCommunicationException
435 {
436 initializeIfNeeded();
437 return meetMeManager.getMeetMeRooms();
438 }
439
440 public MeetMeRoom getMeetMeRoom(String name) throws ManagerCommunicationException
441 {
442 initializeIfNeeded();
443 return meetMeManager.getOrCreateRoomImpl(name);
444 }
445
446 public Collection<AsteriskQueue> getQueues() throws ManagerCommunicationException
447 {
448 initializeIfNeeded();
449 return queueManager.getQueues();
450 }
451
452 public synchronized String getVersion() throws ManagerCommunicationException
453 {
454 final ManagerResponse response;
455 final String command;
456
457 initializeIfNeeded();
458 if (version == null)
459 {
460 if (eventConnection.getVersion().isAtLeast(AsteriskVersion.ASTERISK_1_6))
461 {
462 command = SHOW_VERSION_1_6_COMMAND;
463 }
464 else
465 {
466 command = SHOW_VERSION_COMMAND;
467 }
468
469 response = sendAction(new CommandAction(command));
470 if (response instanceof CommandResponse)
471 {
472 final List<?> result;
473
474 result = ((CommandResponse) response).getResult();
475 if (result.size() > 0)
476 {
477 version = (String) result.get(0);
478 }
479 }
480 else
481 {
482 logger.error("Response to CommandAction(\"" + command + "\") was not a CommandResponse but " + response);
483 }
484 }
485
486 return version;
487 }
488
489 public int[] getVersion(String file) throws ManagerCommunicationException
490 {
491 String fileVersion = null;
492 String[] parts;
493 int[] intParts;
494
495 initializeIfNeeded();
496 if (versions == null)
497 {
498 Map<String, String> map;
499 ManagerResponse response;
500
501 map = new HashMap<String, String>();
502 try
503 {
504 final String command;
505
506 if (eventConnection.getVersion().isAtLeast(AsteriskVersion.ASTERISK_1_6))
507 {
508 command = SHOW_VERSION_FILES_1_6_COMMAND;
509 }
510 else
511 {
512 command = SHOW_VERSION_FILES_COMMAND;
513 }
514 response = sendAction(new CommandAction(command));
515 if (response instanceof CommandResponse)
516 {
517 List<String> result;
518
519 result = ((CommandResponse) response).getResult();
520 for (int i = 2; i < result.size(); i++)
521 {
522 String line;
523 Matcher matcher;
524
525 line = result.get(i);
526 matcher = SHOW_VERSION_FILES_PATTERN.matcher(line);
527 if (matcher.find())
528 {
529 String key = matcher.group(1);
530 String value = matcher.group(2);
531
532 map.put(key, value);
533 }
534 }
535
536 fileVersion = map.get(file);
537 versions = map;
538 }
539 else
540 {
541 logger.error("Response to CommandAction(\""
542 + command + "\") was not a CommandResponse but " + response);
543 }
544 }
545 catch (Exception e)
546 {
547 logger.warn("Unable to send '" + SHOW_VERSION_FILES_COMMAND + "' command.", e);
548 }
549 }
550 else
551 {
552 synchronized (versions)
553 {
554 fileVersion = versions.get(file);
555 }
556 }
557
558 if (fileVersion == null)
559 {
560 return null;
561 }
562
563 parts = fileVersion.split("\\.");
564 intParts = new int[parts.length];
565
566 for (int i = 0; i < parts.length; i++)
567 {
568 try
569 {
570 intParts[i] = Integer.parseInt(parts[i]);
571 }
572 catch (NumberFormatException e)
573 {
574 intParts[i] = 0;
575 }
576 }
577
578 return intParts;
579 }
580
581 public String getGlobalVariable(String variable) throws ManagerCommunicationException
582 {
583 ManagerResponse response;
584 String value;
585
586 initializeIfNeeded();
587 response = sendAction(new GetVarAction(variable));
588 if (response instanceof ManagerError)
589 {
590 return null;
591 }
592 value = response.getAttribute("Value");
593 if (value == null)
594 {
595 value = response.getAttribute(variable);
596 }
597 return value;
598 }
599
600 public void setGlobalVariable(String variable, String value) throws ManagerCommunicationException
601 {
602 ManagerResponse response;
603
604 initializeIfNeeded();
605 response = sendAction(new SetVarAction(variable, value));
606 if (response instanceof ManagerError)
607 {
608 logger.error("Unable to set global variable '" + variable
609 + "' to '" + value + "':" + response.getMessage());
610 }
611 }
612
613 public Collection<Voicemailbox> getVoicemailboxes() throws ManagerCommunicationException
614 {
615 final Collection<Voicemailbox> voicemailboxes;
616 ManagerResponse response;
617 final List<String> result;
618
619 initializeIfNeeded();
620 voicemailboxes = new ArrayList<Voicemailbox>();
621 if (eventConnection.getVersion().isAtLeast(AsteriskVersion.ASTERISK_1_6))
622 {
623 response = sendAction(new CommandAction(SHOW_VOICEMAIL_USERS_1_6_COMMAND));
624 }
625 else
626 {
627 response = sendAction(new CommandAction(SHOW_VOICEMAIL_USERS_COMMAND));
628 }
629 if (!(response instanceof CommandResponse))
630 {
631 logger.error("Response to CommandAction(\"" + SHOW_VOICEMAIL_USERS_COMMAND + "\") was not a CommandResponse but " + response);
632 return voicemailboxes;
633 }
634
635 result = ((CommandResponse) response).getResult();
636 if (result == null || result.size() < 1)
637 {
638 return voicemailboxes;
639 }
640
641
642 result.remove(0);
643
644 for (String line : result)
645 {
646 final Matcher matcher;
647 final Voicemailbox voicemailbox;
648 final String context;
649 final String mailbox;
650 final String user;
651
652 matcher = SHOW_VOICEMAIL_USERS_PATTERN.matcher(line);
653 if (!matcher.find())
654 {
655 continue;
656 }
657
658 context = matcher.group(1);
659 mailbox = matcher.group(2);
660 user = matcher.group(3).trim();
661
662 voicemailbox = new Voicemailbox(mailbox, context, user);
663 voicemailboxes.add(voicemailbox);
664 }
665
666
667 for (Voicemailbox voicemailbox : voicemailboxes)
668 {
669 final String fullname;
670
671 fullname = voicemailbox.getMailbox() + "@"
672 + voicemailbox.getContext();
673 response = sendAction(new MailboxCountAction(fullname));
674 if (response instanceof MailboxCountResponse)
675 {
676 MailboxCountResponse mailboxCountResponse;
677
678 mailboxCountResponse = (MailboxCountResponse) response;
679 voicemailbox.setNewMessages(mailboxCountResponse.getNewMessages());
680 voicemailbox.setOldMessages(mailboxCountResponse.getOldMessages());
681 }
682 else
683 {
684 logger.error("Response to MailboxCountAction was not a MailboxCountResponse but " + response);
685 }
686 }
687
688 return voicemailboxes;
689 }
690
691 public List<String> executeCliCommand(String command) throws ManagerCommunicationException
692 {
693 final ManagerResponse response;
694
695 initializeIfNeeded();
696 response = sendAction(new CommandAction(command));
697 if (!(response instanceof CommandResponse))
698 {
699 throw new ManagerCommunicationException("Response to CommandAction(\"" + command
700 + "\") was not a CommandResponse but " + response, null);
701 }
702
703 return ((CommandResponse) response).getResult();
704 }
705
706 public boolean isModuleLoaded(String module) throws ManagerCommunicationException
707 {
708 return sendAction(new ModuleCheckAction(module)) instanceof ModuleCheckResponse;
709 }
710
711 public void loadModule(String module) throws ManagerCommunicationException
712 {
713 sendModuleLoadAction(module, ModuleLoadAction.LOAD_TYPE_LOAD);
714 }
715
716 public void unloadModule(String module) throws ManagerCommunicationException
717 {
718 sendModuleLoadAction(module, ModuleLoadAction.LOAD_TYPE_UNLOAD);
719 }
720
721 public void reloadModule(String module) throws ManagerCommunicationException
722 {
723 sendModuleLoadAction(module, ModuleLoadAction.LOAD_TYPE_RELOAD);
724 }
725
726 public void reloadAllModules() throws ManagerCommunicationException
727 {
728 sendModuleLoadAction(null, ModuleLoadAction.LOAD_TYPE_RELOAD);
729 }
730
731 protected void sendModuleLoadAction(String module, String loadType) throws ManagerCommunicationException
732 {
733 final ManagerResponse response;
734
735 response = sendAction(new ModuleLoadAction(module, loadType));
736 if (response instanceof ManagerError)
737 {
738 final ManagerError error = (ManagerError) response;
739 throw new ManagerCommunicationException(error.getMessage(), null);
740 }
741 }
742
743 public ConfigFile getConfig(String filename) throws ManagerCommunicationException
744 {
745 final ManagerResponse response;
746 final GetConfigResponse getConfigResponse;
747
748 initializeIfNeeded();
749 response = sendAction(new GetConfigAction(filename));
750 if (!(response instanceof GetConfigResponse))
751 {
752 throw new ManagerCommunicationException("Response to GetConfigAction(\"" + filename
753 + "\") was not a CommandResponse but " + response, null);
754 }
755
756 getConfigResponse = (GetConfigResponse) response;
757
758 final Map<String, List<String>> categories = new LinkedHashMap<String, List<String>>();
759 final Map<Integer, String> categoryMap = getConfigResponse.getCategories();
760 for (Map.Entry<Integer, String> categoryEntry : categoryMap.entrySet())
761 {
762 final List<String> lines;
763 final Map<Integer, String> lineMap = getConfigResponse.getLines(categoryEntry.getKey());
764
765 if (lineMap == null)
766 {
767 lines = new ArrayList<String>();
768 }
769 else
770 {
771 lines = new ArrayList<String>(lineMap.values());
772 }
773
774 categories.put(categoryEntry.getValue(), lines);
775 }
776
777 return new ConfigFileImpl(filename, categories);
778 }
779
780 public void addAsteriskServerListener(AsteriskServerListener listener) throws ManagerCommunicationException
781 {
782 initializeIfNeeded();
783 synchronized (listeners)
784 {
785 listeners.add(listener);
786 }
787 }
788
789 public void removeAsteriskServerListener(AsteriskServerListener listener)
790 {
791 synchronized (listeners)
792 {
793 listeners.remove(listener);
794 }
795 }
796
797 void fireNewAsteriskChannel(AsteriskChannel channel)
798 {
799 synchronized (listeners)
800 {
801 for (AsteriskServerListener listener : listeners)
802 {
803 try
804 {
805 listener.onNewAsteriskChannel(channel);
806 }
807 catch (Exception e)
808 {
809 logger.warn("Exception in onNewAsteriskChannel()", e);
810 }
811 }
812 }
813 }
814
815 void fireNewMeetMeUser(MeetMeUser user)
816 {
817 synchronized (listeners)
818 {
819 for (AsteriskServerListener listener : listeners)
820 {
821 try
822 {
823 listener.onNewMeetMeUser(user);
824 }
825 catch (Exception e)
826 {
827 logger.warn("Exception in onNewMeetMeUser()", e);
828 }
829 }
830 }
831 }
832
833 ManagerResponse sendActionOnEventConnection(ManagerAction action) throws ManagerCommunicationException
834 {
835 try
836 {
837 return eventConnection.sendAction(action);
838 }
839 catch (Exception e)
840 {
841 throw ManagerCommunicationExceptionMapper.mapSendActionException(action.getAction(), e);
842 }
843 }
844
845 ManagerResponse sendAction(ManagerAction action) throws ManagerCommunicationException
846 {
847
848 try
849 {
850 return eventConnection.sendAction(action);
851 }
852 catch (Exception e)
853 {
854 throw ManagerCommunicationExceptionMapper.mapSendActionException(action.getAction(), e);
855 }
856 }
857
858 ResponseEvents sendEventGeneratingAction(EventGeneratingAction action) throws ManagerCommunicationException
859 {
860
861 try
862 {
863 return eventConnection.sendEventGeneratingAction(action);
864 }
865 catch (Exception e)
866 {
867 throw ManagerCommunicationExceptionMapper.mapSendActionException(action.getAction(), e);
868 }
869 }
870
871 ResponseEvents sendEventGeneratingAction(EventGeneratingAction action,
872 long timeout) throws ManagerCommunicationException
873 {
874
875 try
876 {
877 return eventConnection.sendEventGeneratingAction(action, timeout);
878 }
879 catch (Exception e)
880 {
881 throw ManagerCommunicationExceptionMapper.mapSendActionException(action.getAction(), e);
882 }
883 }
884
885 OriginateCallbackData getOriginateCallbackDataByTraceId(String traceId)
886 {
887 synchronized (originateCallbacks)
888 {
889 return originateCallbacks.get(traceId);
890 }
891 }
892
893
894
895
896
897
898
899
900
901 public void onManagerEvent(ManagerEvent event)
902 {
903
904 if (event instanceof ConnectEvent)
905 {
906 handleConnectEvent((ConnectEvent) event);
907 }
908 else if (event instanceof DisconnectEvent)
909 {
910 handleDisconnectEvent((DisconnectEvent) event);
911 }
912 else if (event instanceof NewChannelEvent)
913 {
914 channelManager.handleNewChannelEvent((NewChannelEvent) event);
915 }
916 else if (event instanceof NewExtenEvent)
917 {
918 channelManager.handleNewExtenEvent((NewExtenEvent) event);
919 }
920 else if (event instanceof NewStateEvent)
921 {
922 channelManager.handleNewStateEvent((NewStateEvent) event);
923 }
924 else if (event instanceof NewCallerIdEvent)
925 {
926 channelManager.handleNewCallerIdEvent((NewCallerIdEvent) event);
927 }
928 else if (event instanceof DialEvent)
929 {
930 channelManager.handleDialEvent((DialEvent) event);
931 }
932 else if (event instanceof BridgeEvent)
933 {
934 channelManager.handleBridgeEvent((BridgeEvent) event);
935 }
936 else if (event instanceof RenameEvent)
937 {
938 channelManager.handleRenameEvent((RenameEvent) event);
939 }
940 else if (event instanceof HangupEvent)
941 {
942 channelManager.handleHangupEvent((HangupEvent) event);
943 }
944 else if (event instanceof CdrEvent)
945 {
946 channelManager.handleCdrEvent((CdrEvent) event);
947 }
948 else if (event instanceof VarSetEvent)
949 {
950 channelManager.handleVarSetEvent((VarSetEvent) event);
951 }
952 else if (event instanceof DtmfEvent)
953 {
954 channelManager.handleDtmfEvent((DtmfEvent) event);
955 }
956
957
958 else if (event instanceof ParkedCallEvent)
959 {
960 channelManager.handleParkedCallEvent((ParkedCallEvent) event);
961 }
962 else if (event instanceof ParkedCallGiveUpEvent)
963 {
964 channelManager.handleParkedCallGiveUpEvent((ParkedCallGiveUpEvent) event);
965 }
966 else if (event instanceof ParkedCallTimeOutEvent)
967 {
968 channelManager.handleParkedCallTimeOutEvent((ParkedCallTimeOutEvent) event);
969 }
970 else if (event instanceof UnparkedCallEvent)
971 {
972 channelManager.handleUnparkedCallEvent((UnparkedCallEvent) event);
973 }
974
975
976 else if (event instanceof JoinEvent)
977 {
978 queueManager.handleJoinEvent((JoinEvent) event);
979 }
980 else if (event instanceof LeaveEvent)
981 {
982 queueManager.handleLeaveEvent((LeaveEvent) event);
983 }
984 else if (event instanceof QueueMemberStatusEvent)
985 {
986 queueManager.handleQueueMemberStatusEvent((QueueMemberStatusEvent) event);
987 }
988 else if (event instanceof QueueMemberPenaltyEvent)
989 {
990 queueManager.handleQueueMemberPenaltyEvent((QueueMemberPenaltyEvent) event);
991 }
992 else if (event instanceof QueueMemberAddedEvent)
993 {
994 queueManager.handleQueueMemberAddedEvent((QueueMemberAddedEvent) event);
995 }
996 else if (event instanceof QueueMemberRemovedEvent)
997 {
998 queueManager.handleQueueMemberRemovedEvent((QueueMemberRemovedEvent) event);
999 }
1000 else if (event instanceof QueueMemberPausedEvent)
1001 {
1002 queueManager.handleQueueMemberPausedEvent((QueueMemberPausedEvent) event);
1003 }
1004
1005
1006 else if (event instanceof AbstractMeetMeEvent)
1007 {
1008 meetMeManager.handleMeetMeEvent((AbstractMeetMeEvent) event);
1009 }
1010 else if (event instanceof OriginateResponseEvent)
1011 {
1012 handleOriginateEvent((OriginateResponseEvent) event);
1013 }
1014
1015 else if (event instanceof AgentsEvent)
1016 {
1017 agentManager.handleAgentsEvent((AgentsEvent) event);
1018 }
1019 else if (event instanceof AgentCalledEvent)
1020 {
1021 agentManager.handleAgentCalledEvent((AgentCalledEvent) event);
1022 }
1023 else if (event instanceof AgentConnectEvent)
1024 {
1025 agentManager.handleAgentConnectEvent((AgentConnectEvent) event);
1026 }
1027 else if (event instanceof AgentCompleteEvent)
1028 {
1029 agentManager.handleAgentCompleteEvent((AgentCompleteEvent) event);
1030 }
1031 else if (event instanceof AgentCallbackLoginEvent)
1032 {
1033 agentManager.handleAgentCallbackLoginEvent((AgentCallbackLoginEvent) event);
1034 }
1035 else if (event instanceof AgentCallbackLogoffEvent)
1036 {
1037 agentManager.handleAgentCallbackLogoffEvent((AgentCallbackLogoffEvent) event);
1038 }
1039 else if (event instanceof AgentLoginEvent)
1040 {
1041 agentManager.handleAgentLoginEvent((AgentLoginEvent) event);
1042 }
1043 else if (event instanceof AgentLogoffEvent)
1044 {
1045 agentManager.handleAgentLogoffEvent((AgentLogoffEvent) event);
1046 }
1047
1048 }
1049
1050
1051
1052
1053
1054
1055 private void handleDisconnectEvent(DisconnectEvent disconnectEvent)
1056 {
1057
1058 version = null;
1059 versions = null;
1060
1061
1062 channelManager.disconnected();
1063 agentManager.disconnected();
1064 meetMeManager.disconnected();
1065 queueManager.disconnected();
1066 initialized = false;
1067 }
1068
1069
1070
1071
1072
1073
1074 private void handleConnectEvent(ConnectEvent connectEvent)
1075 {
1076 try
1077 {
1078 initialize();
1079 }
1080 catch (Exception e)
1081 {
1082 logger.error("Unable to reinitialize state after reconnection", e);
1083 }
1084 }
1085
1086 private void handleOriginateEvent(OriginateResponseEvent originateEvent)
1087 {
1088 final String traceId;
1089 final OriginateCallbackData callbackData;
1090 final OriginateCallback cb;
1091 final AsteriskChannelImpl channel;
1092 final AsteriskChannelImpl otherChannel;
1093
1094 traceId = originateEvent.getActionId();
1095 if (traceId == null)
1096 {
1097 return;
1098 }
1099
1100 synchronized (originateCallbacks)
1101 {
1102 callbackData = originateCallbacks.get(traceId);
1103 if (callbackData == null)
1104 {
1105 return;
1106 }
1107 originateCallbacks.remove(traceId);
1108 }
1109
1110 cb = callbackData.getCallback();
1111 if (!AstUtil.isNull(originateEvent.getUniqueId()))
1112 {
1113 channel = channelManager.getChannelImplById(originateEvent.getUniqueId());
1114 }
1115 else
1116 {
1117 channel = callbackData.getChannel();
1118 }
1119
1120 try
1121 {
1122 if (channel == null)
1123 {
1124 final LiveException cause;
1125
1126 cause = new NoSuchChannelException("Channel '" + callbackData.getOriginateAction().getChannel() + "' is not available");
1127 cb.onFailure(cause);
1128 return;
1129 }
1130
1131 if (channel.wasBusy())
1132 {
1133 cb.onBusy(channel);
1134 return;
1135 }
1136
1137 otherChannel = channelManager.getOtherSideOfLocalChannel(channel);
1138
1139
1140 if (otherChannel != null)
1141 {
1142 final AsteriskChannel dialedChannel;
1143
1144 dialedChannel = otherChannel.getDialedChannel();
1145
1146
1147 if (otherChannel.wasBusy())
1148 {
1149 cb.onBusy(channel);
1150 return;
1151 }
1152
1153
1154
1155
1156
1157
1158
1159
1160 if (dialedChannel != null && dialedChannel.wasBusy())
1161 {
1162 cb.onBusy(channel);
1163 return;
1164 }
1165 }
1166
1167 if (channel.wasInState(ChannelState.DOWN))
1168 {
1169 cb.onNoAnswer(channel);
1170 return;
1171 }
1172
1173
1174 cb.onSuccess(channel);
1175 }
1176 catch (Throwable t)
1177 {
1178 logger.warn("Exception dispatching originate progress", t);
1179 }
1180 }
1181
1182 public void shutdown()
1183 {
1184 if (eventConnection != null && (eventConnection.getState() == ManagerConnectionState.CONNECTED || eventConnection.getState() == ManagerConnectionState.RECONNECTING))
1185 {
1186 eventConnection.logoff();
1187 }
1188 if (managerEventListenerProxy != null)
1189 {
1190 managerEventListenerProxy.shutdown();
1191 }
1192 managerEventListenerProxy = null;
1193 eventListener = null;
1194 }
1195
1196 public List<PeerEntryEvent> getPeerEntries() throws ManagerCommunicationException
1197 {
1198 ResponseEvents responseEvents = sendEventGeneratingAction(new SipPeersAction(), 2000);
1199 List<PeerEntryEvent> peerEntries = new ArrayList<PeerEntryEvent>(30);
1200 for (ResponseEvent re : responseEvents.getEvents())
1201 {
1202 if (re instanceof PeerEntryEvent)
1203 {
1204 peerEntries.add((PeerEntryEvent) re);
1205 }
1206 }
1207 return peerEntries;
1208 }
1209
1210 public DbGetResponseEvent dbGet(String family, String key) throws ManagerCommunicationException
1211 {
1212 ResponseEvents responseEvents = sendEventGeneratingAction(new DbGetAction(family, key), 2000);
1213 DbGetResponseEvent dbgre = null;
1214 for (ResponseEvent re : responseEvents.getEvents())
1215 {
1216 dbgre = (DbGetResponseEvent) re;
1217 }
1218 return dbgre;
1219 }
1220
1221 public void dbDel(String family, String key) throws ManagerCommunicationException
1222 {
1223
1224
1225 sendAction(new CommandAction("database del " + family + " " + key));
1226 }
1227
1228 public void dbPut(String family, String key, String value) throws ManagerCommunicationException
1229 {
1230 sendAction(new DbPutAction(family, key, value));
1231 }
1232
1233 public AsteriskChannel getChannelByNameAndActive(String name) throws ManagerCommunicationException
1234 {
1235 initializeIfNeeded();
1236 return channelManager.getChannelImplByNameAndActive(name);
1237 }
1238
1239 public Collection<AsteriskAgent> getAgents() throws ManagerCommunicationException
1240 {
1241 initializeIfNeeded();
1242 return agentManager.getAgents();
1243 }
1244
1245 void fireNewAgent(AsteriskAgentImpl agent)
1246 {
1247 synchronized (listeners)
1248 {
1249 for (AsteriskServerListener listener : listeners)
1250 {
1251 try
1252 {
1253 listener.onNewAgent(agent);
1254 }
1255 catch (Exception e)
1256 {
1257 logger.warn("Exception in onNewAgent()", e);
1258 }
1259 }
1260 }
1261 }
1262
1263 void fireNewQueueEntry(AsteriskQueueEntry entry)
1264 {
1265 synchronized (listeners)
1266 {
1267 for (AsteriskServerListener listener : listeners)
1268 {
1269 try
1270 {
1271 listener.onNewQueueEntry(entry);
1272 }
1273 catch (Exception e)
1274 {
1275 logger.warn("Exception in onNewQueueEntry()", e);
1276 }
1277 }
1278 }
1279 }
1280 }