Skip to content

Add spring-aerospike: Aerospike-Java sample with Keploy record/replay#135

Open
Aditya-eddy wants to merge 1 commit into
mainfrom
add-spring-aerospike
Open

Add spring-aerospike: Aerospike-Java sample with Keploy record/replay#135
Aditya-eddy wants to merge 1 commit into
mainfrom
add-spring-aerospike

Conversation

@Aditya-eddy
Copy link
Copy Markdown
Member

Summary

  • New spring-aerospike/ sample — Spring Boot 2.7 + aerospike-client-jdk8, talks to Aerospike CE on clear-text 3000.
  • Java counterpart of keploy/samples-go/aerospike-tls. Endpoints and concurrency knobs are a one-to-one port (14 endpoints, two-phase warmup, generous per-op policy, app-level retry wrapper).
  • Three pipeline-ready scripts (scripts/script-{1,2,3}.sh) that record + replay one test-set each: CRUD, /parallel, /multiclient + /freshclient.
  • No bundled keploy/ — every script regenerates the test-set, so every CI run validates the full record→replay loop.

Depends on the Aerospike parser landing in keploy: keploy/keploy#4190 + keploy/integrations#194.

Test plan

  • mvn -q -DskipTests package clean
  • docker compose up -d aerospike healthy
  • ./scripts/script-1.sh → test-set-0: 8/8 pass
  • ./scripts/script-2.sh → test-set-1: 6/6 pass (/parallel?n=24 included)
  • ./scripts/script-3.sh → test-set-2: 8/8 pass (/multiclient?n=24 + /freshclient?n=8)

All three scripts validated locally with the dev keploy binary carrying the Aerospike parser before pushing.

🤖 Generated with Claude Code

Java counterpart of keploy/samples-go/aerospike-tls. A Spring Boot
2.7 service that talks to Aerospike CE on clear-text :3000 via the
aerospike-client-jdk8 driver, recorded and replayed end-to-end with
three bundled scripts that mirror the Go sample's shape one-to-one
(same endpoints, same test-set layout, same scripts).

Endpoints (full parity with the Go sample, 14 total):

  GET    /health
  POST   /put            GET    /get/{key}
  POST   /batch/put      GET    /batch/get
  POST   /scan           POST   /query
  POST   /udf            POST   /cdt/list/append  POST /cdt/map/put
  POST   /touch/{key}    DELETE /key/{key}
  POST   /parallel       POST   /multiclient      POST /freshclient

main.go's concurrency story is ported one-for-one:

  * ClientPolicy.maxConnsPerNode = 256, OpeningConnectionThreshold
    analogue set to 16 so bursts don't outpace upstream connect rate.
  * parallelWrite / parallelRead policies with socketTimeout 10s,
    totalTimeout 30s, maxRetries 10, sleepBetweenRetries 5ms.
  * Two-phase warmup on the main client at startup — sequential
    prelude walks the cluster past cold-start latencies, then a
    parallel fill puts idle connections in the pool before the
    HTTP server accepts the first request.
  * RetryHelper.doOp wraps each PUT and GET in /parallel,
    /multiclient, /freshclient.

scripts/ matches the Go sample's pipeline shape (common.sh +
script-{1,2,3}.sh + same env-var knobs: KEPLOY / PORT / LOG_DIR /
SKIP_DOCKER / SKIP_BUILD). Smoke-tested locally with the dev
keploy binary that carries the Aerospike parser:

  script-1.sh → test-set-0: 8/8 pass
  script-2.sh → test-set-1: 6/6 pass
  script-3.sh → test-set-2: 8/8 pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 11, 2026 12:44
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new spring-aerospike/ sample application to the repo: a Spring Boot service that uses the Aerospike Java client and includes Keploy-focused scripts to record and replay multiple test-sets (CRUD + concurrency-focused endpoints).

Changes:

  • Introduces a Spring Boot 2.7 Aerospike-backed service with CRUD, batch, maintenance, and concurrency endpoints (/parallel, /multiclient, /freshclient).
  • Adds Aerospike client configuration (pool sizing + warmup) plus per-operation policies and an app-level retry helper.
  • Adds Docker + Keploy config and 3 scripts to run record→replay loops for three separate test-sets.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
