Go - #3
Go#3Yogeshjindal wants to merge 42 commits into
Conversation
Signed-off-by: Shubham Jain <shubhamkjain@outlook.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a Go-based e-commerce microservices stack (user/product/order + API gateway) with Kafka support and Keploy artifacts for recording/replay, along with Docker Compose and Kubernetes (Kind) deployment resources.
Changes:
- Added Go implementations for user_service, product_service, and apigateway (Gin + MySQL/sqlx + JWT middleware).
- Added Kafka producer/consumer utilities and Docker Compose wiring for Kafka/ZooKeeper + topic initialization.
- Added Keploy configs and recorded HTTP test fixtures, plus K8s/Kind manifests and helper scripts.
Reviewed changes
Copilot reviewed 92 out of 95 changed files in this pull request and generated 19 comments.
Show a summary per file
| File | Description |
|---|---|
| go-services/user_service/main.go | User auth + user/address CRUD service (Gin + MySQL) |
| go-services/user_service/keploy.yml | Keploy config for user_service |
| go-services/user_service/db.sql | user_db schema (users, addresses) |
| go-services/user_service/Dockerfile | Container build/runtime for user_service |
| go-services/product_service/main.go | Product catalog + stock reserve/release service |
| go-services/product_service/keploy.yml | Keploy config for product_service |
| go-services/product_service/db.sql | product_db schema + seed inserts |
| go-services/product_service/Dockerfile | Container build/runtime for product_service |
| go-services/apigateway/main.go | Simple reverse-proxy API gateway for the services |
| go-services/apigateway/keploy.yml | Keploy config for apigateway |
| go-services/apigateway/Dockerfile | Container build/runtime for apigateway |
| go-services/internal/config/config.go | Shared env-based configuration (incl. Kafka broker parsing) |
| go-services/internal/db/mysql.go | MySQL connection helper w/ retry + pool settings |
| go-services/internal/auth/jwt.go | JWT generation/validation helpers |
| go-services/internal/middleware/auth.go | Gin JWT auth middleware |
| go-services/internal/kafka/producer.go | Kafka producer wrapper (kafka-go) |
| go-services/internal/kafka/consumer.go | Kafka consumer wrapper (kafka-go) |
| go-services/docker-compose.yml | Local stack: MySQLs + Kafka/ZK + services + topic init |
| go-services/scripts/create-kafka-topics.sh | Helper script to create Kafka topics |
| go-services/test_order_service.sh | Test driver script to exercise order flows for Keploy recording |
| go-services/script.sh | Local curl-based end-to-end script (Postman-like) |
| go-services/port-forward.sh | Convenience port-forwarding script for K8s deployments |
| go-services/order_service/Dockerfile | Order service container build (incl. Keploy faketime/CA setup) |
| go-services/order_service/entrypoint.sh | Entry point to install CA then run order-service |
| go-services/order_service/db.sql | order_db schema (orders, order_items) |
| go-services/order_service/keploy.yml | Keploy config for order_service |
| go-services/order_service/keploy/.gitignore | Ignores Keploy reports output |
| go-services/order_service/keploy/freezeTime/tests/test-1.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-2.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-3.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-4.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-5.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-6.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-7.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-8.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-9.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-10.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-11.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-12.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-13.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-14.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-15.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-16.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-17.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-18.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-19.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-20.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-21.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-22.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/freezeTime/tests/test-23.yaml | Keploy recorded HTTP test fixture (freezeTime) |
| go-services/order_service/keploy/dedup/tests/test-1.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-2.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-3.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-4.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-5.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-6.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-7.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-8.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-9.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-10.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-11.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-12.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-13.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-14.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-15.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-16.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-17.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-18.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-19.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-20.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-21.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-22.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/order_service/keploy/dedup/tests/test-23.yaml | Keploy recorded HTTP test fixture (dedup) |
| go-services/k8s/user-service.yaml | K8s Service/Deployment for user-service |
| go-services/k8s/product-service.yaml | K8s Service/Deployment for product-service |
| go-services/k8s/order-service.yaml | K8s Service/Deployment for order-service |
| go-services/k8s/order-service-standalone.yaml | Standalone order-service + Keploy agent pod spec |
| go-services/k8s/mysql-users.yaml | K8s MySQL deployment for user_db |
| go-services/k8s/mysql-products.yaml | K8s MySQL deployment for product_db |
| go-services/k8s/mysql-orders.yaml | K8s MySQL deployment for order_db |
| go-services/k8s/localstack.yaml | Localstack SQS init + service/deployment |
| go-services/k8s/apigateway.yaml | K8s Service/Deployment for apigateway |
| go-services/k8s/README.md | K8s/Kind deployment instructions |
| go-services/kind-config.yaml | Kind cluster config (port mapping) |
| go-services/keploy.yml | Root Keploy config for go-services |
| go-services/go.mod | Go module definition + dependencies |
| go-services/guide.md | Keploy workflow notes (local + K8s) |
| go-services/README.md | Main documentation for running/testing stack + Kafka verification |
| go-services/.gitignore | Ignores script/ directory |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| tx, _ := database.Beginx() | ||
| _, err := tx.Exec( | ||
| "INSERT INTO addresses (id, user_id, line1, line2, city, state, postal_code, country, phone, is_default) VALUES (?,?,?,?,?,?,?,?,?,?)", | ||
| addrID, userID, req.Line1, line2, req.City, req.State, req.PostalCode, req.Country, phone, isDefault, |
There was a problem hiding this comment.
database.Beginx() errors are ignored (tx, _ := ...). If Beginx fails, tx will be nil and tx.Exec(...) will panic. Handle the Beginx error and return an appropriate 500 response.
| if desc, ok := req["description"]; ok { | ||
| sets = append(sets, "description=?") | ||
| args = append(args, desc) | ||
| } |
There was a problem hiding this comment.
description is accepted as an untyped interface{} and forwarded directly to SQL. If a client sends a non-string JSON value (object/array/number), this will fail at runtime. Restrict description to string or null (validate type and return 400 on invalid input).
| until kafka-topics --bootstrap-server localhost:9092 --list >/dev/null 2>&1; do | ||
| sleep 1 | ||
| done |
There was a problem hiding this comment.
This script uses --bootstrap-server localhost:9092, but in docker-compose.yml Kafka is exposed on the host as localhost:29092 (and 9092 is only inside the Kafka container/network). If this script is meant to run on the host, it should use localhost:29092 (or accept the bootstrap server as an argument/env var).
| if err != nil { | ||
| c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to create user: %v", err)}) | ||
| return |
There was a problem hiding this comment.
This error response includes the raw DB error (%v), which can leak internal details (schema/driver messages) to clients. Return a generic message (and log the detailed error server-side) instead.
| if isDefault == 1 { | ||
| tx.Exec("UPDATE addresses SET is_default=0 WHERE user_id=? AND id<>?", userID, addrID) | ||
| } | ||
| tx.Commit() | ||
|
|
||
| c.JSON(http.StatusCreated, gin.H{"id": addrID}) |
There was a problem hiding this comment.
Commit() is called without checking its return value. If the commit fails (e.g., connection drop), the handler still returns 201 Created. Check the tx.Commit() error and return 500 on failure (and rollback where appropriate).
| fields := []string{"line1", "line2", "city", "state", "postal_code", "country", "phone"} | ||
| for _, f := range fields { | ||
| if val, ok := req[f]; ok { | ||
| sets = append(sets, f+"=?") | ||
| args = append(args, val) | ||
| } |
There was a problem hiding this comment.
This dynamic update accepts any JSON type for line1/line2/city/... values and passes them directly to SQL args. Non-string values (objects/arrays) will cause SQL/driver errors at runtime. Validate/coerce expected types for each field (and reject invalid types with 400).
| if [ -z "$JWT" ]; then | ||
| echo "ERROR: Failed to get JWT token. Trying to create user first..." | ||
|
|
||
| # Try to create user first (might need admin token or no auth) | ||
| echo "Creating user..." | ||
| CREATE_USER_RESPONSE=$(curl -s -X POST "${USER_BASE}/users" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d "{ | ||
| \"username\": \"${USERNAME}\", | ||
| \"email\": \"${EMAIL}\", | ||
| \"password\": \"${PASSWORD}\" | ||
| }") |
There was a problem hiding this comment.
This script attempts to create a user without an Authorization header when login fails, but the user_service implementation protects POST /api/v1/users with JWT auth. As written, this fallback path will always fail (and the script exits). Either obtain an admin token first and use it for user creation, or make user creation a public endpoint if that’s intended.
| hashedPwd, _ := bcrypt.GenerateFromPassword([]byte(cfg.AdminPassword), bcrypt.DefaultCost) | ||
|
|
There was a problem hiding this comment.
bcrypt.GenerateFromPassword errors are ignored here, which could lead to inserting/updating an empty/invalid hash (and masking configuration issues). Handle the returned error and abort seeding (or log and return) if hashing fails.
| database.Select(&addresses, "SELECT id, line1, line2, city, state, postal_code, country, phone, is_default FROM addresses WHERE user_id=? ORDER BY is_default DESC, created_at DESC", userID) | ||
|
|
||
| c.JSON(http.StatusOK, addresses) |
There was a problem hiding this comment.
The addresses list query error is ignored. If database.Select fails, this returns 200 with an empty list, hiding DB issues. Handle the error and return 500 when the query fails.
| - name: keploy-data | ||
| hostPath: | ||
| path: /home/ashish/asish_workspace/flipkart-jan/ecommerce_sample_app/go-services/order_service/keploy | ||
| type: Directory |
There was a problem hiding this comment.
This manifest hardcodes a developer-specific absolute hostPath (/home/ashish/...). This will not work on other machines/CI and is unsafe to commit as-is. Use a PVC, emptyDir, or a configurable path (and document how to mount Keploy data) instead of an absolute workstation path.
- Add safe_consumer.go and safe_producer.go with graceful shutdown handling - Update consumer.go and producer.go to use safe wrappers - Improve order service Dockerfile and entrypoint.sh for better Keploy integration - Update keploy.yml configuration for order service - Enhance docker-compose.yml with proper service dependencies - Remove unnecessary Keploy test sets (dedup and freezeTime) - Update .gitignore to exclude logs, binaries, coverage, and analysis files
…cript for local development
Fix: startup path for Go order service
Alpine 3.19 package registry intermittently fails in CI, causing builds to error on `apk add ca-certificates`. Copy the certs directly from the builder stage instead, and bump the runtime base to alpine:3.21. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…real readiness
The MySQL healthchecks used `mysqladmin ping -h localhost`, which probes the unix
socket. During MySQL's init phase the server runs on the socket only
(skip-networking) while it applies /docker-entrypoint-initdb.d, so the socket
ping reports healthy BEFORE the network port (3306) is accepting connections.
Services gated on `depends_on: { condition: service_healthy }` (user_service,
product_service, order_service) then start too early and, under CI load where
init is slow, exhaust their connect-retry budget with "connection refused" and
panic (exit 143), failing the kafka-ecommerce lane intermittently.
Force a TCP probe (`-h 127.0.0.1 --protocol=tcp`) so service_healthy only fires
once 3306 actually serves, and add a 60s start_period grace for slow init under
contention. Dependents now reliably wait for a connectable database.
Signed-off-by: slayerjain <shubhamkjain@outlook.com>
fix(go-services): TCP-based MySQL healthcheck so dependents wait for real readiness
Two attributes made it impossible to run two copies of this stack on one docker
host, which is what keploy's CI needs to exercise the default and low-latency
record modes concurrently.
`container_name:` is GLOBAL to the docker daemon — it deliberately ignores
COMPOSE_PROJECT_NAME. With it set on all eight services, a second
`docker compose up` under a different project name does not get its own
containers: it collides with, or silently reuses, the first stack's. Removing it
lets compose derive `<project>-<service>-N`, which is namespaced.
Nothing depended on those names. Inter-service traffic already addresses
SERVICE names (USER_SERVICE_URL=http://user_service:8082,
AWS_ENDPOINT=http://localstack:4566, DB_HOST=mysql-products), and compose DNS
resolves service names regardless of container_name — verified that every host
referenced in the file is a service name. keploy's --container-name also
matches the service name, not just container_name (pkg/platform/docker:
`containerNameMatch || serviceName == containerName`), so recording against
`order_service` keeps working.
The eight published host ports are the other half: two stacks cannot both bind
3307-3309, 4566 and 8080-8083. They are now `${VAR:-<current>}`, so a caller
that wants a second stack can offset them while every existing consumer —
`docker compose up` with no environment at all — gets byte-identical ports to
before.
Verified with `docker compose config`: with no environment the published ports
are unchanged (3307, 3308, 3309, 4566, 8080, 8081, 8082, 8083), and with
MYSQL_PRODUCTS_PORT/ORDER_SERVICE_PORT set they move to the overrides. Zero
explicit container_name entries remain.
Signed-off-by: Shubham Jain <shubham@keploy.io>
fix(compose): make the stack parallel-safe without changing its defaults
…y uses) #16 made the ROOT docker-compose.yml parallel-safe, but keploy's kafka-ecommerce lane does `cd ecommerce_sample_app/go-services` and uses THIS file, which still had 10 explicit `container_name:` entries and 9 fixed host ports. So the lane kept colliding exactly as before, and the log gave it away: every container came up under a bare name (`user_service`, `mysql-products`, `kafka`) with no project prefix, and the service list included kafka/zookeeper/kafka-init — services that do not exist in the root file at all. Same change as #16, applied where it matters: - `container_name:` removed from all ten services. It is GLOBAL to the docker daemon and ignores COMPOSE_PROJECT_NAME, so while it was set two stacks could not coexist on one host no matter how they were namespaced. - the nine published host ports are now `${VAR:-<current>}`. Nothing depended on the old names: every inter-service reference already uses a SERVICE name, which compose DNS resolves regardless of container_name — checked programmatically across every environment value in the file, including the Kafka bootstrap servers and the three DB_HOSTs. keploy's --container-name also matches the service name (pkg/platform/docker: `containerNameMatch || serviceName == containerName`). Verified with `docker compose config`: with no environment the published ports are unchanged (2181, 3307-3309, 8080-8083, 29092), and a second axis with offsets resolves to a fully disjoint set. Zero explicit container_name remain. Signed-off-by: Shubham Jain <shubham@keploy.io>
fix(compose): make go-services parallel-safe too (the file CI actually uses)
…-init flake The kafka-ecommerce lane in keploy CI fails intermittently with dependency failed to start: container kafka-ecom-low-latency-mysql-users-1 is unhealthy and the cause is structural. mysql:8.0 declares VOLUME /var/lib/mysql and this compose file names no volume for it, so every container gets a fresh anonymous volume and every `compose up` pays a full cold `mysqld --initialize`. The lane runs two matrix axes concurrently, three MySQLs each, so six cold inits and their fsyncs contend for one host disk. Pipeline 8806 shows it. The two axes started 17s apart, and during the replay phase their inits overlapped six ways: those took 102-119s, against a budget of start_period 60s + retries 20 x interval 5s = 160s. The container that failed ran 11:54:41 -> 11:57:18 and compose gave up at 11:57:38 -- 177s, over budget -- with a probe history of five consecutive "Can't connect to MySQL server on '127.0.0.1:3306' (111)". Nothing in these databases needs to outlive its container -- they are seeded from db.sql on every start and thrown away -- so put the datadir on tmpfs and stop paying for the disk round-trips at all. Measured here (8 cores / 31G, idle; host-specific, so direction rather than a promise): tmpfs flattens the concurrency scaling completely. One, three and six containers all reach healthy in 11s, where the anonymous volume scaled 16s -> 21s -> 22s. That is comfortably inside the existing 60s start_period, which is why this does NOT raise it. Raising the threshold as well would mean a green lane could no longer tell you which change fixed it, and it costs diagnosability: time-to-unhealthy is start_period + retries*interval, and the CI script gives up at 240s, so a wider start_period narrows that margin until the script's generic "failed to start" fires before compose's precise "dependency failed to start: ... is unhealthy". The tmpfs is size-capped at 1g. An unbounded Docker tmpfs may grow to 50% of host RAM -- verified 15.7G on a 32G box -- so six of them could nominally claim far more than the host has. The cap's failure mode is documented in the file because it is not the obvious one: MySQL does not exit on a full datadir, it logs "Disk is full ... waiting", retries every 60s, reprints only every 600s, and the healthcheck keeps reporting healthy, so a run that hits it hangs with little pointing at the cause. --skip-log-bin is what keeps that far away. At rest it saves almost nothing (202M -> 199M), but binary logging was roughly half the datadir's growth under writes, and it buys nothing here: no replication, no point-in-time recovery, and keploy's MySQL capture is wire-protocol based -- the server greeting packet is byte-identical with and without it, so recorded mocks cannot diverge. 199M against a 1g cap leaves ~825M free at a measured ~1.5x amplification. Not also shrinking innodb_redo_log_capacity, which was tempting: it frees a further ~68M per container, but the redo log is preallocated, so on tmpfs it costs no init time to keep -- both variants cold-start in 11s -- and capping it at 32M makes InnoDB block writer threads with "MY-014084 ... unable to reserve space in redo log" after ~25MB of writes. That trades a new stall mode for RAM nothing here is short of. One cost to be explicit about: tmpfs pages are pinned and non-reclaimable and are charged to the CI step's memory cgroup, where the anonymous volume was backed by reclaimable page cache. That is ~199M per container, ~1.2G across the two concurrent axes. The lane declares no memory limit, so this is the figure to watch if it ever OOMs. One behaviour change: the datadir now dies with the container, not just with the volume, so `compose stop && compose start` re-initialises and re-runs db.sql instead of preserving rows. CI is unaffected, since it tears the project down between the record and replay phases and both already started from a virgin DB. Local `docker compose up` flows in README.md and guide.md get a clean DB per run, which is what replay determinism wants anyway. The healthcheck, tmpfs and server flags are now stated once in an x-mysql-common anchor instead of triplicated. Compose merges that mapping key-by-key rather than recursively, so a service declaring its own `healthcheck:` would replace that key wholesale; the file says so. Signed-off-by: slayerjain <shubhamkjain@outlook.com>
fix(go-services): keep the MySQL test datadirs in RAM to end the cold-init flake
#18 de-triplicated the three MySQL services into `x-mysql-common: &mysql-common` merged in with `<<: *mysql-common`. Docker accepts that -- it is the pattern the Compose spec endorses for reuse -- but it broke keploy's kafka-ecommerce lane: go-yaml load error in composer at L15.C21: unknown anchor 'mysql-common' referenced ERROR error while running the app {"error": "exit status 1"} keploy rewrites the compose file into a temporary one before running the app, and that rewrite keeps exactly six top-level keys -- version, services, networks, volumes, configs, secrets -- dropping every other one. `services` survives as a raw YAML node, so `<<: *mysql-common` was preserved verbatim while the `x-*` block that defined the anchor was discarded. The generated file then referenced an anchor that no longer existed and the app never started. Write the shared block out per service instead. The resolved `docker compose config` is unchanged: the three services' settings are byte-identical to what the anchor produced, and everything else in the file is untouched. An anchor declared INSIDE `services:` would survive the rewrite intact and is noted in the file as the working alternative. It is not used here because it makes the three services share one node while keploy mutates the services tree, so an edit aimed at one service would silently reach all three. The real defect is keploy's, not this file's, and is fixed separately so that compose files using the spec's own extension fields round-trip intact. This change is what unblocks CI in the meantime, since the lane runs whatever keploy release it is pinned to. Signed-off-by: slayerjain <shubhamkjain@outlook.com>
…mp.yaml
keploy writes docker-compose-tmp.yaml into the working directory when it rewrites
a compose file to inject its agent. A copy of that generated artifact was
committed, and it has since drifted into a trap: it still carries the
`mysqladmin ping -h localhost` probe that reports healthy while MySQL's
socket-only init server is running, hardcoded host ports 3307-3309 instead of the
`${MYSQL_*_PORT}` indirection that lets axes run in parallel, and hardcoded
container_names that collide on a shared host.
It is not loaded by accident -- keploy only globs docker-compose.yml/.yaml and
compose.yml/.yaml -- but anyone running `docker compose -f docker-compose-tmp.yaml
up` gets that stale config, and any keploy run from go-services/ overwrites the
tracked file and dirties the tree.
Remove it and ignore the path.
Signed-off-by: slayerjain <shubhamkjain@outlook.com>
…ewrite fix(go-services): stop sharing MySQL config through a top-level anchor
Kafka integration