Simple jetty server to record HTTP requests.
URLs
-
Project home (this page)
Do you want to improve this page? Please edit it on GitHub. |
Description
http-request-recorder
is a small tool that can be used to record HTTP requests.
It is based on Eclipse Jetty and runs on the JVM.
Recorded requests are available in memory (as RxJava stream), can be printed in the console or stored as JSON file on the disk.
Download
Binaries are hosted on maven central.
core
<dependency>
<groupId>com.unblu.tools</groupId>
<artifactId>http-request-recorder-core</artifactId>
<version>4.0.3</version>
</dependency>
"com.unblu.tools:http-request-recorder-core:4.0.3"
cli
<dependency>
<groupId>com.unblu.tools</groupId>
<artifactId>http-request-recorder-cli</artifactId>
<version>4.0.3</version>
</dependency>
"com.unblu.tools:http-request-recorder-cli:4.0.3"
cli (fat jar)
A standalone jar (containing the dependencies) is also published:
<dependency>
<groupId>com.unblu.tools</groupId>
<artifactId>http-request-recorder-cli</artifactId>
<version>4.0.3</version>
<classifier>all</classifier>
</dependency>
"com.unblu.tools:http-request-recorder-cli:4.0.3:all"
Usage
cli
You can start the server with:
java -jar libs/hrr.jar --log
Some usefull flags:
--log
: each request will be logged into the console
--port
: a fixed port for the server will be used
--output
: stores each request as json file (see example bellow).
The --tree
flag can be usefull to influence the way the files are stored.
Usage example:
Started with:
java -jar libs/hrr.jar --port 8090 --output out
For following requests:
GET http://localhost:8090/service1/ping POST http://localhost:8090/service1/ping POST http://localhost:8090/service1/check GET http://localhost:8090/service2
You will get one file per request in the out/
folder:
out/1542289573057-service1_ping.json out/1542289576028-service1_ping.json out/1542289591111-service1_check.json out/1542289607227-service2.json
With the --tree
flag the requested URI is used to separate the files in subfolders that correspond to the file.
The same requests will produce:
out |____service1 | |____ping | | |____1542289573057.json | | |____1542289576028.json | |____check | |____1542289591111.json |____service2 |____1542289607227.json
core
The core
can be embedded in an other java application (for example when used during some unit-tests).
Just include com.unblu.tools:http-request-recorder-core:$hrrVersion
as test dependency.
With server
being a com.unblu.tools.hrr.core.JettyServer
instance (that is created and started before the test execution and stopped after the test), a simple test can look like this:
//Access the request recorder:
Observable<RequestRecord> observable$ = server.onRequest();
//create test observer
TestObserver<RequestRecord> testObserver = observable$.test();
//Simple subscription: log the HTTP record as INFO log
observable$.map(RequestRecordConverter::asLog).subscribe(LOG::info);
//Perform a GET Request:
HttpURLConnection con = performPinGetRequest();
//Perform assertions on the server response:
int status = con.getResponseCode();
assertThat(status).isEqualTo(200);
String content = new BufferedReader(new InputStreamReader(con.getInputStream())).lines().collect(Collectors.joining("\n"));
assertThat(content).isEqualTo("{ \"status\": \"ok\"}");
//Perform assertions on the recorded server event:
testObserver.assertNoErrors().assertValueCount(1).assertValueAt(0, record -> {
assertThat(record.getMethod()).isEqualTo("GET");
assertThat(record.getRequestURI()).isEqualTo("/ping");
return true;
});
In this case onRequest is used, which only emits for events that happen after subscription.
Use getRequest to also get the last previous one:
//Access the request recorder:
Observable<RequestRecord> observable$ = server.getRequest();
//Perform a GET Request:
HttpURLConnection con = performPinGetRequest();
//Simple subscription: log the HTTP record as INFO log
//Retrieves still the last record
observable$.map(RequestRecordConverter::asLog).subscribe(LOG::info);
//Perform assertions on the server response:
int status = con.getResponseCode();
assertThat(status).isEqualTo(200);
String content = new BufferedReader(new InputStreamReader(con.getInputStream())).lines().collect(Collectors.joining("\n"));
assertThat(content).isEqualTo("{ \"status\": \"ok\"}");
//Perform assertions on the recorded server event:
observable$.test().assertNoErrors().assertValueCount(1).assertValueAt(0, record -> {
assertThat(record.getMethod()).isEqualTo("GET");
assertThat(record.getRequestURI()).isEqualTo("/ping");
return true;
});
With JUnit 5 the server can be managed like this (this is only one example, you might prefer to manage the server globally somewhere else)
@BeforeAll
public static void before() throws Exception {
server = new JettyServer();
server.start();
}
@AfterAll
public static void after() throws Exception {
server.stop();
}
Development
This project is tested with Eclipse IDE, it should however work with any other IDE as well.
Build
Build sources:
./gradlew build
Deploy to maven local:
./gradlew publishToMavenLocal
Build the documentation page:
./gradlew asciidoctor
Upload the documentation page on GitHub pages:
./gradlew gitPublishPush
Perform a release:
./gradlew release -Prelease.useAutomaticVersion=true
Using ssh-agent
Some tasks requires to push into the distant git repository (release task or updating the gh-pages
branch).
If they are failing with errors like this:
org.eclipse.jgit.api.errors.TransportException: ... Permission denied (publickey).
Then ssh-agent
can be used.
eval `ssh-agent -s` ssh-add ~/.ssh/id_rsa
(source for this approach)
Get in touch
Use the issue tracker on GitHub.
You can also contact me on Twitter: @j2r2b
License
Code is under Eclipse Public License - v 2.0.