Skip to content

Commit 57e6bd1

Browse files
committed
Initial version
1 parent c3a6949 commit 57e6bd1

File tree

6 files changed

+349
-0
lines changed

6 files changed

+349
-0
lines changed

.classpath

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" output="target/classes" path="src/main/java">
4+
<attributes>
5+
<attribute name="optional" value="true"/>
6+
<attribute name="maven.pomderived" value="true"/>
7+
</attributes>
8+
</classpathentry>
9+
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
10+
<attributes>
11+
<attribute name="optional" value="true"/>
12+
<attribute name="maven.pomderived" value="true"/>
13+
</attributes>
14+
</classpathentry>
15+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
16+
<attributes>
17+
<attribute name="maven.pomderived" value="true"/>
18+
</attributes>
19+
</classpathentry>
20+
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
21+
<attributes>
22+
<attribute name="maven.pomderived" value="true"/>
23+
</attributes>
24+
</classpathentry>
25+
<classpathentry kind="output" path="target/classes"/>
26+
</classpath>

.project

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>jmeter-custom-samplers</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
<buildCommand>
14+
<name>org.eclipse.m2e.core.maven2Builder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
18+
</buildSpec>
19+
<natures>
20+
<nature>org.eclipse.jdt.core.javanature</nature>
21+
<nature>org.eclipse.m2e.core.maven2Nature</nature>
22+
</natures>
23+
</projectDescription>

.settings/org.eclipse.jdt.core.prefs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
eclipse.preferences.version=1
2+
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
3+
org.eclipse.jdt.core.compiler.compliance=1.6
4+
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
5+
org.eclipse.jdt.core.compiler.source=1.6

.settings/org.eclipse.m2e.core.prefs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
activeProfiles=
2+
eclipse.preferences.version=1
3+
resolveWorkspaceProjects=true
4+
version=1

