1 package net.sourceforge.cruisecontrol.distributed.util; 2 3 import org.apache.log4j.Logger; 4 import net.jini.core.lookup.ServiceItem; 5 import net.sourceforge.cruisecontrol.distributed.BuildAgentService; 6 7 import javax.swing.JFrame ; 8 import javax.swing.JPanel ; 9 import javax.swing.JButton ; 10 import javax.swing.JTextArea ; 11 import javax.swing.JScrollPane ; 12 import javax.swing.JComboBox ; 13 import javax.swing.JCheckBox ; 14 import javax.swing.ComboBoxModel ; 15 import javax.swing.DefaultComboBoxModel ; 16 import javax.swing.text.BadLocationException ; 17 import javax.swing.SwingUtilities ; 18 import java.rmi.RemoteException ; 19 import java.awt.event.ActionListener ; 20 import java.awt.event.ActionEvent ; 21 import java.awt.event.WindowAdapter ; 22 import java.awt.event.WindowEvent ; 23 import java.awt.BorderLayout ; 24 import java.awt.Dimension ; 25 import java.awt.Font ; 26 import java.util.List ; 27 import java.util.ArrayList ; 28 29 36 public final class BuildAgentUtility { 37 private static final Logger LOG = Logger.getLogger(BuildAgentUtility.class); 38 39 private static final class UI extends JFrame { 41 private static final int CONSOLE_LINE_BUFFER_SIZE = 1000; 42 43 private final BuildAgentUtility buildAgentUtility; 44 private final JPanel northPanel; 45 private final JButton btnRefresh = new JButton ("Refresh"); 46 private final JComboBox cmbAgents = new JComboBox (); 47 private final JButton btnInvoke = new JButton ("Invoke"); 48 private static final String METH_RESTART = "restart"; 49 private static final String METH_KILL = "kill"; 50 private final JComboBox cmbRestartOrKill = new JComboBox (new String [] {METH_RESTART, METH_KILL}); 51 private final JCheckBox chkAfterBuildFinished = new JCheckBox ("Wait for build to finish.", true); 52 private final JButton btnInvokeOnAll = new JButton ("Invoke on All"); 53 private final JPanel pnlEdit = new JPanel (new BorderLayout ()); 54 private final JButton btnClose = new JButton ("Close"); 55 private final JTextArea txaConsole = new JTextArea (); 56 private final JScrollPane scrConsole = new JScrollPane (); 57 58 private UI(final BuildAgentUtility buildAgentUtil) { 59 super("CruiseControl Distributed - Build Agent Utility"); 60 61 buildAgentUtility = buildAgentUtil; 62 63 btnClose.addActionListener(new ActionListener () { 64 public void actionPerformed(final ActionEvent e) { 65 exitForm(); 66 } 67 }); 68 addWindowListener(new WindowAdapter () { 69 public void windowClosing(final WindowEvent evt) { 70 exitForm(); 71 } 72 }); 73 74 btnRefresh.addActionListener(new ActionListener () { 75 public void actionPerformed(final ActionEvent e) { 76 refreshAgentList(); 77 } 78 }); 79 80 cmbAgents.addActionListener(new ActionListener () { 81 public void actionPerformed(final ActionEvent e) { 82 btnInvoke.setEnabled(true); 83 } 84 }); 85 86 btnInvoke.setEnabled(false); 87 btnInvoke.addActionListener(new ActionListener () { 88 public void actionPerformed(final ActionEvent e) { 89 try { 90 invokeOnAgent( 91 ((ComboItemWrapper) cmbAgents.getSelectedItem()).getAgent() 92 ); 93 } catch (RemoteException e1) { 94 appendInfo(e1.getMessage()); 95 throw new RuntimeException (e1); 96 } 97 } 98 }); 99 100 btnInvokeOnAll.addActionListener(new ActionListener () { 101 public void actionPerformed(final ActionEvent e) { 102 for (int i = 0; i < cmbAgents.getItemCount(); i++) { 103 try { 104 invokeOnAgent(((ComboItemWrapper) cmbAgents.getItemAt(i)).getAgent()); 105 } catch (RemoteException e1) { 106 appendInfo(e1.getMessage()); 107 } 109 } 110 } 111 }); 112 113 txaConsole.setFont(new Font ("Courier New", 0, 12)); 114 115 scrConsole.setViewportView(txaConsole); 116 scrConsole.setPreferredSize(new Dimension (525, 300)); 117 118 119 getContentPane().setLayout(new BorderLayout ()); 120 final JPanel pnlNN = new JPanel (new BorderLayout ()); 121 pnlNN.add(btnRefresh, BorderLayout.WEST); 122 pnlNN.add(cmbAgents, BorderLayout.CENTER); 123 pnlNN.add(btnInvoke, BorderLayout.EAST); 124 125 final JPanel pnlNS = new JPanel (new BorderLayout ()); 126 pnlNS.add(btnClose, BorderLayout.EAST); 127 128 pnlEdit.add(cmbRestartOrKill, BorderLayout.WEST); 129 pnlEdit.add(chkAfterBuildFinished, BorderLayout.CENTER); 130 pnlEdit.add(btnInvokeOnAll, BorderLayout.EAST); 131 132 northPanel = new JPanel (new BorderLayout ()); 133 northPanel.add(pnlNN, BorderLayout.NORTH); 134 northPanel.add(pnlEdit, BorderLayout.CENTER); 135 northPanel.add(pnlNS, BorderLayout.SOUTH); 136 getContentPane().add(northPanel, BorderLayout.NORTH); 137 getContentPane().add(scrConsole, BorderLayout.CENTER); 138 pack(); 139 setVisible(true); 140 } 141 142 private void invokeOnAgent(final BuildAgentService agent) throws RemoteException { 143 if (METH_RESTART.equals(cmbRestartOrKill.getSelectedItem())) { 144 agent.restart(chkAfterBuildFinished.isSelected()); 145 } else { 146 agent.kill(chkAfterBuildFinished.isSelected()); 147 } 148 } 149 150 private static final class ComboItemWrapper { 151 private static ComboItemWrapper[] wrapArray(final ServiceItem[] serviceItems) { 152 final ComboItemWrapper[] result = new ComboItemWrapper[serviceItems.length]; 153 for (int i = 0; i < serviceItems.length; i++) { 154 result[i] = new ComboItemWrapper(serviceItems[i]); 155 } 156 return result; 157 } 158 159 private final ServiceItem serviceItem; 160 private ComboItemWrapper(final ServiceItem serviceItemToWrap) { 161 this.serviceItem = serviceItemToWrap; 162 } 163 public BuildAgentService getAgent() { 164 return (BuildAgentService) serviceItem.service; 165 } 166 public String toString() { 167 try { 168 return getAgent().getMachineName() + ": " + serviceItem.serviceID; 169 } catch (RemoteException e) { 170 return "Error: " + e.getMessage(); 171 } 172 } 173 } 174 175 private void refreshAgentList() { 176 btnRefresh.setEnabled(false); 177 btnInvoke.setEnabled(false); 178 btnInvokeOnAll.setEnabled(false); 179 cmbAgents.setEnabled(false); 180 new Thread () { 181 public void run() { 182 try { 183 final List tmpList = new ArrayList (); 184 final String agentInfoAll = buildAgentUtility.getAgentInfoAll(tmpList); 185 final ServiceItem[] serviceItems = (ServiceItem[]) tmpList.toArray(new ServiceItem[]{}); 186 final ComboBoxModel comboBoxModel = new DefaultComboBoxModel ( 187 ComboItemWrapper.wrapArray(serviceItems)); 188 SwingUtilities.invokeLater(new Runnable () { 189 public void run() { 190 cmbAgents.setModel(comboBoxModel); 191 } 192 }); 193 setInfo(agentInfoAll); 194 } finally { 195 SwingUtilities.invokeLater(new Runnable () { 196 public void run() { 197 btnRefresh.setEnabled(true); 198 btnInvokeOnAll.setEnabled(true); 199 cmbAgents.setEnabled(true); 200 } 201 }); 202 } 203 } 204 } .start(); 205 } 206 207 private static void exitForm() { 208 System.exit(0); 209 } 210 211 private void setInfo(final String infoText) { 212 LOG.debug(infoText); 213 SwingUtilities.invokeLater(new Runnable () { 214 public void run() { 215 txaConsole.setText(infoText); 216 } 217 }); 218 } 219 220 private void appendInfo(final String infoText) { 221 SwingUtilities.invokeLater(new Runnable () { 222 public void run() { 223 txaConsole.append(infoText + "\n"); 224 if (txaConsole.getLineCount() > CONSOLE_LINE_BUFFER_SIZE) { 225 try { 227 txaConsole.replaceRange("", 0, 228 txaConsole.getLineEndOffset( 229 txaConsole.getLineCount() - CONSOLE_LINE_BUFFER_SIZE 230 )); 231 } catch (BadLocationException e) { 232 ; } 234 } 235 txaConsole.setCaretPosition(txaConsole.getDocument().getLength()); 237 } 238 }); 239 240 } 241 } 242 243 private final UI ui; 244 245 246 private BuildAgentUtility() { 247 ui = new UI(this); 248 ui.btnRefresh.doClick(); 249 } 250 251 private String getAgentInfoAll(final List lstServiceItems) { 252 final String waitMessage = "Waiting 5 seconds for registrars to report in..."; 253 ui.setInfo(waitMessage); 254 LOG.info(waitMessage); 255 256 final StringBuffer result = new StringBuffer (); 257 try { 258 final MulticastDiscovery discovery = new MulticastDiscovery(null); 260 try { 261 Thread.sleep(5000); 262 } catch (InterruptedException e1) { 263 LOG.warn("Sleep interrupted", e1); 264 } 265 266 final ServiceItem[] serviceItems 267 = discovery.getLookupCache().lookup(MulticastDiscovery.FLTR_ANY, Integer.MAX_VALUE); 268 new Thread () { 270 public void run() { 271 discovery.terminate(); 272 } 273 } .start(); 274 275 for (int i = 0; i < lstServiceItems.size(); i++) { 277 lstServiceItems.remove(i); 278 } 279 for (int i = 0; i < serviceItems.length; i++) { 280 lstServiceItems.add(serviceItems[i]); 281 } 282 283 result.append("Found: " + serviceItems.length + " agents.\n"); 284 ServiceItem serviceItem; 285 BuildAgentService agent; 286 String agentInfo; 287 for (int x = 0; x < serviceItems.length; x++) { 288 serviceItem = serviceItems[x]; 289 agent = (BuildAgentService) serviceItem.service; 290 agentInfo = "Build Agent: " + serviceItem.serviceID + "\n" 291 + agent.asString() 292 + MulticastDiscovery.toStringEntries(serviceItem.attributeSets) 293 + "\n"; 294 LOG.debug(agentInfo); 295 result.append(agentInfo); 296 } 297 } catch (RemoteException e) { 298 final String message = "Search failed due to an unexpected error"; 299 LOG.error(message, e); 300 throw new RuntimeException (message, e); 301 } 302 303 return result.toString(); 304 } 305 306 public static void main(final String [] args) { 307 new BuildAgentUtility(); 308 } 309 } 310 | Popular Tags |