package org.apache.jxtadoop.hdfs.desktop; import java.awt.AWTException; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Image; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.TextArea; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jxtadoop.hdfs.server.datanode.DataNode; import org.apache.jxtadoop.hdfs.server.datanode.FSDatasetInterface; import org.apache.jxtadoop.util.StringUtils; /** * Used to manage the SystemTray in the Desktop if applicable. * Allow quit for DataNode */ public class DesktopTray extends Frame implements Runnable { /** * */ private static final long serialVersionUID = 2762054010389622504L; public static final Log LOG = LogFactory.getLog(DesktopTray.class); private TrayIcon trayIcon; private SystemTray tray; private TextArea dnInfoArea; private DataNode datanode; private FSDatasetInterface dndata; private int dnStatus = 0; // 0 - Init; 1 - Running; 2 - Starting private Thread desktopTrayThread; private Image startIcon, pendingIcon; private boolean shouldRun = false; private int trayHeight,trayWidth; private Class<?> dnClass; private String[] dnArgs; private org.apache.commons.logging.Log dnLog; public DesktopTray() { this(null); } public DesktopTray(DataNode d) { this.datanode = d; startIcon = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/icons/jx_started.png")); pendingIcon = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/icons/jx_stopped.png")); this.trayIcon = null; tray = SystemTray.getSystemTray(); } public void init(Class<?> clazz, String[] args, final org.apache.commons.logging.Log l) throws SecurityException { LOG.info("Initiliazing the Desktop Tray to control Datanode"); this.dnClass = clazz; this.dnArgs = args; this.dnLog = l; trayHeight = (int)tray.getTrayIconSize().getHeight(); trayWidth = (int)tray.getTrayIconSize().getWidth(); final Image scaledPending = pendingIcon.getScaledInstance(trayWidth, trayHeight, 0); ActionListener infoListener = new ActionListener() { public void actionPerformed(ActionEvent e) { if (datanode != null) showDNInfoArea(datanode); } }; ActionListener quitListener = new ActionListener() { public void actionPerformed(ActionEvent e) { if (datanode != null) datanode.shutdown(); shouldRun = false; System.exit(0); } }; PopupMenu popup = new PopupMenu(); MenuItem infoItem = new MenuItem("Info"); infoItem.addActionListener(infoListener); popup.add(infoItem); MenuItem quitItem = new MenuItem("Shutdown"); quitItem.addActionListener(quitListener); popup.add(quitItem); trayIcon = new TrayIcon(scaledPending, "Datanode Tray", popup); trayIcon.addActionListener(quitListener); this.shouldRun = true; this.desktopTrayThread = new Thread(this, "The Desktop tray Thread"); this.desktopTrayThread.start(); } private void setDesktopIconStart() { if (trayIcon != null) trayIcon.setImage(startIcon.getScaledInstance(trayWidth, trayHeight, 0)); } private void setDesktopIconPending() { if (trayIcon != null) trayIcon.setImage(pendingIcon.getScaledInstance(trayWidth, trayHeight, 0)); } public void setDatanode(DataNode d) { this.datanode = d; } private void showDNInfoArea(DataNode d) { if (dnInfoArea == null) dnInfoArea=new TextArea("",20,50,TextArea.SCROLLBARS_NONE); String info = ""; try { long capacity = dndata.getCapacity(); long dfsused = dndata.getDfsUsed(); long remaining = dndata.getRemaining(); long presentCapacity = dfsused + remaining; String storage = dndata.getStorageInfo(); info += "ID : "+datanode.machineName; info += "\n"; info += "\nStorage info : "+storage; info += "\n"; info += "\nConfigured Capacity: " + capacity + " (" + StringUtils.byteDesc(capacity) + ")"; info += "\nPresent Capacity: " + presentCapacity + " (" + StringUtils.byteDesc(presentCapacity) + ")"; info += "\nDFS Remaining: " + remaining + " (" + StringUtils.byteDesc(remaining) + ")"; info += "\nDFS Used: " + dfsused + " (" + StringUtils.byteDesc(dfsused) + ")"; info += "\nDFS Used%: " + StringUtils.limitDecimalTo2(((1.0 * dfsused) / presentCapacity) * 100) + "%"; } catch (IOException e) {} dnInfoArea.setText(info); dnInfoArea.setEditable(false); WindowAdapter wa = new WindowAdapter(){ public void windowClosing(WindowEvent e){ setVisible(false); } }; setName("Local Datanode Information"); add(dnInfoArea); setLayout(new FlowLayout()); pack(); setResizable(true); setVisible(true); addWindowListener(wa); } @Override public void run() { String msg = ""; try { tray.add(trayIcon); } catch (AWTException e) { LOG.error("Failed to add Desktop tray : "+e.getMessage()); } StringUtils.startupShutdownMessage(dnClass, dnArgs, dnLog); try { this.datanode = DataNode.createDataNode(dnArgs, null); } catch (IOException e) { LOG.error("Failed to create DataNode instance : "+e.getMessage()); } if (datanode != null) { synchronized(datanode) { dndata = datanode.data; try { while(shouldRun) { Thread.sleep(5000); if(datanode !=null) { msg = "dnStatus : "+this.dnStatus+";\t connected : "+(datanode.isConnectedToNN()); LOG.debug(msg); if(this.dnStatus == 0 && DataNode.isDatanodeUp(datanode)) { this.setDesktopIconStart(); this.dnStatus = 1; } else if (this.dnStatus == 1 && !datanode.isConnectedToNN()) { this.setDesktopIconPending(); this.dnStatus = 2; } else if (this.dnStatus == 2 && datanode.isConnectedToNN()) { this.setDesktopIconStart(); this.dnStatus = 1; } else if (this.dnStatus == 1) { this.setDesktopIconStart(); } } } } catch (InterruptedException ie) {} } } } }