1 37 38 package net.sourceforge.cruisecontrol.distributed.util; 39 40 import java.io.BufferedReader ; 41 import java.io.File ; 42 import java.io.IOException ; 43 import java.io.InputStream ; 44 import java.io.InputStreamReader ; 45 import java.rmi.RemoteException ; 46 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.Properties ; 49 50 import net.jini.core.lookup.ServiceItem; 51 import net.jini.core.entry.Entry; 52 import net.sourceforge.cruisecontrol.CruiseControlException; 53 import net.sourceforge.cruisecontrol.PluginXMLHelper; 54 import net.sourceforge.cruisecontrol.ProjectXMLHelper; 55 import net.sourceforge.cruisecontrol.builders.DistributedMasterBuilder; 56 import net.sourceforge.cruisecontrol.distributed.BuildAgentService; 57 import net.sourceforge.cruisecontrol.util.Util; 58 59 import org.apache.log4j.Logger; 60 import org.jdom.Attribute; 61 import org.jdom.Element; 62 import org.jdom.output.XMLOutputter; 63 64 public class InteractiveBuildUtility { 65 66 private static final Logger LOG = Logger.getLogger(InteractiveBuildUtility.class); 67 68 private static Console console = new Console(System.in); 69 private String searchEntries; 70 private Element distributedBuilderElement; 71 72 public InteractiveBuildUtility() { 73 System.out.print("Enter path to Cruise Control configuration file: "); 74 String configFilePath = console.readLine(); 75 new InteractiveBuildUtility(configFilePath); 76 } 77 78 public InteractiveBuildUtility(String configFilePath) { 79 File configFile = new File (configFilePath); 80 if (!configFile.exists() || configFile.isDirectory()) { 81 String message = configFilePath + " does not exist or is a directory - quitting..."; 82 System.err.println(message); 83 LOG.error(message); 84 System.exit(1); 85 } 86 Element project = getProjectFromConfig(configFile); 87 distributedBuilderElement = getBuilderFromProject(project); 88 ServiceItem[] serviceItems = findAgents(distributedBuilderElement.getAttribute("entries")); 89 final BuildAgentService agent = selectAgent(serviceItems); 90 doBuild(); 91 retrieveResults(agent); 92 } 93 94 private Element getProjectFromConfig(File configFile) { 95 Element rootElement = null; 96 Element project = null; 97 try { 98 rootElement = Util.loadConfigFile(configFile); 99 } catch (CruiseControlException e) { 100 System.err.println(e.getMessage()); 101 LOG.error(e.getMessage(), e); 102 System.exit(1); 103 } 104 List projects = rootElement.getChildren("project"); 105 if (projects.size() == 0) { 106 String message = "No projects found in configuration file at " + configFile.getAbsolutePath() 107 + " - quitting..."; 108 System.err.println(message); 109 LOG.error(message); 110 System.out.println(); 111 System.exit(1); 112 } else if (projects.size() == 1) { 113 project = (Element) projects.get(0); 114 String message = "Found one project--using '" + project.getAttributeValue("name") + "'"; 115 System.out.println(message); 116 LOG.info(message); 117 System.out.println(); 118 } else { 119 System.out.println("Found multiple projects in configuration file:"); 120 Iterator iter = projects.iterator(); 121 for (int i = 0; iter.hasNext(); i++) { 122 Element tempProject = (Element) iter.next(); 123 System.out.println(i + 1 + ") " + tempProject.getAttributeValue("name")); 124 LOG.debug("Found project: " + tempProject.getAttributeValue("name")); 125 } 126 System.out.print("Select project number: "); 127 int projectNumber = Integer.parseInt(console.readLine()); 128 if ((projectNumber > projects.size()) || (projectNumber < 1)) { 129 String message = "Not a valid project number - quitting..."; 130 System.err.println(message); 131 LOG.error(message); 132 System.exit(1); 133 } 134 project = (Element) projects.get(projectNumber - 1); 135 System.out.println(); 136 } 137 return project; 138 } 139 140 private Element getBuilderFromProject(Element project) { 141 Element builder = null; 142 List schedules = project.getChildren("schedule"); 143 if (schedules.size() == 0) { 144 String message = "No schedule for project -- quitting..."; 145 System.err.println(message); 146 LOG.error(message); 147 System.exit(1); 148 } else if (schedules.size() > 1) { 149 String message = "More than one schedule for project -- quitting..."; 150 System.err.println(message); 151 LOG.error(message); 152 System.exit(1); 153 } else { 154 List builders = ((Element) schedules.get(0)).getChildren(); 155 if (builders.size() == 0) { 156 String message = "No builder for project -- quitting..."; 157 System.err.println(message); 158 LOG.error(message); 159 System.exit(1); 160 } else if (builders.size() > 1) { 161 String message = "Multiple builders found -- defaulting to first builder"; 162 System.out.println(message); 163 LOG.warn(message); 164 } 165 builder = (Element) builders.get(0); 166 } 167 return builder; 168 } 169 170 private ServiceItem[] findAgents(Attribute configEntries) { 171 if (configEntries == null) { 172 System.out.println("Enter search entries as comma-separated name/value pairs " 173 + "(e.g. \"os.name=WinNT, fixpack=4.1\")"); 174 System.out.print("Search entries: "); 175 searchEntries = console.readLine(); 176 } else { 177 searchEntries = configEntries.getValue(); 178 } 179 LOG.debug("Searching for serviceItems matching entries: " + searchEntries); 180 Entry[] entries = ReggieUtil.convertStringEntries(searchEntries); 181 final MulticastDiscovery discovery = new MulticastDiscovery(entries); 182 ServiceItem[] serviceItems = discovery.getLookupCache().lookup(MulticastDiscovery.FLTR_ANY, Integer.MAX_VALUE); 183 if (serviceItems.length == 0) { 184 String message = "No matches for your search - quitting..."; 185 System.err.println(message); 186 System.out.println(); 187 LOG.error(message); 188 System.exit(1); 189 } 190 System.out.println(); 191 return serviceItems; 192 } 193 194 private BuildAgentService selectAgent(final ServiceItem[] serviceItems) { 195 BuildAgentService agent = null; 196 197 if (serviceItems.length < 1) { 198 String message = "No matching serviceItems found - quitting..."; 199 LOG.error(message); 200 System.err.println(message); 201 System.exit(1); 202 } else if (serviceItems.length == 1) { 203 agent = (BuildAgentService) serviceItems[0].service; 204 String agentName = null; 205 try { 206 agentName = agent.getMachineName(); 207 } catch (RemoteException e) { 208 String message = "Error getting machine name from agent - quitting..."; 209 System.err.println(message); 210 LOG.error(message, e); 211 System.exit(1); 212 } 213 String infoMessage = "One matching agent found: " + agentName + " -- selecting it automatically"; 214 System.out.println(infoMessage); 215 LOG.debug(infoMessage); 216 System.out.println(); 217 } else { 218 System.out.println("Found serviceItems:"); 219 String machineName = null; 220 for (int i = 0; i < serviceItems.length; i++) { 221 try { 222 machineName = ((BuildAgentService) serviceItems[i].service).getMachineName(); 223 System.out.println(i + 1 + ") " + machineName); 224 LOG.debug("Found agent: " + machineName); 225 } catch (RemoteException e1) { 226 String message = "Couldn't get machine name for agent - quitting..."; 227 LOG.error(message, e1); 228 System.err.println(message + " - " + e1.getMessage()); 229 System.exit(1); 230 } 231 } 232 System.out.print("Select agent # or 0 to list status of all serviceItems: "); 233 int agentNum = Integer.parseInt(console.readLine()); 234 if ((agentNum > serviceItems.length) || (agentNum < 0)) { 235 agent = null; 236 String message = "Not a valid agent number - quitting..."; 237 System.err.println(message); 238 LOG.error(message); 239 System.exit(1); 240 } 241 if (agentNum == 0) { 242 displayAgentStatuses(); 243 System.out.println("Done..."); 244 System.exit(0); 245 } else { 246 agent = (BuildAgentService) serviceItems[agentNum - 1].service; 247 System.out.println(); 248 } 249 } 250 return agent; 251 } 252 253 private void displayAgentStatuses() { 254 System.out.println(); 256 System.err.println("Unimplemented feature - quitting..."); 257 } 258 259 private void doBuild() { 260 261 System.out.println("Beginning build..."); 262 System.out.println(); 263 ProjectXMLHelper projectXMLHelper = new ProjectXMLHelper(); 264 PluginXMLHelper pluginXMLHelper = new PluginXMLHelper(projectXMLHelper); 265 266 try { 267 DistributedMasterBuilder distributedBuildMaster = (DistributedMasterBuilder) pluginXMLHelper.configure( 268 distributedBuilderElement, DistributedMasterBuilder.class, false); 269 XMLOutputter xmlOutputter = new XMLOutputter(); 270 xmlOutputter.output(distributedBuildMaster.build(new Properties ()), System.out); 271 } catch (CruiseControlException e) { 272 String message = "Oops..."; 273 LOG.error(message, e); 274 System.err.println(message + " - " + e.getMessage()); 275 } catch (IOException e) { 276 String message = "Oops..."; 277 LOG.error(message, e); 278 System.err.println(message + " - " + e.getMessage()); 279 } 280 System.out.println(); 281 } 282 283 private void retrieveResults(final BuildAgentService agent) { 284 String resultsType = PropertiesHelper.RESULT_TYPE_LOGS; 285 try { 286 DistributedMasterBuilder.getResultsFiles(agent, PropertiesHelper.RESULT_TYPE_LOGS, 287 ".", "resultsInteractive"); 288 DistributedMasterBuilder.getResultsFiles(agent, PropertiesHelper.RESULT_TYPE_OUTPUT, 289 ".", "resultsInteractive"); 290 agent.clearOutputFiles(); 291 } catch (RemoteException e) { 292 String message = "Problem occurred getting or unzipping results"; 293 LOG.debug(message); 294 System.out.println(message); 295 } 296 } 297 298 public static void main(String [] args) { 299 if (args.length == 0) { 300 new InteractiveBuildUtility(); 301 } else { 302 new InteractiveBuildUtility(args[0]); 303 } 304 } 305 306 public static class Console { 307 private InputStream inputStream = null; 308 309 public Console(InputStream in) { 310 this.inputStream = in; 311 } 312 313 public String readLine() { 314 BufferedReader in = new BufferedReader (new InputStreamReader (inputStream)); 315 try { 316 return in.readLine().trim(); 317 } catch (IOException e) { 318 String message = "Error reading input"; 319 LOG.error(message, e); 320 System.err.println(message + " - " + e.getMessage()); 321 throw new RuntimeException (message, e); 322 } 323 } 324 } 325 } 326 | Popular Tags |