1 19 20 package org.apache.jmeter.module.integration; 21 22 import java.awt.Component ; 23 import java.awt.Image ; 24 import java.io.BufferedInputStream ; 25 import java.io.File ; 26 import java.io.FileInputStream ; 27 import java.io.FilenameFilter ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.net.URL ; 31 import java.util.ArrayList ; 32 import java.util.Collection ; 33 import java.util.Collections ; 34 import java.util.Iterator ; 35 import java.util.LinkedList ; 36 import java.util.List ; 37 import java.util.Locale ; 38 import java.util.Map ; 39 import java.util.WeakHashMap ; 40 import java.util.concurrent.Semaphore ; 41 import javax.swing.JPopupMenu ; 42 43 import org.apache.jmeter.engine.JMeterEngine; 44 import org.apache.jmeter.engine.StandardJMeterEngine; 45 import org.apache.jmeter.engine.TreeCloner; 46 import org.apache.jmeter.engine.event.LoopIterationEvent; 47 import org.apache.jmeter.module.JMXTypeDataNode; 48 import org.apache.jmeter.module.exceptions.InitializationException; 49 import org.apache.jmeter.module.loadgenerator.spi.impl.ProcessDescriptor; 50 import org.apache.jmeter.reporters.ResultCollector; 51 import org.apache.jmeter.save.SaveService; 52 import org.apache.jmeter.testelement.TestElement; 53 import org.apache.jmeter.testelement.TestListener; 54 import org.apache.jmeter.testelement.TestPlan; 55 import org.apache.jmeter.util.JMeterUtils; 56 import org.apache.jmeter.visualizers.Visualizer; 57 import org.apache.jorphan.collections.HashTree; 58 import org.apache.jorphan.collections.HashTreeTraverser; 59 import org.openide.filesystems.FileAttributeEvent; 60 import org.openide.filesystems.FileChangeListener; 61 import org.openide.filesystems.FileEvent; 62 import org.openide.filesystems.FileObject; 63 import org.openide.filesystems.FileRenameEvent; 64 import org.openide.filesystems.FileUtil; 65 import org.openide.modules.InstalledFileLocator; 66 import org.openide.util.Utilities; 67 68 72 public class JMeterIntegrationEngine { 73 private static JMeterIntegrationEngine instance; 74 75 private static Semaphore instanceLock = new Semaphore (1); 76 private Semaphore parserLock = new Semaphore (1); 77 78 private Map <String , HashTree> testPlans; 79 80 private Collection <ProcessDescriptor> processes; 81 82 private static String jmeterPath; 83 84 private class TestProcessListener implements TestListener { 85 private ProcessDescriptor descriptor = null; 86 87 public TestProcessListener(final ProcessDescriptor process) { 88 descriptor = process; 89 } 90 91 public void testStarted(String string) { 92 descriptor.setRunning(true); 93 } 94 95 public void testEnded(String string) { 96 descriptor.setRunning(false); 97 } 98 99 public void testIterationStart(LoopIterationEvent loopIterationEvent) { 100 } 101 102 public void testStarted() { 103 descriptor.setRunning(true); 104 } 105 106 public void testEnded() { 107 descriptor.setRunning(false); 108 } 109 110 } 111 112 private static String jmeterCP = System.getProperty("java.class.path"); 113 114 115 private JMeterIntegrationEngine() { 116 testPlans = new WeakHashMap <String , HashTree>(); 117 processes = Collections.synchronizedCollection(new ArrayList <ProcessDescriptor>()); 118 } 119 120 123 public static JMeterIntegrationEngine getDefault() throws InitializationException { 124 if (instance == null) { 125 try { 126 instanceLock.acquire(); 127 if (instance == null) { 128 instance = new JMeterIntegrationEngine(); 129 instance.initJMeter(); 130 } 131 } catch (InterruptedException ex) { 132 ex.printStackTrace(); 133 throw new InitializationException(); 134 } catch (Exception e) { 135 e.printStackTrace(); 136 } finally { 137 instanceLock.release(); 138 } 139 } 140 141 String classpath = System.getProperty("java.class.path"); 142 if (classpath.indexOf("ApacheJMeter_core") == -1) { 143 System.setProperty("java.class.path", classpath + File.pathSeparator + jmeterCP); 144 } 145 return instance; 146 } 147 148 public List <TestElement> getChildren(final TestElement parent, final String testPlan) { 149 List <TestElement> children = new ArrayList <TestElement>(); 150 151 for(Object elementObj : getPlanTree(testPlan, false).list(parent)) { 152 children.add((TestElement)elementObj); 153 } 154 155 return children; 156 } 157 158 public List <TestElement> getChildren(final List <TestElement> elementPath, final String testPlan) { 159 List <TestElement> children = new ArrayList <TestElement>(); 160 161 for(Object elementObj : getPlanTree(testPlan, false).list(elementPath)) { 162 children.add((TestElement)elementObj); 163 } 164 165 return children; 166 } 167 168 public TestElement getRoot(final String testPlan) { 169 HashTree planTree = getPlanTree(testPlan, false); 170 171 return (TestElement)planTree.getArray()[0]; 172 } 173 174 public ProcessDescriptor runTestPlan(final String testPlan) { 175 HashTree planTree = getPlanTree(testPlan, true); 176 TestElement root = getRoot(testPlan); 177 178 JMeterEngine engine = new StandardJMeterEngine(); 179 180 planTree.traverse(new HashTreeTraverser() { 181 public void addNode(Object object, HashTree hashTree) { 182 if (object instanceof TestElement) { 183 if (object instanceof ResultCollector) { 184 ResultCollector collector = (ResultCollector)object; 185 collector.setListener((Visualizer)getElementCustomizer(collector)); 186 } 187 } 188 } 189 public void processPath() { 190 } 191 public void subtractNode() { 192 } 193 }); 194 195 TreeCloner cloner = new TreeCloner(false); 196 planTree.traverse(cloner); 197 198 ProcessDescriptor process = new ProcessDescriptor(engine, testPlan, root.getPropertyAsString(TestElement.NAME), true); 199 HashTree runtimeTree = cloner.getClonedTree(); 200 201 runtimeTree.add(new TestProcessListener(process)); 202 203 engine.configure(runtimeTree); 204 try { 205 engine.runTest(); 206 processes.add(process); 207 } catch (Exception e) { 208 e.printStackTrace(); 209 process = null; 210 } 211 212 return process; 213 } 214 215 public ProcessDescriptor prepareTest(final String testPlan) { 216 HashTree planTree = getPlanTree(testPlan, true); 217 TestElement root = getRoot(testPlan); 218 219 JMeterEngine engine = new StandardJMeterEngine(); 220 221 planTree.traverse(new HashTreeTraverser() { 222 public void addNode(Object object, HashTree hashTree) { 223 if (object instanceof TestElement) { 224 if (object instanceof ResultCollector) { 225 ResultCollector collector = (ResultCollector)object; 226 collector.setListener((Visualizer)getElementCustomizer(collector)); 227 } 228 } 229 } 230 public void processPath() { 231 } 232 public void subtractNode() { 233 } 234 }); 235 236 TreeCloner cloner = new TreeCloner(false); 237 planTree.traverse(cloner); 238 239 ProcessDescriptor process = new ProcessDescriptor(engine, testPlan, root.getPropertyAsString(TestElement.NAME), true); 240 HashTree runtimeTree = cloner.getClonedTree(); 241 242 TestPlan plan = (TestPlan)runtimeTree.getArray()[0]; 243 Map userVariables = plan.getUserDefinedVariables(); 244 245 if (userVariables.containsKey("nb.enabled")) { 246 process.setNbReady(true); 247 process.setThreadsCount(Integer.parseInt((String )userVariables.get("nb.users"))); 248 process.setRampup(Integer.parseInt((String )userVariables.get("nb.rampup"))); 249 process.setInterleave(Integer.parseInt((String )userVariables.get("nb.interleave"))); 250 } 251 252 runtimeTree.add(runtimeTree.getArray()[0], new TestProcessListener(process)); 253 engine.configure(runtimeTree); 254 255 return process; 256 } 257 258 public void runTestPlan(final ProcessDescriptor descriptor) { 259 try { 260 descriptor.getEngine().runTest(); 261 } catch (Exception e) { 262 e.printStackTrace(); 263 } 264 } 265 266 public void stopTestPlan(final ProcessDescriptor descriptor) { 267 descriptor.getEngine().stopTest(); 268 } 269 270 public Collection <ProcessDescriptor> getProcesses() { 271 Collection <ProcessDescriptor> result = new ArrayList <ProcessDescriptor>(); 272 result.addAll(processes); 273 274 return result; 275 } 276 277 public Component getElementCustomizer(final TestElement element) { 278 return JMeterGUISupport.getDefault().getGui(element); 279 } 280 281 public Image getElementIcon(final TestElement element) { 282 return JMeterGUISupport.getDefault().getIcon(element); 283 } 284 285 public JPopupMenu getElementMenu(final TestElement element) { 286 return JMeterGUISupport.getDefault().getPopup(element); 287 } 288 289 public void add(final List <TestElement> parentPath, final TestElement child, final String testPlan) { 290 HashTree planTree = getPlanTree(testPlan, false); 291 HashTree newTree = planTree.getTree(parentPath); 292 293 if (planTree != null) { 294 planTree.getTree(parentPath).add(child); 295 } 296 } 297 298 public HashTree getPlanTree(final String testPlan, final boolean forceReload) { 299 HashTree planTree = forceReload ? null : testPlans.get(testPlan); 300 301 if (planTree == null) { 302 try { 303 parserLock.acquire(); 304 if (planTree == null) { 305 planTree = parseJMeterTree(testPlan); 306 testPlans.put(testPlan, planTree); 307 } 308 } catch (InterruptedException e) { 309 e.printStackTrace(); 310 } finally { 311 parserLock.release(); 312 } 313 } 314 315 return planTree; 316 } 317 318 public Process externalEdit(final String scriptPath) throws IOException { 319 final String jmeterRoot = jmeterPath + File.separator + "bin"; 321 final String jmeterExecutable = jmeterRoot + File.separator + "jmeter" + (Utilities.isWindows() ? ".bat" : ""); 322 323 String [] params = null; 324 System.out.println("Userdir = " + jmeterRoot); 325 System.out.println("Scirptpath = " + decoratePath(scriptPath)); 326 327 if (Utilities.isWindows()) { 328 params = new String []{ 329 jmeterExecutable, 330 "-t", 331 decoratePath(scriptPath) 332 }; 333 } else { 334 params = new String []{ 335 "sh", 336 jmeterExecutable, 337 "-t", 338 decoratePath(scriptPath) 339 }; 340 } 341 return Runtime.getRuntime().exec(params,null,new File (jmeterRoot)); 342 } 343 344 public void cleanup() { 345 Iterator <ProcessDescriptor> iter = processes.iterator(); 346 while(iter.hasNext()) { 347 ProcessDescriptor desc = iter.next(); 348 if (!desc.isRunning()) { 349 iter.remove(); 350 } 351 } 352 } 353 354 public static String getLogPath() { 355 return JMeterUtils.getJMeterHome() + File.separator + "summariser.log"; } 357 358 public static void clearLog() { 359 } 371 372 375 private static void initJMeter() throws InitializationException { 376 URL rsrc = JMXTypeDataNode.class.getResource("/org/apache/jmeter/JMeter.class"); 379 File userDir = InstalledFileLocator.getDefault().locate("modules/jmeter/bin/jmeter.properties", "org.apache.jmeter.module", false); try { 381 jmeterPath = userDir.getCanonicalPath(); 382 System.out.println("Calculated JMeter path = " + jmeterPath); 383 jmeterPath = jmeterPath.substring(0, jmeterPath.lastIndexOf("modules" + File.separator + "jmeter") + ("modules" + File.separator + "jmeter").length()); System.out.println("Modified JMeter path = " + jmeterPath); 385 JMeterUtils.setJMeterHome(jmeterPath); 389 final String extPath = jmeterPath + File.separator + "lib" + File.separator + "ext"; 391 File dir = new File (extPath); 392 String [] jars = dir.list(new FilenameFilter () { 393 public boolean accept(File f, String name) { 394 if (name.endsWith(".jar")) { 395 return true; 396 } 397 return false; 398 } 399 }); 400 String classPath = System.getProperty("java.class.path"); 401 String separator = System.getProperty("path.separator"); 402 403 StringBuffer newClassPath = new StringBuffer (); 404 for(String jar : jars) { 405 newClassPath.append(separator).append(extPath).append(File.separator).append(jar); 406 } 407 jmeterCP = newClassPath.toString(); 408 409 JMeterUtils.getProperties(userDir.getCanonicalPath()); 411 JMeterUtils.setLocale(Locale.getDefault()); 414 } catch (IOException e) { 416 throw new InitializationException(e); 417 } 418 } 419 420 private HashTree parseJMeterTree(final String planPath) { 421 FileObject planFile = FileUtil.toFileObject(new File (planPath)); 422 return parseJMeterTree(planFile); 423 } 424 425 private HashTree parseJMeterTree(final FileObject file) { 426 InputStream planInputStream = null; 427 HashTree rootTree = null; 428 try { 429 planInputStream = new BufferedInputStream (new FileInputStream (FileUtil.toFile(file))); 430 rootTree = SaveService.loadTree(planInputStream); 431 432 convertSubTree(rootTree); 434 435 } catch (Exception e) { 436 e.printStackTrace(); 437 } 438 439 return rootTree; 440 } 441 442 private void convertSubTree(HashTree tree) { 444 Iterator iter = new LinkedList (tree.list()).iterator(); 445 while (iter.hasNext()) { 446 TestElement item = (TestElement) iter.next(); 447 if (!item.isEnabled() || item instanceof ResultCollector) { 448 tree.remove(item); 449 } else { 450 if (item instanceof TestPlan) { 451 TestPlan tp = (TestPlan) item; 452 tp.setFunctionalMode(tp.isFunctionalMode()); 453 tp.setSerialized(tp.isSerialized()); 454 } 455 convertSubTree(tree.getTree(item)); 456 } 457 } 458 } 459 460 private String decoratePath(final String path) { 461 if (Utilities.isWindows() && path.indexOf(' ') > -1) { 462 return "\"" + path + "\""; 463 } 464 return path; 465 } 466 } 467 | Popular Tags |