spring-aerospike/src/main/resources/application.properties Configures server port and Aerospike connection/pool + warmup settings.
spring-aerospike/src/main/java/com/example/aerospike/util/RetryHelper.java Adds an app-level retry wrapper used by concurrency endpoints.
spring-aerospike/src/main/java/com/example/aerospike/SpringAerospikeApplication.java Spring Boot application entrypoint.
spring-aerospike/src/main/java/com/example/aerospike/dto/PutRequest.java DTO for /put and other endpoints accepting JSON bins.
spring-aerospike/src/main/java/com/example/aerospike/controller/ParallelController.java Implements single-client concurrent PUT+GET burst endpoint.
spring-aerospike/src/main/java/com/example/aerospike/controller/MultiClientController.java Implements concurrent burst endpoint that round-robins across multiple clients.
spring-aerospike/src/main/java/com/example/aerospike/controller/MaintenanceController.java Implements /touch and /key delete maintenance endpoints.
spring-aerospike/src/main/java/com/example/aerospike/controller/HealthController.java Adds /health endpoint for readiness checks used by scripts.
spring-aerospike/src/main/java/com/example/aerospike/controller/FreshClientController.java Implements concurrent burst endpoint that constructs a new client per worker.
spring-aerospike/src/main/java/com/example/aerospike/controller/CrudController.java Implements CRUD + batch endpoints for recording baseline Aerospike traffic.
spring-aerospike/src/main/java/com/example/aerospike/controller/AdvancedController.java Adds scan/query/udf/cdt endpoints for parity with the Go sample.
spring-aerospike/src/main/java/com/example/aerospike/config/Policies.java Defines tuned read/write policies for bursty concurrency endpoints.
spring-aerospike/src/main/java/com/example/aerospike/config/AerospikeProperties.java Adds Spring @ConfigurationProperties for Aerospike settings.
spring-aerospike/src/main/java/com/example/aerospike/config/AerospikeConfig.java Wires Aerospike clients, builds ClientPolicy, and performs warmup.
spring-aerospike/scripts/script-1.sh Script to record+replay CRUD-focused test-set-0.
spring-aerospike/scripts/script-2.sh Script to record+replay /parallel test-set-1.
spring-aerospike/scripts/script-3.sh Script to record+replay /multiclient + /freshclient test-set-2.
spring-aerospike/scripts/common.sh Shared script helpers for docker boot, build, record, normalize, replay.
spring-aerospike/README.md Documents endpoints, layout, and how to run scripts for record/replay.
spring-aerospike/pom.xml Maven project definition (Spring Boot + Aerospike client dependency).
spring-aerospike/keploy.yml Keploy CLI configuration for recording/testing.
spring-aerospike/Dockerfile Container build for the sample app.
spring-aerospike/docker-compose.yml Spins up Aerospike CE and the sample app.
spring-aerospike/aerospike-conf/aerospike.conf Aerospike server configuration for the sample environment.
spring-aerospike/.gitignore Ignores build artifacts and generated keploy recordings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +48 to +51
// Hold concurrent-open low so a burst doesn't outpace stunnel /
// the proxy's TLS handshake rate. The Go sample uses the same
// 16 ceiling for the same reason.
policy.asyncMaxConnsPerNode = props.getOpeningConnectionThreshold();
Comment on lines +115 to +117
} catch (Throwable t) {
log.warn("warmup failed (non-fatal): {}", t.toString());
}
-H 'Content-Type: application/json' \
-d '[{"key":"a","bins":{"n":1}},{"key":"b","bins":{"n":2}}]'
sleep 1
curl -s -o /dev/null "http://127.0.0.1:$PORT/batch/get?k=a&k=b" || true
Comment on lines +47 to +51
policy.asyncMaxConnsPerNode = props.getConnectionQueueSize();
// Hold concurrent-open low so a burst doesn't outpace stunnel /
// the proxy's TLS handshake rate. The Go sample uses the same
// 16 ceiling for the same reason.
policy.asyncMaxConnsPerNode = props.getOpeningConnectionThreshold();
Comment on lines +37 to +38
throw last;
}
Comment on lines +45 to +49
Statement stmt = new Statement();
stmt.setNamespace(props.getNamespace());
stmt.setSetName(props.getSet());
stmt.setFilter(Filter.range("age", 0, 99));
int count = 0;
Comment on lines +58 to +62
@PostMapping("/udf")
public Map<String, Object> udf(@RequestBody PutRequest req) {
Key k = new Key(props.getNamespace(), props.getSet(), req.getKey());
Object out = client.execute(null, k, "transform", "apply", Value.get("bin"), Value.get(1));
return Map.of("result", out == null ? "null" : out.toString());
Comment on lines +67 to +73
sudo pkill -SIGINT keploy 2>/dev/null || true
for _ in $(seq 1 15); do
if ! pgrep -af "keploy record" >/dev/null 2>&1; then return 0; fi
sleep 1
done
echo "WARN: keploy didn't exit on SIGINT, killing"
sudo pkill -KILL keploy 2>/dev/null || true
import java.util.Map;

/**
* The four extra endpoints that the Go sample carries — /scan,

| Method | Path | What it does |
| ------ | -------------------------- | ---------------------------------------------------------------------------- |
| GET | `/health` | `info build + namespaces` |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants