├── JMeterRestSampler
├── build.properties
├── properties
│ └── fabrizio.properties
├── CHANGELOG
├── .project
├── .settings
│ └── org.eclipse.jdt.core.prefs
├── src
│ └── main
│ │ └── java
│ │ └── smartrics
│ │ └── jmeter
│ │ ├── ant
│ │ ├── Property.java
│ │ ├── Arg.java
│ │ ├── SuccessParser.java
│ │ ├── DataExtractor.java
│ │ ├── JMeterTaskExt.java
│ │ ├── ChartGenerator.java
│ │ └── JMeterTask.java
│ │ └── sampler
│ │ ├── gui
│ │ ├── SaveGraphListener.java
│ │ ├── JmxGraphPanel.java
│ │ ├── JmxPanel.java
│ │ ├── JmxGui.java
│ │ ├── JmxVisualizer.java
│ │ ├── SaveChartFilePanel.java
│ │ ├── RestGui.java
│ │ └── ChartWrapper.java
│ │ ├── MyRequestEntity.java
│ │ ├── JmxSampleResult.java
│ │ ├── SaveGraphUtil.java
│ │ ├── jmx
│ │ └── MemUsageJmxClient.java
│ │ ├── JmxSampler.java
│ │ └── RestSampler.java
├── README
├── build.xml
├── bsd.license
├── .classpath
├── ant-jmeter-1.0.9.license
└── etc
│ └── Rest Sampler.jmx
├── .gitignore
└── README
/JMeterRestSampler/build.properties:
--------------------------------------------------------------------------------
1 | jmeter.home=/opt/java/jakarta-jmeter
2 |
--------------------------------------------------------------------------------
/JMeterRestSampler/properties/fabrizio.properties:
--------------------------------------------------------------------------------
1 | jmeter.home=C:/opt/jakarta-jmeter-2.3.4
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | JMeterRestSampler/JMeterRestSampler.build.log
2 | JMeterRestSampler/bin/
3 | JMeterRestSampler/build/
4 |
5 |
--------------------------------------------------------------------------------
/JMeterRestSampler/CHANGELOG:
--------------------------------------------------------------------------------
1 | Version 0.1 - 31/01/2010
2 | - JMeterRestSampler, moved in his own repository/project on googlecode.
3 |
--------------------------------------------------------------------------------
/JMeterRestSampler/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | JMeterRestSampler
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/JMeterRestSampler/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Wed Dec 10 09:23:09 GMT 2008
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.5
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12 | org.eclipse.jdt.core.compiler.source=1.5
13 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/ant/Property.java:
--------------------------------------------------------------------------------
1 | package smartrics.jmeter.ant;
2 |
3 | public class Property {
4 | private String name = "";
5 | private String value = "";
6 |
7 | public void setName(String arg) {
8 | name = arg.trim();
9 | }
10 |
11 | public String getName() {
12 | return name;
13 | }
14 |
15 | public void setValue(String arg) {
16 | value = arg.trim();
17 | }
18 |
19 | public String getValue() {
20 | return value;
21 | }
22 |
23 | public boolean isValid() {
24 | return (!name.equals("") && !value.equals(""));
25 | }
26 |
27 | public String toString() {
28 | return name + "=" + value;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/SaveGraphListener.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.sampler.gui;
15 |
16 |
17 | public interface SaveGraphListener {
18 | public void saveGraphPressed(String filename);
19 | }
20 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/ant/Arg.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 Joseph Fifield
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package smartrics.jmeter.ant;
17 |
18 | public class Arg {
19 | private String value;
20 |
21 | public void setValue(String arg) {
22 | value = arg;
23 | }
24 |
25 | public String getValue() {
26 | return value;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | - Build
2 | Add a properties/${user.name}.properties file and define the jmeter.home property. Then run ant.
3 | ${user.name} is the username of the logged in user.
4 | This code has been tested with JMeter 2.3.4 (http://archive.apache.org/dist/jakarta/jmeter/binaries/jakarta-jmeter-2.3.4.tgz)
5 |
6 | - Install
7 | Edit the ${jmeter.home}/bin/user.properties and set the searh_paths property to the location of the JMeterRestSampler.java file:
8 | search_paths=/path/to/JMeterRestSampler.jar
9 | Alternatively, copy the JMeterRestSampler.jar in the directory ${jmeter.home}/lib/ext
10 |
11 | If installation is successful, when starting JMeter, the Rest Sampler and JMX Sampler should be available in the Add/Sampler ThreadGroup context popup menu.
12 |
13 | - Eclipse project
14 | To successfully compile the project within Eclipse, once imported, you need to define two workspace
15 | variables: JMETER_HOME and ANT_HOME to respectively point to your JMeter home and Ant home directories.
16 |
17 | - License
18 | The software is licensed using a BSD license.
19 |
20 | - Disclaimer
21 | JMeterRestSampler is no more than a toy to prove the concept of Robustness testing via JMeter.
22 | I am not intentioned to improve it in the foreseeable future.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/JMeterRestSampler/README:
--------------------------------------------------------------------------------
1 | - Build
2 | Add a properties/${user.name}.properties file and define the jmeter.home property. Then run ant.
3 | ${user.name} is the username of the logged in user.
4 | This code has been tested with JMeter 2.3.4 (http://archive.apache.org/dist/jakarta/jmeter/binaries/jakarta-jmeter-2.3.4.tgz)
5 |
6 | - Install
7 | Edit the ${jmeter.home}/bin/user.properties and set the searh_paths property to the location of the JMeterRestSampler.java file:
8 | search_paths=/path/to/JMeterRestSampler.jar
9 | Alternatively, copy the JMeterRestSampler.jar in the directory ${jmeter.home}/lib/ext
10 |
11 | If installation is successful, when starting JMeter, the Rest Sampler and JMX Sampler should be available in the Add/Sampler ThreadGroup context popup menu.
12 |
13 | - Eclipse project
14 | To successfully compile the project within Eclipse, once imported, you need to define two workspace
15 | variables: JMETER_HOME and ANT_HOME to respectively point to your JMeter home and Ant home directories.
16 |
17 | - License
18 | The software is licensed using a BSD license.
19 |
20 | - Disclaimer
21 | JMeterRestSampler is no more than a toy to prove the concept of Robustness testing via JMeter.
22 | I am not intentioned to improve it in the foreseeable future.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/JMeterRestSampler/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/JMeterRestSampler/bsd.license:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009, Fabrizio Cannizzo
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 | * The names of the author may not be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
24 | OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/ant/SuccessParser.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.ant;
15 |
16 | import java.io.File;
17 |
18 | import org.apache.jmeter.samplers.SampleResult;
19 |
20 | import smartrics.jmeter.sampler.JmxSampleResult;
21 |
22 | /**
23 | * Parses the jtl file and accumulates successes and total sample results passed
24 | * (JmxSampleResults are skipped as they are not part of the actual test)
25 | */
26 | public class SuccessParser extends DataExtractor {
27 |
28 | private int successes = 0;
29 |
30 | private int total = 0;
31 |
32 | public SuccessParser(File jtlFile) {
33 | super(jtlFile);
34 | }
35 |
36 | public void handle(SampleResult res) {
37 | if (!(res instanceof JmxSampleResult)) {
38 | total++;
39 | if (res.isSuccessful()) {
40 | successes++;
41 | }
42 | }
43 | }
44 | public int getSuccesses() {
45 | return successes;
46 | }
47 |
48 | public int getTotal() {
49 | return total;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/MyRequestEntity.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler;
16 |
17 | import java.io.IOException;
18 | import java.io.OutputStream;
19 | import java.io.PrintWriter;
20 |
21 | import org.apache.commons.httpclient.methods.RequestEntity;
22 |
23 | /**
24 | * Holds the body content of a PUT/POST as requested by the apache HttpClient.
25 | */
26 | public class MyRequestEntity implements RequestEntity {
27 |
28 | private String data;
29 | private String contentType;
30 |
31 | public MyRequestEntity(String data) {
32 | this("text/xml", data);
33 | }
34 |
35 | public MyRequestEntity(String type, String data) {
36 | this.data = data;
37 | this.contentType = type;
38 | }
39 |
40 | public boolean isRepeatable() {
41 | return true;
42 | }
43 |
44 | public void writeRequest(OutputStream out) throws IOException {
45 | PrintWriter printer = new PrintWriter(out);
46 | printer.print(data);
47 | printer.flush();
48 | }
49 |
50 | public long getContentLength() {
51 | // so we don't generate chunked encoding
52 | return data.getBytes().length;
53 | }
54 |
55 | public String getContentType() {
56 | return contentType;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/JmxSampleResult.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler;
16 |
17 | import org.apache.jmeter.samplers.SampleResult;
18 |
19 | /**
20 | * The result of a sample on a JMX server.
21 | *
22 | * It's a hack as it contains not only the results but also some other data like
23 | * the path to the file where to save the graph. the reason for that is that the
24 | * file name (and the saveGraph flag) must be set in the sampler to be
25 | * persisted. they are passed to the visualiser via this result object.
26 | */
27 | public class JmxSampleResult extends SampleResult {
28 |
29 | private static final long serialVersionUID = 527766459330955540L;
30 | private String memType;
31 | private long value;
32 | private String jmxUri;
33 |
34 | public String getMemType() {
35 | return memType;
36 | }
37 |
38 | public void setMemType(String memType) {
39 | this.memType = memType;
40 | }
41 |
42 | public long getValue() {
43 | return value;
44 | }
45 |
46 | public void setValue(long value) {
47 | this.value = value;
48 | }
49 |
50 | public String getJmxUri() {
51 | return jmxUri;
52 | }
53 |
54 | public void setJmxUri(String uri) {
55 | this.jmxUri = uri;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/SaveGraphUtil.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.sampler;
15 |
16 | import java.io.FileOutputStream;
17 | import java.io.IOException;
18 |
19 | import org.apache.commons.logging.Log;
20 | import org.apache.commons.logging.LogFactory;
21 | import org.jCharts.Chart;
22 | import org.jCharts.encoders.PNGEncoder;
23 |
24 | public class SaveGraphUtil {
25 |
26 | private static Log log = LogFactory.getLog(SaveGraphUtil.class);
27 |
28 | public synchronized static void saveGraph(String fileName, String fileIdx, Chart chart) {
29 | String extension = ".png";
30 | FileOutputStream fileOutputStream = null;
31 | if (fileName != null && !("".equals(fileName.trim()))) {
32 | fileName = fileName.trim();
33 | if (fileName.toLowerCase().endsWith(extension)) {
34 | fileName = fileName.substring(0, fileName.length() - 4);
35 | }
36 | try {
37 |
38 | fileOutputStream = new FileOutputStream(fileName + fileIdx + extension);
39 | PNGEncoder.encode(chart, fileOutputStream);
40 | fileOutputStream.flush();
41 | } catch (Throwable throwable) {
42 | log.warn("Unable to save graph in " + fileName, throwable);
43 | throw new IllegalArgumentException("Unable to save graph in " + fileName, throwable);
44 | } finally {
45 | if (fileOutputStream != null)
46 | try {
47 | fileOutputStream.close();
48 | } catch (IOException e) {
49 | log.warn("Unable to close " + fileName, e);
50 | }
51 | }
52 | }
53 | }
54 |
55 | public synchronized static void saveGraph(String fileName, Chart chart) {
56 | saveGraph(fileName, "", chart);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/JmxGraphPanel.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.sampler.gui;
15 |
16 | import java.awt.Graphics;
17 | import java.awt.LayoutManager;
18 |
19 | import javax.swing.JPanel;
20 |
21 | import org.apache.jorphan.logging.LoggingManager;
22 | import org.apache.log.Logger;
23 |
24 | /**
25 | * Wraps a jChart graph on a Swing panel to ease embedding in the JmxVisualiser.
26 | * The graph is represented as an area chart for the data in column 1 and a line
27 | * chart for data in column 2.
28 | */
29 | public class JmxGraphPanel extends JPanel {
30 | private static final Logger log = LoggingManager.getLoggerForClass();
31 |
32 | private static final long serialVersionUID = -4967670058219091920L;
33 | private ChartWrapper graph;
34 |
35 | /**
36 | *
37 | */
38 | public JmxGraphPanel() {
39 | super();
40 | }
41 |
42 | /**
43 | * @param layout
44 | */
45 | public JmxGraphPanel(LayoutManager layout) {
46 | super(layout);
47 | }
48 |
49 | /**
50 | * @param layout
51 | * @param isDoubleBuffered
52 | */
53 | public JmxGraphPanel(LayoutManager layout, boolean isDoubleBuffered) {
54 | super(layout, isDoubleBuffered);
55 | }
56 |
57 | public ChartWrapper getGraph() {
58 | return graph;
59 | }
60 |
61 | public void setGraph(ChartWrapper graph) {
62 | this.graph = graph;
63 | }
64 |
65 | public void paintComponent() {
66 | try {
67 | graph.drawData();
68 | } catch (RuntimeException e) {
69 | log.info(String.format("Exception when drowing graph '%s'", graph.getTitle()), e);
70 | }
71 | }
72 |
73 | public void paintComponent(Graphics g) {
74 | try {
75 | graph.drawData(g);
76 | } catch (RuntimeException e) {
77 | // ignore this time around
78 | log.info(String.format("Exception when drowing graph '%s'", graph.getTitle()), e);
79 | }
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/JmxPanel.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler.gui;
16 |
17 | import java.util.LinkedList;
18 | import java.util.List;
19 |
20 | import javax.swing.BorderFactory;
21 | import javax.swing.JComboBox;
22 | import javax.swing.JFileChooser;
23 | import javax.swing.JLabel;
24 | import javax.swing.JTextField;
25 | import javax.swing.event.ChangeListener;
26 |
27 | import org.apache.jmeter.gui.util.HorizontalPanel;
28 | import org.apache.jmeter.gui.util.VerticalPanel;
29 | import org.apache.jorphan.gui.JLabeledTextField;
30 |
31 | import smartrics.jmeter.sampler.JmxSampler;
32 |
33 | /**
34 | * UI for the JMX data, used by the JmxGui
35 | */
36 | @SuppressWarnings("serial")
37 | public class JmxPanel extends VerticalPanel {
38 |
39 | List listeners = new LinkedList();
40 |
41 | private JTextField jmxUrl;
42 | private JComboBox usedMemoryType;
43 | private JLabeledTextField samplingFrequency;
44 |
45 | private JFileChooser saveFileChooser;
46 |
47 | public JmxPanel() {
48 | setBorder(BorderFactory.createTitledBorder("JMX"));
49 | HorizontalPanel jmxDataPanel = new HorizontalPanel();
50 | JLabel label = new JLabel("Url");
51 | jmxDataPanel.add(label);
52 | jmxUrl = new JTextField("service:jmx:rmi:///jndi/rmi://:/jmxrmi", 50);
53 | jmxDataPanel.add(jmxUrl);
54 | label = new JLabel("Memory");
55 | jmxDataPanel.add(label);
56 | usedMemoryType = new JComboBox(new String[] { JmxSampler.HEAP_MEM });
57 | // usedMemoryType = new JComboBox(new String[] { JmxSampler.HEAP_MEM,
58 | // JmxSampler.NON_HEAP_MEM});
59 | jmxDataPanel.add(usedMemoryType);
60 | samplingFrequency = new JLabeledTextField("Sampling Frequency (sec)", 5);
61 | jmxDataPanel.add(samplingFrequency);
62 | add(jmxDataPanel);
63 | }
64 |
65 | public void setUsedMemoryType(String memType) {
66 | usedMemoryType.setSelectedItem(memType);
67 | }
68 |
69 | public String getUsedMemoryType() {
70 | return usedMemoryType.getSelectedItem().toString();
71 | }
72 |
73 | public void setUrl(String u) {
74 | if (u == null)
75 | u = "";
76 | jmxUrl.setText(u);
77 | }
78 |
79 | public String getUrl() {
80 | return jmxUrl.getText();
81 | }
82 |
83 | public void setSamplingFrequency(int sf) {
84 | if (sf > 0) {
85 | samplingFrequency.setText(Integer.toString(sf));
86 | }
87 | }
88 |
89 | public int getSamplingFrequency() {
90 | return Integer.parseInt(samplingFrequency.getText());
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/jmx/MemUsageJmxClient.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler.jmx;
16 |
17 | import java.io.IOException;
18 | import java.lang.management.ManagementFactory;
19 | import java.lang.management.MemoryMXBean;
20 | import java.lang.management.MemoryUsage;
21 | import java.net.MalformedURLException;
22 |
23 | import javax.management.MBeanServerConnection;
24 | import javax.management.remote.JMXConnector;
25 | import javax.management.remote.JMXConnectorFactory;
26 | import javax.management.remote.JMXServiceURL;
27 |
28 | /**
29 | * A JMX client wrapper.
30 | *
31 | * @see MemoryMXBean
32 | */
33 | public class MemUsageJmxClient {
34 |
35 | public static class MemoryData {
36 | private MemoryMXBean mBean;
37 |
38 | private MemoryData(MemoryMXBean mBean) {
39 | this.mBean = mBean;
40 | }
41 |
42 | public long getUsedHeap() {
43 | return mBean.getHeapMemoryUsage().getUsed();
44 | }
45 |
46 | public long getUsedNonHeap() {
47 | return mBean.getNonHeapMemoryUsage().getUsed();
48 | }
49 | }
50 |
51 | private JMXServiceURL url;
52 | private MemoryMXBean memoryMbean;
53 |
54 | public void setUrl(String u) {
55 | try {
56 | url = new JMXServiceURL(u);
57 | } catch (MalformedURLException e) {
58 | throw new IllegalArgumentException("Unable to parse url: " + u);
59 | }
60 | }
61 |
62 | private void createMemoryMxBean() {
63 | try {
64 | JMXConnector connector = JMXConnectorFactory.connect(url);
65 | MBeanServerConnection mbsc = connector.getMBeanServerConnection();
66 | memoryMbean = ManagementFactory.newPlatformMXBeanProxy(mbsc, "java.lang:type=Memory", MemoryMXBean.class);
67 | } catch (IOException e) {
68 | throw new IllegalStateException("Unable to get to the MemoryMXBean", e);
69 | }
70 | }
71 |
72 | public MemoryData getData() {
73 | if (memoryMbean == null)
74 | createMemoryMxBean();
75 | MemoryData data = new MemoryData(memoryMbean);
76 | return data;
77 | }
78 |
79 |
80 | public static void main(String[] args) throws Exception {
81 | JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi");
82 | JMXConnector connector = JMXConnectorFactory.connect(url);
83 | MBeanServerConnection mbsc = connector.getMBeanServerConnection();
84 | MemoryMXBean memoryMbean = ManagementFactory.newPlatformMXBeanProxy(mbsc, "java.lang:type=Memory", MemoryMXBean.class);
85 | for (int i = 0; i < 100; i++) {
86 | MemoryUsage mu = memoryMbean.getHeapMemoryUsage();
87 | System.out.println(mu.getUsed());
88 | Thread.sleep(1000);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/ant/DataExtractor.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.ant;
15 |
16 | import java.io.File;
17 | import java.io.FileInputStream;
18 | import java.io.FileNotFoundException;
19 | import java.util.ArrayList;
20 | import java.util.Collection;
21 | import java.util.List;
22 |
23 | import org.apache.jmeter.reporters.ResultCollector;
24 | import org.apache.jmeter.reporters.ResultCollectorHelper;
25 | import org.apache.jmeter.samplers.SampleEvent;
26 | import org.apache.jmeter.samplers.SampleResult;
27 | import org.apache.jmeter.save.SaveService;
28 | import org.apache.jmeter.visualizers.GraphVisualizer;
29 | import org.apache.jmeter.visualizers.Visualizer;
30 |
31 | public abstract class DataExtractor {
32 |
33 | private File jtlFile;
34 |
35 | public DataExtractor(File jtlFile) {
36 | super();
37 | if (jtlFile == null) {
38 | throw new IllegalArgumentException("jtl file is null");
39 | }
40 | this.jtlFile = jtlFile;
41 | }
42 |
43 | public File getJtlFile() {
44 | return jtlFile;
45 | }
46 |
47 | @SuppressWarnings({"serial" })
48 | public void handleResults() {
49 | String jtlFilePath = jtlFile.getAbsolutePath();
50 | try {
51 | // FileInputStream fis = new FileInputStream(getJtlFile());
52 | final Collection results = new ArrayList();
53 | // ResultCollector resultCollector = new ResultCollector(){
54 | // public void sampleOccurred(SampleEvent event) {
55 | // SampleResult result = event.getResult();
56 | // results.add(result);
57 | // }
58 | // };
59 | // Visualizer visualizer = new GraphVisualizer();
60 | // ResultCollectorHelper resultCollectorHelper = new ResultCollectorHelper(resultCollector, visualizer);
61 | // SaveService.loadTestResults(fis, resultCollectorHelper);
62 | // resultCollector.loadExistingFile();
63 |
64 | ResultCollector rc = new ResultCollector();
65 | rc.setFilename(jtlFilePath);
66 | rc.setListener(new Visualizer() {
67 |
68 | public void add(SampleResult sample) {
69 | results.add(sample);
70 | }
71 |
72 | public boolean isStats() {
73 | return false;
74 | }
75 |
76 | });
77 | rc.loadExistingFile();
78 |
79 | for (SampleResult r : results) {
80 | try {
81 | handle(r);
82 | } catch (IllegalArgumentException e) {
83 | throw new IllegalArgumentException("jtl file '" + jtlFilePath + "' contains data not processable", e);
84 | }
85 | }
86 | } catch (Exception e) {
87 | e.printStackTrace();
88 | throw new IllegalArgumentException("Unable to load test results from " + jtlFilePath, e);
89 | }
90 | }
91 |
92 | public abstract void handle(SampleResult res);
93 |
94 | }
--------------------------------------------------------------------------------
/JMeterRestSampler/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/JmxGui.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler.gui;
16 |
17 | import java.awt.BorderLayout;
18 | import java.awt.Dimension;
19 |
20 | import org.apache.jmeter.functions.InvalidVariableException;
21 | import org.apache.jmeter.gui.GuiPackage;
22 | import org.apache.jmeter.gui.util.VerticalPanel;
23 | import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
24 | import org.apache.jmeter.testelement.TestElement;
25 |
26 | import smartrics.jmeter.sampler.JmxSampler;
27 |
28 | /**
29 | * Frontend for the JmxSampler
30 | */
31 | public class JmxGui extends AbstractSamplerGui {
32 | private static final long serialVersionUID = -5576774730632101012L;
33 | private JmxPanel panel;
34 |
35 | public JmxGui() {
36 | init();
37 | }
38 |
39 | public String getLabelResource() {
40 | return "jmx_sampler_title"; //$NON-NLS-1$
41 | }
42 |
43 | public String getStaticLabel() {
44 | return "Jmx Sampler";
45 | }
46 |
47 | /*
48 | * (non-Javadoc)
49 | *
50 | * @see org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
51 | */
52 | public TestElement createTestElement() {
53 | JmxSampler sampler = new JmxSampler();
54 | modifyTestElement(sampler);
55 | return sampler;
56 | }
57 |
58 | public void clear() {
59 | resetJmxPanel();
60 | }
61 |
62 | private void resetJmxPanel() {
63 | panel.setUrl("service:jmx:rmi:///jndi/rmi://:/jmxrmi");
64 | panel.setUsedMemoryType(JmxSampler.HEAP_MEM);
65 | panel.setSamplingFrequency(5);
66 | }
67 |
68 | /**
69 | * Modifies a given TestElement to mirror the data in the gui components.
70 | *
71 | * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
72 | */
73 | public void modifyTestElement(TestElement s) {
74 | this.configureTestElement(s);
75 | if (s instanceof JmxSampler) {
76 | JmxSampler sampler = (JmxSampler) s;
77 | try {
78 | GuiPackage.getInstance().getReplacer().replaceValues(sampler);
79 | } catch (InvalidVariableException e) {
80 | e.printStackTrace();
81 | }
82 | sampler.setSampleFrequency(panel.getSamplingFrequency());
83 | sampler.setJmxUri(panel.getUrl());
84 | sampler.setJmxMemType(panel.getUsedMemoryType());
85 | }
86 | }
87 |
88 | /**
89 | * Implements JMeterGUIComponent.clearGui
90 | */
91 | public void clearGui() {
92 | super.clearGui();
93 | }
94 |
95 | private void init() {
96 | setLayout(new BorderLayout());
97 | setBorder(makeBorder());
98 | VerticalPanel p = new VerticalPanel();
99 | add(p, BorderLayout.NORTH);
100 | p.add(makeTitlePanel());
101 | panel = new JmxPanel();
102 | resetJmxPanel();
103 | p.add(panel);
104 | }
105 |
106 | public void configure(TestElement el) {
107 | super.configure(el);
108 | if (el instanceof JmxSampler) {
109 | JmxSampler sampler = (JmxSampler) el;
110 | panel.setUrl(sampler.getJmxUri());
111 | panel.setUsedMemoryType(sampler.getJmxMemType());
112 | int sf = sampler.getSampleFrequency();
113 | panel.setSamplingFrequency(sf);
114 | }
115 | }
116 |
117 | public Dimension getPreferredSize() {
118 | return getMinimumSize();
119 | }
120 |
121 | }
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/JmxSampler.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler;
16 |
17 | import java.util.HashMap;
18 | import java.util.Map;
19 |
20 | import org.apache.jmeter.samplers.AbstractSampler;
21 | import org.apache.jmeter.samplers.Entry;
22 | import org.apache.jmeter.samplers.SampleResult;
23 |
24 | import smartrics.jmeter.sampler.jmx.MemUsageJmxClient;
25 | import smartrics.jmeter.sampler.jmx.MemUsageJmxClient.MemoryData;
26 |
27 | /**
28 | * This samples a JMX server for memory usage. At the moment only for Heap
29 | * memory of the JVM to which it points to. This sampler captures the URI for
30 | * the server, whether and where to save a graph file of the results and the
31 | * sample frequency.
32 | *
33 | * It's a bit odd as a sampler because it should not be used to gather
34 | * performance measures on a JMX server.
35 | *
36 | * It's main usage, in fact, is for reporting on memory usage, functional to
37 | * robustness builds.
38 | */
39 | public class JmxSampler extends AbstractSampler {
40 | public static String HEAP_MEM = "heap";
41 | public static String NON_HEAP_MEM = "non heap";
42 | private static final long serialVersionUID = -5877623539165274730L;
43 | private static Map lastSampleTs = new HashMap();
44 |
45 | public static final String JMX_URI = "JmxSampler.jmx_uri";
46 |
47 | public static final String JMX_MEM_TYPE = "JmxSampler.jmx_mem_type";
48 |
49 | public static final String JMX_SAMPLE_FREQUENCY = "JmxSampler.jmx_sample_frequency";
50 |
51 | public static final String JMX_LAST_SAMPLE_TS = "JmxSampler.jmx_last_sample_ts";
52 |
53 | public JmxSampler() {
54 | }
55 |
56 | public int getSampleFrequency() {
57 | return getPropertyAsInt(JMX_SAMPLE_FREQUENCY);
58 | }
59 |
60 | public void setSampleFrequency(int data) {
61 | setProperty(JMX_SAMPLE_FREQUENCY, Integer.toString(data));
62 | }
63 |
64 | public void setLastSampleTs(String uri, long data) {
65 | lastSampleTs.put(uri, data);
66 | }
67 |
68 | public long getLastSampleTs(String uri) {
69 | Long ts = lastSampleTs.get(uri);
70 | if (ts == null)
71 | return 0;
72 | return ts.longValue();
73 | }
74 |
75 | public void setJmxUri(String data) {
76 | setProperty(JMX_URI, data);
77 | }
78 |
79 | public String getJmxUri() {
80 | return getPropertyAsString(JMX_URI);
81 | }
82 |
83 | public void setJmxMemType(String data) {
84 | setProperty(JMX_MEM_TYPE, data);
85 | }
86 |
87 | public String getJmxMemType() {
88 | return getPropertyAsString(JMX_MEM_TYPE);
89 | }
90 |
91 | public String toString() {
92 | return "Jmx uri: " + getJmxUri() + ", mem: " + getJmxMemType();
93 | }
94 |
95 | public SampleResult sample(Entry e) {
96 | return sample();
97 | }
98 |
99 | /**
100 | *
101 | * @return a standard sample result of type JmxSampleResult.
102 | */
103 | public SampleResult sample() {
104 | long startdate = System.currentTimeMillis();
105 | long lastSampleTs = getLastSampleTs(getJmxUri());
106 | if ((startdate - lastSampleTs) < getSampleFrequency() * 1000) {
107 | // sampling more frequently than the set frequency
108 | return null;
109 | }
110 | setLastSampleTs(getJmxUri(), startdate);
111 | JmxSampleResult newRes = new JmxSampleResult();
112 | MemUsageJmxClient c = new MemUsageJmxClient();
113 | c.setUrl(getJmxUri());
114 | MemoryData d = c.getData();
115 | newRes.setSampleLabel("jmx");
116 | long mem = byte2Kbyte(d.getUsedNonHeap());
117 | if (HEAP_MEM.equals(getJmxMemType())) {
118 | // transform in Kb by default (mem is returned in bytes)
119 | mem = byte2Kbyte(d.getUsedHeap());
120 | }
121 | newRes.setMemType(getJmxMemType());
122 | newRes.setValue(mem);
123 | newRes.setJmxUri(getJmxUri());
124 | newRes.setSamplerData(Long.toString(mem));
125 | long enddate = System.currentTimeMillis();
126 | newRes.setStampAndTime(enddate, enddate - startdate);
127 | // obviously it's always successful as we're capturing data for report
128 | // purposes
129 | newRes.setSuccessful(true);
130 | return newRes;
131 | }
132 |
133 | private long byte2Kbyte(long n) {
134 | return n / 1024;
135 | }
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/ant/JMeterTaskExt.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.ant;
15 |
16 | import java.io.File;
17 | import java.io.FilenameFilter;
18 | import java.util.AbstractList;
19 | import java.util.ArrayList;
20 | import java.util.Iterator;
21 |
22 | import org.apache.jmeter.util.JMeterUtils;
23 | import org.apache.soap.providers.com.Log;
24 | import org.apache.tools.ant.BuildException;
25 | import org.apache.tools.ant.Project;
26 |
27 | public class JMeterTaskExt extends JMeterTask {
28 |
29 | private String succecssThresholdPerc;
30 |
31 | public void setSuccecssThresholdPerc(String t) {
32 | this.succecssThresholdPerc = t;
33 | }
34 |
35 | public String getSuccecssThresholdPerc() {
36 | return this.succecssThresholdPerc;
37 | }
38 |
39 | private File chartsOutputDir;
40 |
41 | public File getChartsOutputDir() {
42 | return chartsOutputDir;
43 | }
44 |
45 | public void setChartsOutputDir(File chartsOutputDir) {
46 | this.chartsOutputDir = chartsOutputDir;
47 | }
48 |
49 | public int getSuccecssThresholdAsInt() {
50 | try {
51 | return Integer.parseInt(getSuccecssThresholdPerc());
52 | } catch (NumberFormatException e) {
53 | Log.msg(Log.WARNING, "Unable to parse succecssThreshold. Use default of 100%");
54 | return 100;
55 | }
56 | }
57 |
58 | public void execute() throws BuildException {
59 | try {
60 | super.execute();
61 | generateCharts();
62 | } catch (RuntimeException e) {
63 | throw new BuildException("Unexpected exception: " + e.getMessage());
64 | }
65 | }
66 |
67 | private void generateCharts() throws BuildException {
68 | if (chartsOutputDir != null) {
69 | AbstractList resultFiles = getResultLogFiles();
70 | for (File result : resultFiles) {
71 | String name = result.getName();
72 | int pos = name.indexOf(".jtl");
73 | name = name.substring(0, pos);
74 | File jmxChartFile = new File(chartsOutputDir, name + "_jmxChart.png");
75 | File perfChartFile = new File(chartsOutputDir, name + "_perfChart.png");
76 | File fullResult = new File(getResultLogDir(), result.getName());
77 | ChartGenerator dataExtractor = new ChartGenerator(fullResult, jmxChartFile, perfChartFile);
78 | log("Generating charts with data extracted from " + fullResult.getAbsolutePath(), Project.MSG_VERBOSE);
79 | dataExtractor.generate();
80 | log("Charts generated in '" + jmxChartFile.getAbsolutePath() + "' and '" + perfChartFile.getAbsolutePath() + "'", Project.MSG_VERBOSE);
81 | }
82 | }
83 | }
84 |
85 | private ArrayList getResultLogFiles() {
86 | ArrayList resultLogFiles = new ArrayList();
87 | FilenameFilter filter = new FilenameFilter() {
88 | public boolean accept(File dir, String name) {
89 | return name.endsWith(".jtl");
90 | }
91 | };
92 | String[] files = getResultLogDir().list(filter);
93 | for (String s : files) {
94 | resultLogFiles.add(new File(s));
95 | }
96 | return resultLogFiles;
97 | }
98 |
99 | protected void checkForFailures() throws BuildException {
100 | JMeterUtils.setJMeterHome(getJmeterHome().getAbsolutePath());
101 | JMeterUtils.loadJMeterProperties(getJmeterProperties().getAbsolutePath());
102 | if (getFailureProperty() != null && getFailureProperty().trim().length() > 0) {
103 | AbstractList resultFiles = getResultLogFiles();
104 | for (Iterator i = resultFiles.iterator(); i.hasNext();) {
105 | File resultLogFile = new File(getResultLogDir(), ((File) i.next()).getName());
106 | log("Processing " + resultLogFile.getAbsolutePath());
107 | SuccessParser parser = new SuccessParser(resultLogFile);
108 | parser.handleResults();
109 | int totals = parser.getTotal();
110 | int successes = parser.getSuccesses();
111 | int failures = totals - successes;
112 | int succecssThresholdPerc = getSuccecssThresholdAsInt();
113 | double percSuccesses = 100 * successes / totals;
114 | log(String.format("Total samples: %s, successes: %s, failures: %s", totals, successes, failures), Project.MSG_VERBOSE);
115 | log(String.format("Success percent: $s, success threshold percent: %s", percSuccesses, succecssThresholdPerc));
116 | if (percSuccesses < succecssThresholdPerc) {
117 | setFailure(getFailureProperty());
118 | }
119 | }
120 | }
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/JmxVisualizer.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler.gui;
16 |
17 | import java.awt.BorderLayout;
18 | import java.awt.Color;
19 | import java.awt.Container;
20 | import java.awt.Dimension;
21 | import java.util.Collections;
22 | import java.util.HashMap;
23 | import java.util.Iterator;
24 | import java.util.Map;
25 | import java.util.Map.Entry;
26 |
27 | import javax.swing.BorderFactory;
28 |
29 | import org.apache.jmeter.gui.util.VerticalPanel;
30 | import org.apache.jmeter.samplers.SampleResult;
31 | import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
32 | import org.apache.jorphan.logging.LoggingManager;
33 | import org.apache.log.Logger;
34 |
35 | import smartrics.jmeter.sampler.JmxSampleResult;
36 | import smartrics.jmeter.sampler.SaveGraphUtil;
37 |
38 | /**
39 | * Visualises the results of sampling a JMX server for memory.
40 | *
41 | * Each server is represented by a graph and identified by it's uri. It captures
42 | * and display results from all JmxSampler set up to sample different servers.
43 | */
44 | @SuppressWarnings("serial")
45 | public class JmxVisualizer extends AbstractVisualizer implements SaveGraphListener {
46 | private static final Logger log = LoggingManager.getLoggerForClass();
47 |
48 | private VerticalPanel graphsPanel;
49 | private Map graphTable = Collections.synchronizedMap(new HashMap());
50 |
51 | public JmxVisualizer() {
52 | setLayout(new BorderLayout());
53 | setBorder(makeBorder());
54 | VerticalPanel groupPanel = new VerticalPanel();
55 | Container titlePanel = makeTitlePanel();
56 | groupPanel.add(titlePanel);
57 | // redo a filepanel for savegraph
58 | // - forces png
59 | // - files only
60 | // - add save button below
61 | // - this will listen to save file actions
62 | // - displays file chooser if file not chosen
63 | // - if file added by hand, must work
64 | SaveChartFilePanel saveGraph = new SaveChartFilePanel("Save Graph", "PNG [*.png]");
65 | saveGraph.addSaveGraphPressedListener(this);
66 | groupPanel.add(saveGraph);
67 | add(groupPanel, BorderLayout.NORTH);
68 | graphsPanel = new VerticalPanel();
69 | add(graphsPanel, BorderLayout.CENTER);
70 | }
71 |
72 | public String getStaticLabel() {
73 | return "JMX Memory Usage";
74 | }
75 |
76 | private JmxGraphPanel addGraph(String memType, String uri) {
77 | JmxGraphPanel graphPanel = new JmxGraphPanel();
78 | ChartWrapper graph = new ChartWrapper();
79 | graphsPanel.add(graphPanel);
80 | graphPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
81 | graph.setTitle(memType + " usage for " + uri);
82 | graph.setXAxisTitle("elapsed time (seconds)");
83 | graph.setYAxisTitle("Kb");
84 | graph.setYAxisLabels(new String[] { memType, "Average" });
85 | Dimension size = new Dimension(800, 600);
86 | graph.setWidth(size.width);
87 | graph.setHeight(size.height);
88 | graphPanel.setGraph(graph);
89 | graphPanel.setMaximumSize(size);
90 | graphPanel.setPreferredSize(size);
91 | return graphPanel;
92 | }
93 |
94 | public void add(SampleResult res) {
95 | if (res instanceof JmxSampleResult) {
96 | log.warn("INVOKED: " + res);
97 | JmxSampleResult result = (JmxSampleResult) res;
98 | String uri = result.getJmxUri();
99 | JmxGraphPanel graphPanel = graphTable.get(uri);
100 | if (graphPanel == null) {
101 | graphPanel = addGraph(result.getMemType(), uri);
102 | graphTable.put(uri, graphPanel);
103 | }
104 | ChartWrapper graph = graphPanel.getGraph();
105 | graph.setXAxisScalingFactor(1000);
106 | graph.putRawData(result.getStartTime(), result.getValue());
107 | renderChart(uri, graphPanel);
108 | }
109 | }
110 |
111 | public String getLabelResource() {
112 | return "jmx.visualizer";
113 | }
114 |
115 | private synchronized void renderChart(String uri, JmxGraphPanel graphPanel) {
116 | graphPanel.invalidate();
117 | graphPanel.paintComponent();
118 | repaint();
119 | }
120 |
121 | public void saveGraphPressed(String filename) {
122 | Iterator> it = graphTable.entrySet().iterator();
123 | int i = 0;
124 | while (it.hasNext()) {
125 | JmxGraphPanel v = it.next().getValue();
126 | String id = Integer.toString(i);
127 | if (graphTable.size() == 1) {
128 | id = "";
129 | }
130 | SaveGraphUtil.saveGraph(filename, id, v.getGraph().getChart());
131 | i++;
132 | }
133 | }
134 |
135 | public void clearData() {
136 |
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/ant/ChartGenerator.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.ant;
15 |
16 | import java.io.File;
17 | import java.net.URL;
18 | import java.util.HashMap;
19 | import java.util.Map;
20 | import java.util.Set;
21 |
22 | import org.apache.jmeter.protocol.http.sampler.HTTPSampleResult;
23 | import org.apache.jmeter.samplers.SampleResult;
24 | import org.apache.jmeter.util.JMeterUtils;
25 |
26 | import smartrics.jmeter.sampler.JmxSampleResult;
27 | import smartrics.jmeter.sampler.SaveGraphUtil;
28 | import smartrics.jmeter.sampler.gui.ChartWrapper;
29 |
30 | public class ChartGenerator extends DataExtractor {
31 | private Map jmxCharts = new HashMap();
32 | private Map perfCharts = new HashMap();
33 | private File jmxGraphFile;
34 | private File perfGraphFile;
35 |
36 | public ChartGenerator(File jtlFile, File jmxGraphFile, File perfGraphFile) {
37 | super(jtlFile);
38 | this.jmxGraphFile = jmxGraphFile;
39 | this.perfGraphFile = perfGraphFile;
40 | }
41 |
42 | public void handle(SampleResult res) {
43 | if (res instanceof JmxSampleResult)
44 | handle((JmxSampleResult) res);
45 | else if (res instanceof HTTPSampleResult)
46 | handle((HTTPSampleResult) res);
47 | else {
48 | throw new IllegalArgumentException("Unable to handle SampleResult of type " + res.getClass().getName());
49 | }
50 | }
51 |
52 | public void generate() {
53 | if (jmxGraphFile == null && perfGraphFile == null) {
54 | return;
55 | }
56 | handleResults();
57 | produceGraphFiles(jmxCharts, jmxGraphFile);
58 | produceGraphFiles(perfCharts, perfGraphFile);
59 | }
60 |
61 | private void produceGraphFiles(Map charts, File graphFile) {
62 | if (graphFile == null) {
63 | return;
64 | }
65 | Set keys = charts.keySet();
66 | int cnt = 0;
67 | for (String key : keys) {
68 | ChartWrapper chart = charts.get(key);
69 | chart.drawData();
70 | String gfname = graphFile.getAbsolutePath();
71 | if (keys.size() > 1) {
72 | gfname = addCounterToFilename(cnt, gfname);
73 | cnt++;
74 | }
75 | SaveGraphUtil.saveGraph(gfname, chart.getChart());
76 | }
77 | }
78 |
79 | private String addCounterToFilename(int cnt, String fname) {
80 | int extPos = fname.lastIndexOf('.');
81 | String pre = fname.substring(0, extPos);
82 | String post = fname.substring(extPos);
83 | return pre + "_" + cnt + post;
84 | }
85 |
86 | public void handle(JmxSampleResult res) {
87 | ChartWrapper jmxChart = jmxCharts.get(res.getJmxUri());
88 | if (jmxChart == null) {
89 | String[] label = new String[] { res.getMemType(), "Average" };
90 | String yaTitle = "Kb";
91 | String xaTitle = "time";
92 | jmxChart = createChartWrapper(res.getJmxUri(), label, yaTitle, xaTitle);
93 | jmxCharts.put(res.getJmxUri(), jmxChart);
94 | }
95 | jmxChart.putRawData(res.getTimeStamp(), Long.parseLong(res.getSamplerData()));
96 | }
97 |
98 | private ChartWrapper createChartWrapper(String title, String[] label, String yaTitle, String xaTitle) {
99 | ChartWrapper chart = new ChartWrapper();
100 | chart.setHeight(600);
101 | chart.setWidth(800);
102 | chart.setTitle(title);
103 | chart.setYAxisLabels(label);
104 | chart.setYAxisTitle(yaTitle);
105 | chart.setXAxisTitle(xaTitle);
106 | return chart;
107 | }
108 |
109 | public void handle(HTTPSampleResult res) {
110 | URL url = res.getURL();
111 | String uri = "host";
112 | // TODO: find out why the URL is not saved in the HTTPSampleResult
113 | if (url != null)
114 | uri = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort();
115 | ChartWrapper timeChart = perfCharts.get(uri);
116 | if (timeChart == null) {
117 | String[] label = new String[] { "Time", "Average" };
118 | String yaTitle = "ms";
119 | String xaTitle = "time";
120 | timeChart = createChartWrapper(uri, label, yaTitle, xaTitle);
121 | perfCharts.put(uri, timeChart);
122 | }
123 | timeChart.putRawData(res.getTimeStamp(), res.getEndTime() - res.getStartTime());
124 | }
125 |
126 | public static void main(String[] args) {
127 | JMeterUtils.setJMeterHome("/opt/java/jakarta-jmeter");
128 | JMeterUtils.loadJMeterProperties("/opt/java/jakarta-jmeter/bin/jmeter.properties");
129 | File f = new File("/home/fabrizio/Desktop/twitter.jtl");
130 | File jmxFile = new File("/home/fabrizio/Desktop/jmxGraph.png");
131 | File perfFile = new File("/home/fabrizio/Desktop/timeGraph.png");
132 | new ChartGenerator(f, jmxFile, perfFile).generate();
133 | }
134 |
135 | }
136 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/SaveChartFilePanel.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.sampler.gui;
15 |
16 | import java.awt.event.ActionEvent;
17 | import java.awt.event.ActionListener;
18 | import java.util.Iterator;
19 | import java.util.LinkedList;
20 | import java.util.List;
21 |
22 | import javax.swing.BorderFactory;
23 | import javax.swing.Box;
24 | import javax.swing.JButton;
25 | import javax.swing.JFileChooser;
26 | import javax.swing.JLabel;
27 | import javax.swing.JTextField;
28 | import javax.swing.event.ChangeEvent;
29 | import javax.swing.event.ChangeListener;
30 |
31 | import org.apache.jmeter.gui.util.FileDialoger;
32 | import org.apache.jmeter.gui.util.HorizontalPanel;
33 | import org.apache.jmeter.util.JMeterUtils;
34 |
35 | public class SaveChartFilePanel extends HorizontalPanel implements ActionListener {
36 | private static final long serialVersionUID = -4969098309721273290L;
37 |
38 | JTextField filename = new JTextField(20);
39 |
40 | JLabel label = new JLabel(JMeterUtils.getResString("file_visualizer_filename")); //$NON-NLS-1$
41 |
42 | JButton browse = new JButton(JMeterUtils.getResString("browse")); //$NON-NLS-1$
43 |
44 | private static final String ACTION_BROWSE = "browse"; //$NON-NLS-1$
45 | private static final String ACTION_SAVE = "save"; //$NON-NLS-1$
46 |
47 | List listeners = new LinkedList();
48 | List sgListeners = new LinkedList();
49 |
50 | String title;
51 |
52 | String filetype;
53 |
54 | public SaveChartFilePanel(String title, String filetype) {
55 | this(null, title, filetype);
56 | }
57 |
58 | /**
59 | * Constructor for the FilePanel object.
60 | */
61 | public SaveChartFilePanel(ChangeListener l, String title, String filetype) {
62 | this.title = title;
63 | this.filetype = filetype;
64 | init();
65 | if (l != null)
66 | listeners.add(l);
67 | }
68 |
69 | public void addChangeListener(ChangeListener l) {
70 | listeners.add(l);
71 | }
72 |
73 | private void init() {
74 | setBorder(BorderFactory.createTitledBorder(title));
75 | add(label);
76 | add(Box.createHorizontalStrut(5));
77 | add(filename);
78 | add(Box.createHorizontalStrut(5));
79 | filename.addActionListener(this);
80 | add(browse);
81 | browse.setActionCommand(ACTION_BROWSE);
82 | browse.addActionListener(this);
83 | JButton save = new JButton("Save");
84 | save.setActionCommand(ACTION_SAVE);
85 | final SaveChartFilePanel t = this;
86 | save.addActionListener(new ActionListener() {
87 | public void actionPerformed(ActionEvent e) {
88 | if (e.getActionCommand().equals("save")) {
89 | if (filename != null && filename.getText() != null && !"".equals(filename.getText().trim())) {
90 | t.fireSaveGraphPressed(filename.getText());
91 | } else {
92 | t.actionPerformed(e);
93 | }
94 | }
95 | }
96 | });
97 | add(save);
98 | }
99 |
100 | private void fireSaveGraphPressed(String text) {
101 | Iterator iter = sgListeners.iterator();
102 | while (iter.hasNext()) {
103 | iter.next().saveGraphPressed(text);
104 | }
105 | }
106 |
107 | public void clearGui(){
108 | filename.setText("");
109 | }
110 |
111 | /**
112 | * Gets the filename attribute of the FilePanel object.
113 | *
114 | * @return the filename value
115 | */
116 | public String getFilename() {
117 | return filename.getText();
118 | }
119 |
120 | /**
121 | * Sets the filename attribute of the FilePanel object.
122 | *
123 | * @param f
124 | * the new filename value
125 | */
126 | public void setFilename(String f) {
127 | filename.setText(f);
128 | }
129 |
130 | private void fireFileChanged() {
131 | Iterator iter = listeners.iterator();
132 | while (iter.hasNext()) {
133 | iter.next().stateChanged(new ChangeEvent(this));
134 | }
135 | }
136 |
137 | public void actionPerformed(ActionEvent e) {
138 | if (e.getActionCommand().equals(ACTION_BROWSE)) {
139 | JFileChooser chooser;
140 | if(filetype == null){
141 | chooser = FileDialoger.promptToOpenFile();
142 | } else {
143 | chooser = FileDialoger.promptToOpenFile(new String[] { filetype });
144 | }
145 | if (chooser != null && chooser.getSelectedFile() != null) {
146 | filename.setText(chooser.getSelectedFile().getPath());
147 | fireFileChanged();
148 | }
149 | } else {
150 | fireFileChanged();
151 | }
152 | }
153 |
154 | public void addSaveGraphPressedListener(SaveGraphListener listener) {
155 | sgListeners.add(listener);
156 | }
157 | }
158 |
159 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/RestGui.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler.gui;
16 |
17 | import java.awt.BorderLayout;
18 | import java.awt.Dimension;
19 |
20 | import javax.swing.BorderFactory;
21 | import javax.swing.JCheckBox;
22 | import javax.swing.JPanel;
23 | import javax.swing.event.ChangeEvent;
24 | import javax.swing.event.ChangeListener;
25 |
26 | import org.apache.jmeter.gui.util.HorizontalPanel;
27 | import org.apache.jmeter.gui.util.VerticalPanel;
28 | import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
29 | import org.apache.jmeter.testelement.TestElement;
30 | import org.apache.jmeter.util.JMeterUtils;
31 | import org.apache.jorphan.gui.JLabeledChoice;
32 | import org.apache.jorphan.gui.JLabeledTextArea;
33 | import org.apache.jorphan.gui.JLabeledTextField;
34 | import org.apache.jorphan.logging.LoggingManager;
35 | import org.apache.log.Logger;
36 |
37 | import smartrics.jmeter.sampler.RestSampler;
38 |
39 | /**
40 | * Frontend to the REST sampler.
41 | *
42 | * It only eposes GET/POST/PUT/DELETE.
43 | */
44 | public class RestGui extends AbstractSamplerGui {
45 | private static final long serialVersionUID = -5576774730632101012L;
46 | private static final Logger log = LoggingManager.getLoggerForClass();
47 | private JCheckBox useKeepAlive;
48 | private JCheckBox automaticRedirect;
49 | private JLabeledTextArea body;
50 | private JLabeledTextArea headers;
51 | private JLabeledTextField hostBaseUrl;
52 | private JLabeledTextField resource;
53 | private JLabeledTextField encoding;
54 | private JLabeledTextField queryString;
55 | private JLabeledChoice httpMethods;
56 |
57 | public RestGui() {
58 | log.debug("Initialised RestGui");
59 | try {
60 | init();
61 | } catch(Exception e){
62 | log.error("Exception loading RestGui", e);
63 | }
64 | }
65 |
66 | public String getLabelResource() {
67 | return "rest_sampler_title"; //$NON-NLS-1$
68 | }
69 |
70 | public String getStaticLabel() {
71 | return "Rest Sampler";
72 | }
73 |
74 | /*
75 | * (non-Javadoc)
76 | *
77 | * @see org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
78 | */
79 | public TestElement createTestElement() {
80 | RestSampler sampler = new RestSampler();
81 | modifyTestElement(sampler);
82 | return sampler;
83 | }
84 |
85 | public void clear() {
86 | this.httpMethods.setText("GET");
87 | this.hostBaseUrl.setText("");
88 | this.headers.setText("");
89 | this.resource.setText("");
90 | this.encoding.setText("UTF-8");
91 | this.queryString.setText("");
92 | this.useKeepAlive.setSelected(true);
93 | this.automaticRedirect.setSelected(true);
94 | this.body.setText("");
95 | }
96 |
97 | /**
98 | * Modifies a given TestElement to mirror the data in the gui components.
99 | *
100 | * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
101 | */
102 | public void modifyTestElement(TestElement s) {
103 | this.configureTestElement(s);
104 | if (s instanceof RestSampler) {
105 | RestSampler sampler = (RestSampler) s;
106 | sampler.setRequestBody(body.getText());
107 | sampler.setMethod(httpMethods.getText());
108 | sampler.setUseKeepAlive(useKeepAlive.isSelected());
109 | sampler.setAutoRedirects(automaticRedirect.isSelected());
110 | sampler.setHostBaseUrl(hostBaseUrl.getText());
111 | sampler.setResource(resource.getText());
112 | sampler.setContentEncoding(encoding.getText());
113 | sampler.setQueryString(queryString.getText());
114 | sampler.setRequestHeaders(headers.getText());
115 | }
116 | }
117 |
118 | /**
119 | * Implements JMeterGUIComponent.clearGui
120 | */
121 | public void clearGui() {
122 | super.clearGui();
123 | }
124 |
125 | private JPanel getResourceConfigPanel() {
126 | automaticRedirect = new JCheckBox(JMeterUtils.getResString("follow_redirects"));
127 | httpMethods = new JLabeledChoice("Method", new String[] { "GET", "POST", "PUT", "DELETE" });
128 | httpMethods.addChangeListener(new ChangeListener() {
129 | public void stateChanged(ChangeEvent e) {
130 | JLabeledChoice c = (JLabeledChoice) e.getSource();
131 | String text = c.getText();
132 | if ("PUT".equals(text) || "POST".equals(text)) {
133 | automaticRedirect.setSelected(false);
134 | automaticRedirect.setEnabled(false);
135 | } else {
136 | automaticRedirect.setEnabled(true);
137 | }
138 | }
139 | });
140 | useKeepAlive = new JCheckBox(JMeterUtils.getResString("use_keepalive"));
141 | hostBaseUrl = new JLabeledTextField("Base Url", 25);
142 | resource = new JLabeledTextField("Resource", 20);
143 | queryString = new JLabeledTextField("QueryString", 30);
144 | encoding = new JLabeledTextField("Content Encoding", 8);
145 | VerticalPanel panel = new VerticalPanel();
146 | HorizontalPanel panel1 = new HorizontalPanel();
147 | panel1.add(httpMethods);
148 | panel1.add(useKeepAlive);
149 | panel1.add(automaticRedirect);
150 | HorizontalPanel panel2 = new HorizontalPanel();
151 | panel2.add(hostBaseUrl);
152 | panel2.add(resource);
153 | HorizontalPanel panel3 = new HorizontalPanel();
154 | panel3.add(queryString);
155 | panel3.add(encoding);
156 | panel.add(panel1);
157 | panel.add(panel2);
158 | panel.add(panel3);
159 | return panel;
160 | }
161 |
162 | private JPanel getRequestPanel() {
163 | body = new JLabeledTextArea("Body"); //$NON-NLS-1$
164 | headers = new JLabeledTextArea("Headers"); //$NON-NLS-1$
165 | VerticalPanel panel = new VerticalPanel();
166 | panel.add(headers, BorderLayout.NORTH);
167 | panel.add(body, BorderLayout.CENTER);
168 | return panel;
169 | }
170 |
171 | private void init() {
172 | setLayout(new BorderLayout());
173 | setBorder(makeBorder());
174 | add(makeTitlePanel(), BorderLayout.NORTH);
175 | VerticalPanel panel = new VerticalPanel();
176 | panel.setBorder(BorderFactory.createEtchedBorder());
177 | panel.add(getResourceConfigPanel(), BorderLayout.NORTH);
178 | panel.add(getRequestPanel(), BorderLayout.CENTER);
179 | add(panel, BorderLayout.CENTER);
180 | }
181 |
182 | public void configure(TestElement el) {
183 | log.debug("Congiguring for el: " + el.toString());
184 | super.configure(el);
185 | RestSampler sampler = (RestSampler) el;
186 | body.setText(sampler.getRequestBody());
187 | headers.setText(sampler.getRequestHeaders());
188 | useKeepAlive.setSelected(sampler.getUseKeepAlive());
189 | automaticRedirect.setSelected(sampler.getAutoRedirects());
190 | httpMethods.setText(sampler.getMethod());
191 | resource.setText(sampler.getResource());
192 | queryString.setText(sampler.getQueryString());
193 | encoding.setText(sampler.getContentEncoding());
194 | hostBaseUrl.setText(sampler.getHostBaseUrl());
195 | }
196 |
197 | public Dimension getPreferredSize() {
198 | return getMinimumSize();
199 | }
200 | }
--------------------------------------------------------------------------------
/JMeterRestSampler/ant-jmeter-1.0.9.license:
--------------------------------------------------------------------------------
1 | Files from ant-jmeter-1.0.9.jar have been modified for extensibility.
2 | Original files available here: http://www.programmerplanet.org/pages/projects/jmeter-ant-task.php
3 | ant-jmeter-1.0.9.jar is licensed under Apache 2.0
4 |
5 | =================
6 |
7 | Apache License
8 | Version 2.0, January 2004
9 | http://www.apache.org/licenses/
10 |
11 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
12 |
13 | 1. Definitions.
14 |
15 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
16 |
17 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
18 |
19 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
20 |
21 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
22 |
23 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
24 |
25 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
26 |
27 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
28 |
29 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
30 |
31 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
32 |
33 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
34 |
35 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
36 |
37 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
38 |
39 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
40 |
41 | 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
42 |
43 | 2. You must cause any modified files to carry prominent notices stating that You changed the files; and
44 |
45 | 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
46 |
47 | 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
48 |
49 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
50 |
51 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
52 |
53 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
54 |
55 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
56 |
57 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
58 |
59 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
60 |
61 | END OF TERMS AND CONDITIONS
62 |
63 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/gui/ChartWrapper.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 | package smartrics.jmeter.sampler.gui;
15 |
16 | import java.awt.Color;
17 | import java.awt.Graphics;
18 | import java.awt.Graphics2D;
19 | import java.awt.Paint;
20 | import java.awt.Shape;
21 | import java.awt.Stroke;
22 | import java.awt.geom.Ellipse2D;
23 | import java.awt.image.BufferedImage;
24 | import java.util.ArrayList;
25 | import java.util.HashMap;
26 | import java.util.List;
27 | import java.util.Map;
28 | import java.util.TreeMap;
29 |
30 | import org.apache.jorphan.logging.LoggingManager;
31 | import org.apache.log.Logger;
32 | import org.jCharts.Chart;
33 | import org.jCharts.axisChart.AxisChart;
34 | import org.jCharts.axisChart.customRenderers.axisValue.renderers.ValueLabelPosition;
35 | import org.jCharts.axisChart.customRenderers.axisValue.renderers.ValueLabelRenderer;
36 | import org.jCharts.chartData.AxisChartDataSet;
37 | import org.jCharts.chartData.ChartDataException;
38 | import org.jCharts.chartData.DataSeries;
39 | import org.jCharts.properties.AxisProperties;
40 | import org.jCharts.properties.ChartProperties;
41 | import org.jCharts.properties.DataAxisProperties;
42 | import org.jCharts.properties.LabelAxisProperties;
43 | import org.jCharts.properties.LegendProperties;
44 | import org.jCharts.properties.LineChartProperties;
45 | import org.jCharts.properties.PropertyException;
46 | import org.jCharts.types.ChartType;
47 |
48 | /**
49 | * Wraps a jChart graph on a simpler interface. The graph is represented as an
50 | * area chart for the data in column 1 and a line chart for data in column 2.
51 | */
52 | public class ChartWrapper {
53 |
54 | private static final long serialVersionUID = 8263438417891736098L;
55 | private Map rawData = new TreeMap();
56 |
57 | private static final Logger log = LoggingManager.getLoggerForClass();
58 |
59 | private final static ChartType[] chartTypes = new ChartType[] { ChartType.AREA, ChartType.LINE, ChartType.BAR, ChartType.POINT };
60 | private final static Color[] colours = new Color[] { Color.ORANGE, Color.BLUE, Color.RED, Color.GREEN };
61 | private final static int poolsLength = chartTypes.length;
62 |
63 | protected String title, xAxisTitle, yAxisTitle;
64 | protected String[] yAxisLabels;
65 | protected int width, height;
66 | protected Chart chart;
67 | protected BufferedImage image;
68 | private int xAxisScalingFactor = 1;
69 |
70 | /**
71 | *
72 | */
73 | public ChartWrapper() {
74 | super();
75 | }
76 |
77 | public int getWidth() {
78 | return width;
79 | }
80 |
81 | public int getHeight() {
82 | return height;
83 | }
84 |
85 | public void putRawData(Long key, Long val) {
86 | if (rawData == null)
87 | rawData = new HashMap();
88 | rawData.put(key, val);
89 | }
90 |
91 | public void setXAxisScalingFactor(int xAsf) {
92 | this.xAxisScalingFactor = xAsf;
93 | }
94 |
95 | public Chart getChart() {
96 | return chart;
97 | }
98 |
99 | public String getTitle() {
100 | return title;
101 | }
102 |
103 | public void setTitle(String title) {
104 | this.title = title;
105 | }
106 |
107 | public void setXAxisTitle(String title) {
108 | this.xAxisTitle = title;
109 | }
110 |
111 | public void setYAxisTitle(String title) {
112 | this.yAxisTitle = title;
113 | }
114 |
115 | public void setYAxisLabels(String[] label) {
116 | this.yAxisLabels = label;
117 | }
118 |
119 | public void setWidth(int w) {
120 | this.width = w;
121 | }
122 |
123 | public void setHeight(int h) {
124 | this.height = h;
125 | }
126 |
127 | public void drawData() {
128 | if (image == null) {
129 | image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
130 | }
131 | Graphics2D graphics = image.createGraphics();
132 | drawData(graphics);
133 | }
134 |
135 | public void drawData(Graphics g) {
136 | if (getWidth() == 0) {
137 | log.warn("Width is 0 - nothing to draw");
138 | }
139 | if (getHeight() == 0) {
140 | log.warn("Height is 0 - nothing to draw");
141 | }
142 | if (rawData == null) {
143 | log.warn("Nothing to draw");
144 | return;
145 | }
146 | if (title == null)
147 | title = "Graph";
148 | if (this.xAxisTitle == null)
149 | xAxisTitle = "X Axis Title";
150 | if (this.yAxisTitle == null)
151 | yAxisTitle = "Y Axis Title";
152 | render(g);
153 | }
154 |
155 | private void render(Graphics g) {
156 | try {
157 | String[] xAxisLabels = formattedKeys();
158 | DataSeries dataSeries = new DataSeries(xAxisLabels, xAxisTitle, yAxisTitle, title);
159 | LineChartProperties lineChartProperties = createLineChartProperties();
160 | double data[][] = createDatasetWithAverage();
161 | for (int i = 0; i < data.length; i++) {
162 | String[] legendLabelsData = { yAxisLabels[i] };
163 | Paint[] paints = new Paint[] { colours[i % poolsLength] };
164 | double[][] extracted = extract(i, data);
165 | AxisChartDataSet axisChartDataSet = new AxisChartDataSet(extracted, legendLabelsData, paints, chartTypes[i % poolsLength], lineChartProperties);
166 | dataSeries.addIAxisPlotDataSet(axisChartDataSet);
167 | }
168 | chart = createAxisChart(dataSeries);
169 | chart.setGraphics2D((Graphics2D) g);
170 | chart.render();
171 |
172 | } catch (ChartDataException e) {
173 | log.warn("Chart Data Exception", e);
174 | } catch (PropertyException e) {
175 | log.warn("Property Exception", e);
176 | }
177 | }
178 |
179 | private Chart createAxisChart(DataSeries dataSeries) {
180 | DataAxisProperties yaxis = new DataAxisProperties();
181 | yaxis.setShowGridLines(1);
182 |
183 | LabelAxisProperties xaxis = new LabelAxisProperties();
184 | xaxis.setShowGridLines(1);
185 |
186 | AxisProperties axisProperties = new AxisProperties(xaxis, yaxis);
187 | axisProperties.setXAxisLabelsAreVertical(true);
188 |
189 | LegendProperties legendProperties = new LegendProperties();
190 | ChartProperties chartProperties = new ChartProperties();
191 | return new AxisChart(dataSeries, chartProperties, axisProperties, legendProperties, width, height);
192 | }
193 |
194 | private LineChartProperties createLineChartProperties() {
195 | ValueLabelRenderer valueLabelRenderer = new ValueLabelRenderer(false, false, true, 0);
196 | valueLabelRenderer.setValueLabelPosition(ValueLabelPosition.AT_TOP);
197 | valueLabelRenderer.useVerticalLabels(true);
198 |
199 | Ellipse2D.Double dot = new Ellipse2D.Double(0.0D, 0.0D, 2D, 2D);
200 | Shape[] shapes = { dot };
201 |
202 | Stroke[] strokes = { LineChartProperties.DEFAULT_LINE_STROKE };
203 |
204 | LineChartProperties lineChartProperties = new LineChartProperties(strokes, shapes);
205 | lineChartProperties.addPostRenderEventListener(valueLabelRenderer);
206 | return lineChartProperties;
207 | }
208 |
209 | private double[][] extract(int index, double[][] _data) {
210 | double[][] d = new double[1][_data[0].length];
211 | for (int i = 0; i < _data[index].length; i++) {
212 | d[0][i] = _data[index][i];
213 | }
214 | return d;
215 | }
216 |
217 | protected String[] formattedKeys() {
218 | List fk = new ArrayList();
219 | Long k0 = -1L;
220 | for (Long k : rawData.keySet()) {
221 | if (k0 == -1)
222 | k0 = k;
223 | // transform to double to the first decimal digit.
224 | long etMs = k.longValue() - k0.longValue();
225 | long etSec = etMs / xAxisScalingFactor;
226 | String et = new Long(etSec).toString();
227 | fk.add(et);
228 | }
229 | return fk.toArray(new String[fk.size()]);
230 | }
231 |
232 | private double[][] createDatasetWithAverage() {
233 | List data = getDataValues();
234 | double[][] dataset = new double[2][data.size()];
235 | double avg = 0;
236 | for (int idx = 0; idx < data.size(); idx++) {
237 | dataset[0][idx] = data.get(idx);
238 | avg += dataset[0][idx];
239 | double val = avg / (idx + 1);
240 | dataset[1][idx] = val;
241 | }
242 | return dataset;
243 | }
244 |
245 | private List getDataValues() {
246 | List data = new ArrayList();
247 | for (Long l : rawData.keySet()) {
248 | data.add(rawData.get(l));
249 | }
250 | return data;
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/JMeterRestSampler/etc/Rest Sampler.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | false
17 | 100
18 |
19 | 100
20 | 1
21 | 1228178137000
22 | 1228178137000
23 | false
24 | continue
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | <resource>
34 | <name>a resource name</name>
35 | <data>${__Random(0, 1000, data)}</data>
36 | </resource>
37 |
38 | POST
39 | true
40 | false
41 | http
42 | localhost
43 | 8765
44 | http://localhost:8765
45 | /resources/
46 | UTF-8
47 |
48 | header1=value1
49 | header2=value2
50 |
51 |
52 |
53 | true
54 | id
55 | Location\s*:.*\/(\d+)
56 | $1$
57 |
58 | 1
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | GET
68 | true
69 | true
70 | http
71 | localhost
72 | 8765
73 | http://localhost:8765
74 | /resources/${id}
75 | UTF-8
76 |
77 | header1=value1
78 |
79 |
80 |
81 |
82 |
83 |
84 | <resource>
85 | <name>a resource name - updated</name>
86 | <data>this var is defined in the POST: ${data}</data>
87 | </resource>
88 |
89 | PUT
90 | true
91 | false
92 | http
93 | localhost
94 | 8765
95 | http://localhost:8765
96 | /resources/${id}
97 | UTF-8
98 |
99 | header1=value1
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | DELETE
108 | true
109 | true
110 | http
111 | localhost
112 | 8765
113 | http://localhost:8765
114 | /resources/${id}
115 | UTF-8
116 |
117 |
118 |
119 |
120 |
121 | false
122 |
123 | saveConfig
124 |
125 |
126 | true
127 | true
128 | true
129 |
130 | true
131 | true
132 | true
133 | true
134 | false
135 | true
136 | true
137 | false
138 | false
139 | true
140 | false
141 | false
142 | false
143 | false
144 | false
145 | 0
146 | true
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/sampler/RestSampler.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2009 Fabrizio Cannizzo
2 | *
3 | * This file is part of JMeterRestSampler.
4 | *
5 | * JMeterRestSampler (http://code.google.com/p/rest-fixture/) is free software:
6 | * you can redistribute it and/or modify it under the terms of the
7 | * BSD License
8 | *
9 | * You should have received a copy of the BSD License
10 | * along with JMeterRestSampler. If not, see .
11 | *
12 | * If you want to contact the author please see http://smartrics.blogspot.com
13 | */
14 |
15 | package smartrics.jmeter.sampler;
16 |
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 | import java.net.MalformedURLException;
20 | import java.net.URL;
21 | import java.util.zip.GZIPInputStream;
22 |
23 | import org.apache.commons.httpclient.Header;
24 | import org.apache.commons.httpclient.HttpClient;
25 | import org.apache.commons.httpclient.HttpMethodBase;
26 | import org.apache.commons.httpclient.methods.DeleteMethod;
27 | import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
28 | import org.apache.commons.httpclient.methods.GetMethod;
29 | import org.apache.commons.httpclient.methods.HeadMethod;
30 | import org.apache.commons.httpclient.methods.OptionsMethod;
31 | import org.apache.commons.httpclient.methods.PostMethod;
32 | import org.apache.commons.httpclient.methods.PutMethod;
33 | import org.apache.commons.httpclient.methods.TraceMethod;
34 | import org.apache.jmeter.protocol.http.control.CacheManager;
35 | import org.apache.jmeter.protocol.http.sampler.HTTPSampleResult;
36 | import org.apache.jmeter.protocol.http.sampler.HTTPSampler2;
37 | import org.apache.jmeter.protocol.http.util.EncoderCache;
38 | import org.apache.jorphan.logging.LoggingManager;
39 | import org.apache.jorphan.util.JOrphanUtils;
40 | import org.apache.log.Logger;
41 |
42 | /**
43 | * Models a REST request for sampling purposes.
44 | */
45 | public class RestSampler extends HTTPSampler2 {
46 | private static final long serialVersionUID = -5877623539165274730L;
47 |
48 | private static final Logger log = LoggingManager.getLoggerForClass();
49 |
50 | public static final String REQUEST_BODY = "RestSampler.request_body";
51 |
52 | public static final String QUERY_STRING = "RestSampler.query_string";
53 |
54 | public static final String RESOURCE = "RestSampler.resource";
55 |
56 | public static final String BASE_HOST = "RestSampler.base_host";
57 |
58 | public static final String REQUEST_HEADERS = "RestSampler.request_headers";
59 |
60 | public RestSampler() {
61 | log.debug("initialised new RestSampler");
62 | }
63 |
64 | public void setRequestBody(String data) {
65 | setProperty(REQUEST_BODY, data);
66 | }
67 |
68 | public void setRequestHeaders(String headers) {
69 | setProperty(REQUEST_HEADERS, headers);
70 | }
71 |
72 | public String getRequestBody() {
73 | return getPropertyAsString(REQUEST_BODY);
74 | }
75 |
76 | public String getRequestHeaders() {
77 | return getPropertyAsString(REQUEST_HEADERS);
78 | }
79 |
80 | public void setResource(String data) {
81 | setProperty(RESOURCE, data);
82 | }
83 |
84 | public String getResource() {
85 | return getPropertyAsString(RESOURCE);
86 | }
87 |
88 | public void setQueryString(String data) {
89 | setProperty(QUERY_STRING, data);
90 | getArguments().clear();
91 | parseArguments(data, EncoderCache.URL_ARGUMENT_ENCODING);
92 | }
93 |
94 | public String getQueryString() {
95 | return getPropertyAsString(QUERY_STRING);
96 | }
97 |
98 | public void setHostBaseUrl(final String data) {
99 | setProperty(BASE_HOST, data);
100 | }
101 |
102 | public String getHostBaseUrl() {
103 | return getPropertyAsString(BASE_HOST);
104 | }
105 |
106 | /**
107 | * Returns the full resource URI concatenating the base url and the resource
108 | * id. If either components are missing or invalid, it returns a canned
109 | * value of "http://undefined.com"
110 | */
111 | public URL getUrl() {
112 | String validHost = toValidUrl(getHostBaseUrl());
113 | URL u = toURL("http://undefined.com");
114 | if (validHost != null && getResource() != null) {
115 | String fullUrl = validHost + getResource();
116 | u = toURL(fullUrl);
117 | }
118 | return u;
119 | }
120 |
121 | public String toString() {
122 | return "Base host url: " + getHostBaseUrl() + ", resource: " + getResource() + ", Method: " + getMethod();
123 | }
124 |
125 | private String toValidUrl(String u) {
126 | try {
127 | URL url = new URL(u);
128 | String urlStr = url.toString();
129 | if (urlStr.endsWith("/")) {
130 | url = toURL(urlStr.substring(0, urlStr.length() - 1));
131 | urlStr = url.toString();
132 | }
133 | return urlStr;
134 | } catch (MalformedURLException e) {
135 | return null;
136 | }
137 | }
138 |
139 | private URL toURL(String u) {
140 | try {
141 | return new URL(u);
142 | } catch (MalformedURLException e) {
143 | return null;
144 | }
145 | }
146 |
147 | private void overrideHeaders(HttpMethodBase httpMethod) {
148 | String headers = getRequestHeaders();
149 | String[] header = headers.split(System.getProperty("line.separator"));
150 | for (String kvp : header) {
151 | int pos = kvp.indexOf(':');
152 | if (pos < 0)
153 | pos = kvp.indexOf('=');
154 | if (pos > 0) {
155 | String k = kvp.substring(0, pos).trim();
156 | String v = "";
157 | if (kvp.length() > pos + 1)
158 | v = kvp.substring(pos + 1).trim();
159 | httpMethod.addRequestHeader(k, v);
160 | }
161 | }
162 | }
163 |
164 | /**
165 | * Method invoked by JMeter when a sample needs to happen. It's actually an
166 | * indirect call from the main sampler interface. it's resolved in the base
167 | * class.
168 | *
169 | * This is a copy and paste from the HTTPSampler2 - quick and dirty hack as
170 | * that class is not very extensible. The reason to extend and slightly
171 | * modify is that I needed to get the body content from a text field in the
172 | * GUI rather than a file.
173 | */
174 | protected HTTPSampleResult sample(URL url, String method, boolean areFollowingRedirect, int frameDepth) {
175 |
176 | String urlStr = url.toString();
177 |
178 | log.debug("Start : sample " + urlStr);
179 | log.debug("method " + method);
180 |
181 | HttpMethodBase httpMethod = null;
182 |
183 | HTTPSampleResult res = new HTTPSampleResult();
184 | res.setMonitor(isMonitor());
185 |
186 | res.setSampleLabel(urlStr); // May be replaced later
187 | res.setHTTPMethod(method);
188 | res.setURL(url);
189 | res.sampleStart(); // Count the retries as well in the time
190 | HttpClient client = null;
191 | InputStream instream = null;
192 | try {
193 | httpMethod = createHttpMethod(method, urlStr);
194 | // Set any default request headers
195 | setDefaultRequestHeaders(httpMethod);
196 | // Setup connection
197 | client = setupConnection(url, httpMethod, res);
198 | // Handle the various methods
199 | if (httpMethod instanceof EntityEnclosingMethod) {
200 | String postBody = sendData((EntityEnclosingMethod) httpMethod);
201 | res.setResponseData(postBody.getBytes());
202 | }
203 | overrideHeaders(httpMethod);
204 | res.setRequestHeaders(getConnectionHeaders(httpMethod));
205 |
206 | int statusCode = -1;
207 | try {
208 | statusCode = client.executeMethod(httpMethod);
209 | } catch (RuntimeException e) {
210 | log.error("Exception when executing '" + httpMethod + "'", e);
211 | throw e;
212 | }
213 |
214 | // Request sent. Now get the response:
215 | instream = httpMethod.getResponseBodyAsStream();
216 |
217 | if (instream != null) {// will be null for HEAD
218 |
219 | Header responseHeader = httpMethod.getResponseHeader(HEADER_CONTENT_ENCODING);
220 | if (responseHeader != null && ENCODING_GZIP.equals(responseHeader.getValue())) {
221 | instream = new GZIPInputStream(instream);
222 | }
223 | res.setResponseData(readResponse(res, instream, (int) httpMethod.getResponseContentLength()));
224 | }
225 |
226 | res.sampleEnd();
227 | // Done with the sampling proper.
228 |
229 | // Now collect the results into the HTTPSampleResult:
230 |
231 | res.setSampleLabel(httpMethod.getURI().toString());
232 | // Pick up Actual path (after redirects)
233 |
234 | res.setResponseCode(Integer.toString(statusCode));
235 | res.setSuccessful(isSuccessCode(statusCode));
236 |
237 | res.setResponseMessage(httpMethod.getStatusText());
238 |
239 | String ct = null;
240 | org.apache.commons.httpclient.Header h = httpMethod.getResponseHeader(HEADER_CONTENT_TYPE);
241 | if (h != null)// Can be missing, e.g. on redirect
242 | {
243 | ct = h.getValue();
244 | res.setContentType(ct);// e.g. text/html; charset=ISO-8859-1
245 | res.setEncodingAndType(ct);
246 | }
247 |
248 | String responseHeaders = getResponseHeaders(httpMethod);
249 | res.setResponseHeaders(responseHeaders);
250 | if (res.isRedirect()) {
251 | final Header headerLocation = httpMethod.getResponseHeader(HEADER_LOCATION);
252 | if (headerLocation == null) { // HTTP protocol violation, but
253 | // avoids NPE
254 | throw new IllegalArgumentException("Missing location header");
255 | }
256 | res.setRedirectLocation(headerLocation.getValue());
257 | }
258 |
259 | // If we redirected automatically, the URL may have changed
260 | if (getAutoRedirects()) {
261 | res.setURL(new URL(httpMethod.getURI().toString()));
262 | }
263 |
264 | // Store any cookies received in the cookie manager:
265 | saveConnectionCookies(httpMethod, res.getURL(), getCookieManager());
266 |
267 | // Save cache information
268 | final CacheManager cacheManager = getCacheManager();
269 | if (cacheManager != null) {
270 | cacheManager.saveDetails(httpMethod, res);
271 | }
272 |
273 | // Follow redirects and download page resources if appropriate:
274 | res = resultProcessing(areFollowingRedirect, frameDepth, res);
275 |
276 | log.debug("End : sample");
277 | httpMethod.releaseConnection();
278 | return res;
279 | } catch (IllegalArgumentException e)// e.g. some kinds of invalid URL
280 | {
281 | res.sampleEnd();
282 | HTTPSampleResult err = errorResult(e, res);
283 | err.setSampleLabel("Error: " + url.toString());
284 | return err;
285 | } catch (IOException e) {
286 | res.sampleEnd();
287 | HTTPSampleResult err = errorResult(e, res);
288 | err.setSampleLabel("Error: " + url.toString());
289 | return err;
290 | } finally {
291 | JOrphanUtils.closeQuietly(instream);
292 | if (httpMethod != null) {
293 | httpMethod.releaseConnection();
294 | }
295 | }
296 | }
297 |
298 | private HttpMethodBase createHttpMethod(String method, String urlStr) {
299 | HttpMethodBase httpMethod;
300 | // May generate IllegalArgumentException
301 | if (method.equals(POST)) {
302 | httpMethod = new PostMethod(urlStr);
303 | } else if (method.equals(PUT)) {
304 | httpMethod = new PutMethod(urlStr);
305 | } else if (method.equals(HEAD)) {
306 | httpMethod = new HeadMethod(urlStr);
307 | } else if (method.equals(TRACE)) {
308 | httpMethod = new TraceMethod(urlStr);
309 | } else if (method.equals(OPTIONS)) {
310 | httpMethod = new OptionsMethod(urlStr);
311 | } else if (method.equals(DELETE)) {
312 | httpMethod = new DeleteMethod(urlStr);
313 | } else if (method.equals(GET)) {
314 | httpMethod = new GetMethod(urlStr);
315 | } else {
316 | log.error("Unexpected method (converted to GET): " + method);
317 | httpMethod = new GetMethod(urlStr);
318 | }
319 | return httpMethod;
320 | }
321 |
322 | /**
323 | * Set up the PUT/POST data.
324 | *
325 | * TODO: should parse request headers and pass the Content-Type. For
326 | * now it will always assume text/xml
327 | */
328 | private String sendData(EntityEnclosingMethod method) throws IOException {
329 | method.setRequestEntity(new MyRequestEntity(getRequestBody()));
330 | return getRequestBody();
331 | }
332 |
333 | }
334 |
--------------------------------------------------------------------------------
/JMeterRestSampler/src/main/java/smartrics/jmeter/ant/JMeterTask.java:
--------------------------------------------------------------------------------
1 | /*
2 | * File modified to enable for extensibility.
3 | * Original copy available in ant-jmeter-1.0.9.jar obtained at
4 | * http://www.programmerplanet.org/pages/projects/jmeter-ant-task.php
5 | * Changelog
6 | * - repackaged in smartrics.jmeter.ant
7 | * - checkForFailures() made protected
8 | *
9 | * Copyright 2007 Joseph Fifield
10 | *
11 | * Licensed under the Apache License, Version 2.0 (the "License");
12 | * you may not use this file except in compliance with the License.
13 | * You may obtain a copy of the License at
14 | *
15 | * http://www.apache.org/licenses/LICENSE-2.0
16 | *
17 | * Unless required by applicable law or agreed to in writing, software
18 | * distributed under the License is distributed on an "AS IS" BASIS,
19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | * See the License for the specific language governing permissions and
21 | * limitations under the License.
22 | */
23 | package smartrics.jmeter.ant;
24 |
25 | import java.io.File;
26 | import java.io.FileReader;
27 | import java.io.IOException;
28 | import java.io.LineNumberReader;
29 | import java.util.ArrayList;
30 | import java.util.Iterator;
31 |
32 | import org.apache.tools.ant.BuildException;
33 | import org.apache.tools.ant.DirectoryScanner;
34 | import org.apache.tools.ant.Project;
35 | import org.apache.tools.ant.Task;
36 | import org.apache.tools.ant.taskdefs.Execute;
37 | import org.apache.tools.ant.taskdefs.LogStreamHandler;
38 | import org.apache.tools.ant.types.CommandlineJava;
39 | import org.apache.tools.ant.types.FileSet;
40 |
41 | public class JMeterTask extends Task {
42 |
43 | /**
44 | * The JMeter installation directory.
45 | */
46 | private File jmeterHome;
47 |
48 | /**
49 | * The property file to use.
50 | */
51 | private File jmeterProperties;
52 |
53 | /**
54 | * The test plan to execute.
55 | */
56 | private File testPlan;
57 |
58 | /**
59 | * The file to log results to.
60 | */
61 | private File resultLog;
62 |
63 | /**
64 | * The directory need to save all result log files.
65 | */
66 | private File resultLogDir;
67 |
68 | /**
69 | * A collection of FileSets specifying test plans to execute.
70 | */
71 | private ArrayList