pom.xml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<properties>
8+
<rsyntaxtextarea.version>2.5.0</rsyntaxtextarea.version>
9+
</properties>
10+
11+
<groupId>com.comulentlabs</groupId>
12+
<packaging>jar</packaging>
13+
<version>0.0.1-SNAPSHOT</version>
14+
<artifactId>jmeter-custom-components</artifactId>
15+
<name>Cromulent Labs JMeter custom components</name>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>org.apache.jmeter</groupId>
20+
<artifactId>ApacheJMeter_java</artifactId>
21+
<!--
22+
Need to harmonize with the version that the jmeter-maven-plugin uses,
23+
1.4 -> 2.6
24+
-->
25+
<version>2.11</version>
26+
</dependency>
27+
<dependency>
28+
<groupId>org.apache.jmeter</groupId>
29+
<artifactId>ApacheJMeter_http</artifactId>
30+
<version>2.11</version>
31+
</dependency>
32+
<dependency>
33+
<groupId>com.fifesoft</groupId>
34+
<artifactId>rsyntaxtextarea</artifactId>
35+
<version>${rsyntaxtextarea.version}</version>
36+
<scope>runtime</scope>
37+
</dependency>
38+
</dependencies>
39+
40+
</project>
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
package com.cromulentlabs.appengine.cloudendpoints;
2+
3+
import java.io.BufferedReader;
4+
import java.io.File;
5+
import java.io.FileNotFoundException;
6+
import java.io.FileReader;
7+
import java.io.FilenameFilter;
8+
import java.io.IOException;
9+
import java.util.ArrayList;
10+
import java.util.Arrays;
11+
import java.util.Comparator;
12+
import java.util.List;
13+
import java.util.regex.Matcher;
14+
import java.util.regex.Pattern;
15+
16+
import org.apache.jmeter.config.Arguments;
17+
import org.apache.jmeter.protocol.http.control.Header;
18+
import org.apache.jmeter.protocol.http.control.HeaderManager;
19+
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
20+
import org.apache.jmeter.protocol.http.util.HTTPArgument;
21+
import org.apache.jmeter.protocol.http.util.accesslog.Filter;
22+
import org.apache.jmeter.protocol.http.util.accesslog.LogParser;
23+
import org.apache.jmeter.testelement.TestElement;
24+
import org.apache.jmeter.testelement.property.TestElementProperty;
25+
import org.apache.jorphan.logging.LoggingManager;
26+
import org.apache.log.Logger;
27+
28+
public class GoogleCloudEndpointsLogParser implements LogParser
29+
{
30+
protected static final Logger log = LoggingManager.getLoggerForClass();
31+
protected static final Pattern INPUT_FILE_PATTERN = Pattern.compile("^fetch_(\\d+)\\.txt$");
32+
protected static final Pattern REQUEST_LINE_PATTERN = Pattern.compile("^Request: ([A-Z]+) (.*)$");
33+
34+
protected String sourceDirectory = null;
35+
protected File[] sourceFiles = null;
36+
protected BufferedReader[] sourceReaders = null;
37+
protected int currentFilePointer = 0;
38+
39+
@Override
40+
public void close()
41+
{
42+
if (this.sourceReaders != null)
43+
{
44+
for (BufferedReader reader : this.sourceReaders)
45+
{
46+
if (reader != null)
47+
{
48+
try
49+
{
50+
reader.close();
51+
}
52+
catch (Exception e)
53+
{
54+
log.warn("Unable to close reader", e);
55+
}
56+
}
57+
}
58+
}
59+
}
60+
61+
@Override
62+
public int parseAndConfigure(int count, TestElement el)
63+
{
64+
log.info("sourceDirectory = " + this.sourceDirectory);
65+
if (this.sourceDirectory == null)
66+
{
67+
return -1;
68+
}
69+
if (this.sourceFiles == null)
70+
{
71+
File rootDir = new File(sourceDirectory);
72+
if (!rootDir.isDirectory())
73+
{
74+
throw new RuntimeException("Source File must be directory");
75+
}
76+
this.sourceFiles = rootDir.listFiles(new FilenameFilter()
77+
{
78+
public boolean accept(File dir, String name)
79+
{
80+
if (INPUT_FILE_PATTERN.matcher(name).matches())
81+
{
82+
return true;
83+
}
84+
return false;
85+
}
86+
});
87+
Arrays.sort(this.sourceFiles, new Comparator<File>() {
88+
@Override
89+
public int compare(File f0, File f1)
90+
{
91+
return new Integer(parseFileInputNumber(f0.getName())).compareTo(parseFileInputNumber(f1.getName()));
92+
}
93+
});
94+
this.sourceReaders = new BufferedReader[this.sourceFiles.length];
95+
for (int i = 0; i < this.sourceFiles.length; i++)
96+
{
97+
try
98+
{
99+
log.info("Opening file: " + this.sourceFiles[i]);
100+
this.sourceReaders[i] = new BufferedReader(new FileReader(this.sourceFiles[i]));
101+
}
102+
catch (FileNotFoundException e)
103+
{
104+
throw new RuntimeException("Hit exception attempting to open input file: " + this.sourceFiles[i] + ": " + e);
105+
}
106+
}
107+
}
108+
if (this.currentFilePointer < this.sourceReaders.length)
109+
{
110+
int i = 0;
111+
for (; i < count; i++)
112+
{
113+
BufferedReader reader = this.sourceReaders[this.currentFilePointer + i];
114+
try
115+
{
116+
log.info("Parsing file: " + this.sourceFiles[i]);
117+
parseFile(reader, el);
118+
}
119+
catch (IOException ioe) {
120+
log.error("Error reading log file", ioe);
121+
}
122+
}
123+
this.currentFilePointer += i;
124+
return i;
125+
}
126+
return -1;
127+
}
128+
129+
@Override
130+
public void setFilter(Filter filter)
131+
{
132+
// TODO Auto-generated method stub
133+
134+
}
135+
136+
@Override
137+
public void setSourceFile(String sourceFile)
138+
{
139+
this.sourceDirectory = sourceFile;
140+
}
141+
142+
private static int parseFileInputNumber(String filename)
143+
{
144+
int i = 0;
145+
Matcher m = INPUT_FILE_PATTERN.matcher(filename);
146+
if (m.matches())
147+
{
148+
String num = m.group(1);
149+
try
150+
{
151+
i = Integer.parseInt(num);
152+
}
153+
catch (NumberFormatException e)
154+
{
155+
// Ignore
156+
}
157+
}
158+
return i;
159+
}
160+
161+
private void parseFile(BufferedReader reader, TestElement el)
162+
throws IOException
163+
{
164+
boolean requestParsed = false;
165+
boolean inHeaders = false;
166+
boolean inRequest = false;
167+
List<Header> headers = new ArrayList<Header>();
168+
StringBuffer body = new StringBuffer();
169+
String line = null;
170+
while ((line = reader.readLine()) != null)
171+
{
172+
if (inHeaders)
173+
{
174+
if (line.trim().length() == 0)
175+
{
176+
inHeaders = false;
177+
HeaderManager hm = new HeaderManager();
178+
for (Header header : headers)
179+
{
180+
hm.add(header);
181+
}
182+
el.setProperty(new TestElementProperty(HTTPSamplerBase.HEADER_MANAGER, hm));
183+
}
184+
else
185+
{
186+
if (log.isDebugEnabled())
187+
{
188+
log.debug("Adding header: " + line);
189+
}
190+
if (line.contains(":"))
191+
{
192+
String[] headerParts = line.trim().split(":", 2);
193+
headers.add(new Header(headerParts[0], headerParts[1]));
194+
}
195+
}
196+
}
197+
else if (inRequest)
198+
{
199+
if (line.trim().length() == 0)
200+
{
201+
inRequest = false;
202+
if (log.isDebugEnabled())
203+
{
204+
log.debug("Setting post body: " + body);
205+
}
206+
el.setProperty(HTTPSamplerBase.POST_BODY_RAW, true);
207+
Arguments args = new Arguments();
208+
HTTPArgument argument = new HTTPArgument("", body.toString(), "", false, "UTF-8");
209+
argument.setAlwaysEncoded(false);
210+
args.addArgument(argument);
211+
el.setProperty(new TestElementProperty(HTTPSamplerBase.ARGUMENTS, args));
212+
break;
213+
}
214+
else
215+
{
216+
body.append(line);
217+
}
218+
}
219+
else if (!requestParsed)
220+
{
221+
if (log.isDebugEnabled())
222+
{
223+
log.debug("Checking line: " + line);
224+
}
225+
Matcher requestMatcher = REQUEST_LINE_PATTERN.matcher(line);
226+
if (requestMatcher.matches())
227+
{
228+
String method = requestMatcher.group(1);
229+
String url = requestMatcher.group(2);
230+
if (log.isDebugEnabled())
231+
{
232+
log.debug("Setting method = " + method + ", url = " + url);
233+
}
234+
el.setProperty(HTTPSamplerBase.METHOD, method);
235+
el.setProperty(HTTPSamplerBase.PATH, url);
236+
requestParsed = true;
237+
}
238+
}
239+
else if (line.contains("Request headers:"))
240+
{
241+
log.debug("inHeaders");
242+
inHeaders = true;
243+
}
244+
else if (line.contains("Request body:"))
245+
{
246+
log.debug("inRequest");
247+
inRequest = true;
248+
}
249+
}
250+
}
251+
}

0 commit comments

Comments
 (0)