{"id":21633772,"url":"https://github.com/dgroomes/http-client-server-playground","last_synced_at":"2026-04-14T01:31:14.324Z","repository":{"id":146626984,"uuid":"262942029","full_name":"dgroomes/http-client-server-playground","owner":"dgroomes","description":"📚 Learning and exploring various HTTP client and servers in the JVM eco-system: Netty, Jetty, Apache HTTP Components.","archived":false,"fork":false,"pushed_at":"2023-12-12T08:20:42.000Z","size":274,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-18T22:39:14.738Z","etag":null,"topics":["http4k","httpcomponents","java","jetty","jmeter","netty","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dgroomes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-11T04:54:20.000Z","updated_at":"2023-12-09T18:49:49.000Z","dependencies_parsed_at":"2023-12-12T08:38:04.712Z","dependency_job_id":null,"html_url":"https://github.com/dgroomes/http-client-server-playground","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dgroomes/http-client-server-playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgroomes%2Fhttp-client-server-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgroomes%2Fhttp-client-server-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgroomes%2Fhttp-client-server-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgroomes%2Fhttp-client-server-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dgroomes","download_url":"https://codeload.github.com/dgroomes/http-client-server-playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgroomes%2Fhttp-client-server-playground/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31778580,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T00:11:49.126Z","status":"ssl_error","status_checked_at":"2026-04-14T00:10:29.837Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http4k","httpcomponents","java","jetty","jmeter","netty","spring-boot"],"created_at":"2024-11-25T03:13:51.316Z","updated_at":"2026-04-14T01:31:14.284Z","avatar_url":"https://github.com/dgroomes.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# http-client-server-playground\n\n📚 Learning and exploring various HTTP client and servers in the JVM ecosystem: Netty, Jetty, Apache HTTP Components.\n\nNOTE: This is currently being re-tooled as an \"http-client-server-playground\". See the Wish List section. This is a work-in-progress.\n\n\n## Structure\n\nThis project includes simple usage examples of some Java-based HTTP client libraries, Java-based HTTP servers, and a\nJMeter load test. It is broken down into a collection of subprojects:\n\n* `clients/`\n  * A collection of simple usage examples of some Java-based HTTP client libraries \n  * `client-httpcomponents-v4`\n    * A usage example of [Apache HTTP Components](https://hc.apache.org/index.html) version 4.x.\n  * `client-httpcomponents-v5` \n    * A usage example of [Apache HTTP Components](https://hc.apache.org/index.html) version 5.x.\n* `client-jmeter-plugin/`\n* `client-runner/`\n* `servers/`\n    * `server-wiremock/`\n      * A WireMock mock HTTP server. \n    * `server-spring/`\n      * A simple Spring Boot app that serves as a mock HTTP server.\n    * `server-netty`\n      * A simple Netty server wrapped via the convenient [http4k toolkit](https://github.com/http4k/http4k). \n\n\n## Instructions\n\nFollow these instructions to run a scenario:\n\n1. Use Java 21\n2. Run a mock HTTP server:\n   * ```shell\n     ./gradlew servers:server-wiremock:run\n     ```\n   * Alternatively, run a mock HTTP server with different server tech using one of the following commands.\n   * ```shell\n     ./gradlew servers:server-spring:run\n     ```\n   * ```shell\n     ./gradlew servers:server-netty:run\n     ```\n   * ```shell\n     ./gradlew servers:server-jetty:run\n     ```\n   * ```shell\n     ./gradlew servers:server-micronaut:run\n     ```\n3. Execute a scenario for one of the HTTP client libraries:\n   * ```shell\n     ./gradlew client-runner:run --args 'httpcomponents-v4 single-request false'\n     ```\n   * Alternatively, try a different scenario and different client library. For example, use the following command.\n   * ```shell\n     ./gradlew client-runner:run --args 'httpcomponents-v5 multiple-requests true'\n     ```\n4. Observe the server statistics\n   * Open \u003chttp://localhost:8070/stats/\u003e in the browser\n   * Statistics include things like the number of responses with 200/300/400/500 status codes, the number of connections,\n     and the amount of memory used by the server.\n\n\n## `client-jmeter-plugin/`\n\nThis subproject enables using JMeter to define and execute test plans against the Apache HTTP Components code. It \nbuilds a JMeter plugin distribution.\n\nFollow these instructions to run the JMeter load test:\n\n1. Use Java 21\n2. Use JMeter 5.6.1\n3. Run a mock HTTP server:\n   * ```shell\n     ./gradlew servers:server-wiremock:run\n     ```\n4. Build the JMeter plugin distribution:\n   * ```shell\n     ./gradlew :client-jmeter-plugin:installDist\n     ```\n5. Run the load test:\n   * ```shell\n     ./run-jmeter-load-test.sh\n     ```\n6. Optionally, edit the test plan:\n   * ```shell\n     ./edit-jmeter-load-test.sh\n     ```\n   * And then repeat the earlier step to run the test again, as desired.\n\n\n## Wish List\n\nGeneral clean-ups, changes and things I wish to implement for this project:\n\n* [x] DONE Add a Jetty server example\n* [x] DONE Add a Netty server example\n* How can we get the Apache HttpComponents client to fail? How do we leak connections? I am curious to force a leak and\n  see how the system (client/server) behaves because connection leaks are a common thing in the real world and I want to\n  understand it better.\n* [ ] IN PROGRESS Re-tool this repo as a \"http-client-server-playground\" where multiple kinds of clients (Apache HttpComponents, OkHttp, Java\n  standard library's HttpClient, others?) can be tested against multiple kinds of servers (Jetty, Tomcat, Netty, maybe\n  Undertow).\n  * DONE Organize the clients\n  * IN PROGRESS Componentize/organize/modularize (whatever) the JMeter plugin modules. This is a bit tricky because there are\n    limited options for getting JMeter plugin and JMeter utility/library code on the classpath. See the [options listed in\n    the official docs](https://jmeter.apache.org/usermanual/get-started.html#classpath).\n  * SKIP? (The client-runner is ok as is. It already parameterizes the scenario/client types) Create a runner shell script, which let's you pick which client to use, and which \"scenarios\" and other options.\n  * DONE add a Spring Boot based server.\n* [x] DONE (latest JMeter supports Java 17 thankfully; I won't go to 21 any time soon) Upgrade to Java 17 but BE WARNED. I've tried this twice (in April 2022 and sometime earlier) and I think JMeter doesn't\n  work on Java 17. I get this error when I run the JMeter simulation:\n  ```text\n  Error generating the report: org.apache.jmeter.report.dashboard.GenerationException: Error while processing samples: Consumer failed with message :Consumer failed with message :Consumer failed with message :Consumer failed with message :Begin size 1 is not equal to fixed size 5\n  ```\n* [x] DONE Dependency upgrades for late 2023\n* [ ] Replace `dependency-constraints` with a TOML-based version catalog. Although consider if the `dependendency-constraints-jmeter`\n  actually serves a unique purpose that we can't get from a TOML-based version catalog. Maybe use two different version\n  catalogs?\n* [x] DONE Major upgrade to http4k 5.x\n* [ ] Major upgrade to WireMock 3.x\n* [x] DONE Upgrade to HttpComponents client 5.3.x\n* [x] DONE Consider upgrading to SLF4J 2.x (but the other dependencies, especially JMeter, might not be ready for it)\n* [ ] Upgrade Spring Boot to 3.x\n* [x] DONE Upgrade to Gradle 8.5\n\n\n## Notes\n\n* Check open file descriptors by port `lsof -p 123 | wc -l` \n  * Useful to detect connection leaks (I think)\n  * \u003chttps://stackoverflow.com/a/38732186\u003e\n* Stop JMeter test. It should stop gracefully (but it might still fail!) and produce the test reports\n  * `stoptest.sh` This script is in the JMeter installation's `/bin` dir\n* Issues relating to the statisticshandler and Jetty async\n  * \u003chttps://github.com/eclipse/jetty.project/issues/2717\u003e\n  * \u003chttps://www.eclipse.org/lists/jetty-dev/msg02886.html\u003e \n\n\n## Reference\n\n* \u003chttps://github.com/dgroomes/jmeter-playground\u003e\n  * This is my own project that shows, with commentary, how to run JMeter test with a custom plugin and with custom library\n    dependencies (i.e. `.jar` files).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgroomes%2Fhttp-client-server-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdgroomes%2Fhttp-client-server-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgroomes%2Fhttp-client-server-playground/lists"}