View Javadoc

1   package org.asteriskjava.tools;
2   
3   import org.asteriskjava.live.DefaultAsteriskServer;
4   import org.asteriskjava.manager.ManagerEventListener;
5   import org.asteriskjava.manager.event.*;
6   
7   import java.beans.BeanInfo;
8   import java.beans.Introspector;
9   import java.beans.PropertyDescriptor;
10  import java.io.IOException;
11  import java.io.PrintWriter;
12  import java.util.ArrayList;
13  import java.util.HashMap;
14  import java.util.List;
15  import java.util.Map;
16  
17  /**
18   * A diagnostic tool that creates an HTML file showing the state changing events
19   * received from Asterisk on the Manager API.<p>
20   * The following events are shown:
21   * <ul>
22   * <li>NewChannel</li>
23   * <li>NewState</li>
24   * <li>Rename</li>
25   * <li>Dial</li>
26   * <li>Bridge (Link and Unlink)</li>
27   * <li>Hangup</li>
28   * </ul>
29   * Usage: java org.asteriskjava.tools.HtmlEventTracer host username password
30   *
31   * @version $Id$
32   */
33  public class HtmlEventTracer implements ManagerEventListener
34  {
35      private String filename = "trace.html";
36      private PrintWriter writer;
37      private final List<String> uniqueIds;
38      private final List<ManagerEvent> events;
39      private final Map<Class<? extends ManagerEvent>, String> colors;
40  
41      public HtmlEventTracer()
42      {
43          uniqueIds = new ArrayList<String>();
44          events = new ArrayList<ManagerEvent>();
45          colors = new HashMap<Class<? extends ManagerEvent>, String>();
46  
47          colors.put(NewChannelEvent.class, "#7cd300"); // green
48          colors.put(NewStateEvent.class, "#a4b6c8");
49          colors.put(NewExtenEvent.class, "#efefef"); // grey
50          colors.put(RenameEvent.class, "#ddeeff"); // light blue
51          colors.put(DialEvent.class, "#feec30"); // yellow
52          colors.put(BridgeEvent.class, "#fff8ae"); // light yellow
53          colors.put(HangupEvent.class, "#ff6c17"); // orange
54  
55          try
56          {
57              writer = new PrintWriter(filename);
58          }
59          catch (IOException e)
60          {
61              e.printStackTrace();
62          }
63      }
64  
65      public static void main(String[] args) throws Exception
66      {
67          if (args.length != 3)
68          {
69              System.err.println("Usage: java org.asteriskjava.tools.HtmlEventTracer host username password");
70              System.exit(1);
71          }
72  
73          final HtmlEventTracer tracer;
74          final DefaultAsteriskServer server;
75  
76          tracer = new HtmlEventTracer();
77          server = new DefaultAsteriskServer(args[0], args[1], args[2]);
78          server.initialize();
79          server.getManagerConnection().addEventListener(tracer);
80  
81          System.err.println("Event tracer successfully started. Press Ctrl-C to write trace file and exit.");
82  
83          Runtime.getRuntime().addShutdownHook(new Thread()
84          {
85              @Override
86              public void run()
87              {
88                  tracer.write();
89                  server.shutdown();
90              }
91          }
92          );
93  
94          while(true)
95          {
96              Thread.sleep(1000);
97          }
98      }
99  
100     public void onManagerEvent(ManagerEvent event)
101     {
102         events.add(event);
103         System.out.println("> " + event);
104         for (String property : new String[]{"uniqueId", "uniqueId1", "uniqueId2", "srcUniqueId", "destUniqueId"})
105         {
106             String uniqueId;
107 
108             uniqueId = getProperty(event, property);
109             if (uniqueId != null && !uniqueIds.contains(uniqueId))
110             {
111                 uniqueIds.add(uniqueId);
112             }
113         }
114     }
115 
116     public void write()
117     {
118         writer.append("<table border='1'><tr><td> </td>");
119         for (String uniqueId : uniqueIds)
120         {
121             writer.append("<td><font size='-2'>");
122             writer.append(uniqueId.substring(0, uniqueId.lastIndexOf('.') + 1));
123             writer.append("</font>");
124             writer.append(uniqueId.substring(uniqueId.lastIndexOf('.') + 1, uniqueId.length()));
125             writer.append("</td>");
126         }
127         writer.append("</tr>");
128         writer.println("");
129 
130         for (ManagerEvent event : events)
131         {
132             boolean print = false;
133             StringBuilder line = new StringBuilder();
134 
135             line.append("<tr><td>");
136             line.append(getLocalName(event.getClass()));
137             line.append("<br><font size='-2'>");
138             line.append(event.getDateReceived());
139             line.append("</font></td>");
140             for (String uniqueId : uniqueIds)
141             {
142                 String text;
143                 text = getText(uniqueId, event);
144                 if (text == null)
145                 {
146                     line.append("<td> </td>");
147                 }
148                 else
149                 {
150                     String color = getColor(event.getClass());
151                     line.append("<td bgcolor='").append(color).append("'><tt>").append(text).append("</tt></td>");
152                     print = true;
153                 }
154             }
155             line.append("</tr>");
156             if (print)
157             {
158                 writer.println(line.toString());
159             }
160         }
161         writer.append("</table>");
162         writer.close();
163         System.err.println("Trace file successfully written to " + filename + ".");
164     }
165 
166     private String getColor(Class<? extends ManagerEvent> clazz)
167     {
168         for (Map.Entry<Class<? extends ManagerEvent>, String> entry : colors.entrySet())
169         {
170             if (entry.getKey().isAssignableFrom(clazz))
171             {
172                 return entry.getValue();
173             }
174         }
175         return "#ffffff";
176     }
177 
178     protected String getProperty(Object obj, String property)
179     {
180         try
181         {
182             BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
183             for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors())
184             {
185                 if (!propertyDescriptor.getName().equals(property))
186                 {
187                     continue;
188                 }
189 
190                 return propertyDescriptor.getReadMethod().invoke(obj).toString();
191             }
192         }
193         catch (Exception e)
194         {
195             System.err.println("Unable to read property '" + property + "' from object " + obj + ": " + e.getMessage());
196             return null;
197         }
198 
199         return null;
200     }
201 
202     protected String getLocalName(Class<?> c)
203     {
204         String s;
205 
206         s = c.getName();
207         return s.substring(s.lastIndexOf(".") + 1, s.length());
208     }
209 
210     protected String getText(String uniqueId, ManagerEvent event)
211     {
212         String format = null;
213         String[] properties = null;
214 
215         if (uniqueId.equals(getProperty(event, "uniqueId")))
216         {
217             if (event instanceof NewChannelEvent)
218             {
219                 format = "%s<br>%s";
220                 properties = new String[]{"channel", "state"};
221             }
222             else if (event instanceof NewStateEvent)
223             {
224                 format = "%s<br>%s";
225                 properties = new String[]{"channel", "state"};
226             }
227             else if (event instanceof NewExtenEvent)
228             {
229                 format = "%s,%s,%s<br>%s(%s)";
230                 properties = new String[]{"context", "extension", "priority", "application", "appData"};
231             }
232             else if (event instanceof RenameEvent)
233             {
234                 format = "old: %s<br>new: %s";
235                 properties = new String[]{"oldname", "newname"};
236             }
237             else if (event instanceof HoldEvent)
238             {
239                 format = "%s";
240                 properties = new String[]{"status"};
241             }
242             else if (event instanceof AbstractParkedCallEvent)
243             {
244                 format = "exten: %s<br>from: %s";
245                 properties = new String[]{"exten", "from"};
246             }
247             else if (event instanceof HangupEvent)
248             {
249                 format = "%s<br>%s (%s)";
250                 properties = new String[]{"channel", "cause", "causeTxt"};
251             }
252         }
253 
254         if (event instanceof BridgeEvent)
255         {
256             if (uniqueId.equals(getProperty(event, "uniqueId1")))
257             {
258                 format = "%s<br>%s<br>%s";
259                 properties = new String[]{"uniqueId2", "channel2", "bridgeState"};
260             }
261             else if (uniqueId.equals(getProperty(event, "uniqueId2")))
262             {
263                 format = "%s<br>%s<br>%s";
264                 properties = new String[]{"uniqueId1", "channel1", "bridgeState"};
265             }
266         }
267 
268         if (event instanceof DialEvent)
269         {
270             if (uniqueId.equals(getProperty(event, "srcUniqueId")))
271             {
272                 format = "To: %s";
273                 properties = new String[]{"destination"};
274             }
275             else if (uniqueId.equals(getProperty(event, "destUniqueId")))
276             {
277                 format = "From: %s";
278                 properties = new String[]{"src"};
279             }
280         }
281 
282         if (format != null)
283         {
284             String[] args = new String[properties.length];
285 
286             for (int i = 0; i < properties.length; i++)
287             {
288                 String value;
289 
290                 value = getProperty(event, properties[i]);
291                 if (value == null)
292                 {
293                     args[i] = "";
294                 }
295                 else
296                 {
297                     value = value.replace("<", "&lt;");
298                     value = value.replace(">", "&gt;");
299                     args[i] = value;
300                 }
301             }
302 
303             return String.format(format, (Object[]) args);
304         }
305         return null;
306     }
307 }