Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
52f42a8
Add node dependency matrix sample
officialasishkumar Mar 24, 2026
4759af3
Add compose setup for node matrix sample
officialasishkumar Mar 24, 2026
36ceeac
docs: tighten node dependency matrix k8s flow
officialasishkumar Mar 24, 2026
1a7a45a
Stabilize node dependency matrix recording flows
officialasishkumar Mar 24, 2026
8b5cb4f
Document node dependency matrix staging runbook
officialasishkumar Mar 24, 2026
0f32218
Implement async catalog synchronization and deduplication endpoints i…
officialasishkumar Mar 24, 2026
fa22767
Update Kubernetes traffic recording instructions and enhance scripts …
officialasishkumar Mar 24, 2026
e058e3f
Refactor Kafka and SQS scenario functions to improve error handling a…
officialasishkumar Mar 24, 2026
503c04a
Enhance deploy-kind.sh to support custom node images for Kind cluster…
officialasishkumar Mar 25, 2026
faf87b6
fix: update expected-values.json to match actual UI dedup behavior
officialasishkumar Mar 26, 2026
93048b8
fix: update requiredKinds to include PostgresV2 and Redis
officialasishkumar Mar 26, 2026
90ef1d0
fix: address Copilot review feedback for node-dependency-matrix
officialasishkumar Mar 26, 2026
c09e5b3
fix: reduce requiredKinds to Http only — mock kinds vary between runs
officialasishkumar Mar 26, 2026
106d008
fix: sync package-lock.json with package.json
officialasishkumar Mar 26, 2026
d5c74f0
fix: use ECR public mirrors to avoid Docker Hub rate limits
officialasishkumar Mar 27, 2026
a083455
fix: use docker pull + kind load instead of crictl pull
officialasishkumar Mar 27, 2026
aaf64db
fix: configure Kind with GCR mirror to avoid all registry rate limits
officialasishkumar Mar 27, 2026
616949a
fix: use Keploy's local registry mirror (192.168.116.165:5000)
officialasishkumar Mar 27, 2026
d7fadf6
fix: load Kind images one at a time to avoid all-or-nothing failure
officialasishkumar Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This repo contains the sample for [Keploy's](https://keploy.io) JS Application.
8. [Node-JWT](https://github.com/keploy/samples-typescript/tree/main/node-jwt)
9. [Node-Mongoose](https://github.com/keploy/samples-typescript/tree/main/node-mongoose)
10. [Rest-Express-Mongo](https://github.com/keploy/samples-typescript/tree/main/rest-express-mongo)
11. [Node-Dependency-Matrix](https://github.com/keploy/samples-typescript/tree/main/node-dependency-matrix)

## Community Support ❤️

Expand Down
7 changes: 7 additions & 0 deletions node-dependency-matrix/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
dist
.generated
README.md
k8s
scripts
keploy
4 changes: 4 additions & 0 deletions node-dependency-matrix/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist
node_modules
.generated
keploy
33 changes: 33 additions & 0 deletions node-dependency-matrix/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
FROM node:20-bookworm-slim@sha256:17281e8d1dc4d671976c6b89a12f47a44c2f390b63a989e2e327631041f544fd AS build

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY tsconfig.json ./
COPY proto ./proto
COPY fixtures ./fixtures
COPY src ./src
COPY entrypoint.sh ./entrypoint.sh

RUN npm run build && chmod +x /app/entrypoint.sh

FROM node:20-bookworm-slim@sha256:17281e8d1dc4d671976c6b89a12f47a44c2f390b63a989e2e327631041f544fd

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*

COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/proto ./proto
COPY --from=build /app/fixtures ./fixtures
COPY --from=build /app/entrypoint.sh ./entrypoint.sh

ENV NODE_ENV=production
ENV PORT=8080
ENV GRPC_PORT=9090

ENTRYPOINT ["./entrypoint.sh"]
CMD ["node", "dist/bin/app.js"]
105 changes: 105 additions & 0 deletions node-dependency-matrix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Node Dependency Matrix

This sample is a TypeScript application built to validate Keploy cloud record/replay against a broad dependency matrix.

What it exposes:

- incoming HTTP
- incoming gRPC
- outgoing HTTPS
- outgoing HTTP/2
- outgoing gRPC
- outgoing MySQL
- outgoing Postgres
- outgoing Mongo
- outgoing Redis
- outgoing Kafka
- outgoing SQS-over-HTTPS
- outgoing generic TLS traffic
- an async background workflow that performs real outbound calls after a `202 Accepted`
- a noisy endpoint
- an expected replay failure endpoint
- duplicate-friendly GET and POST endpoints for static dedup verification

## Quick start

```bash
cd samples-typescript/node-dependency-matrix
npm install
npm run build
bash k8s/deploy-kind.sh
APP_URL=http://localhost:30081 bash scripts/record_traffic.sh
```

If the default host ports are already occupied, override them:

```bash
HOST_PROXY_PORT=31080 HOST_APP_PORT=31081 HOST_GRPC_PORT=31090 bash k8s/deploy-kind.sh
APP_URL=http://localhost:31081 bash scripts/record_traffic.sh
```

Optional incoming gRPC traffic:

```bash
GRPC_TARGET=localhost:30090 bash scripts/send_grpc_traffic.sh
```

## Docker Compose

For a non-Kubernetes local stack:

```bash
cd samples-typescript/node-dependency-matrix
npm install
bash scripts/compose_up.sh
APP_URL=http://localhost:38081 bash scripts/record_traffic.sh
GRPC_TARGET=localhost:39090 bash scripts/send_grpc_traffic.sh
```

To stop it:

```bash
bash scripts/compose_down.sh
```

If `38081` or `39090` are occupied:

```bash
APP_HTTP_PORT=48081 APP_GRPC_PORT=49090 bash scripts/compose_up.sh
APP_URL=http://localhost:48081 bash scripts/record_traffic.sh
GRPC_TARGET=localhost:49090 bash scripts/send_grpc_traffic.sh
```

## Keploy expectations

The machine-readable contract is:

```bash
fixtures/expected-values.json
```

Use it later in manual verification or other automation for:

- testcase counts
- required and acceptable mock kinds
- scenario-to-mock-kind mapping
- the exact HTTP and gRPC traffic plans
- the async workflow contract and expected background scenarios
- hosted UI + Helm expectations for Kind
- total mock count ranges
- dedup expectations
- expected replay pass/noisy/fail scenarios

## Kubernetes

The full Kind and hosted UI flow is in:

```bash
k8s/README.md
```

The detailed step-by-step staging runbook and troubleshooting guide is in:

```bash
k8s/STAGING_RUNBOOK.md
```
206 changes: 206 additions & 0 deletions node-dependency-matrix/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
name: node-dependency-matrix

x-node-matrix-image: &node_matrix_image
build:
context: .
image: node-dependency-matrix:compose

services:
app:
<<: *node_matrix_image
depends_on:
fixture-service:
condition: service_started
mysql:
condition: service_healthy
postgres:
condition: service_healthy
mongo-tls:
condition: service_started
redis-tls:
condition: service_started
redpanda:
condition: service_started
sqs-tls:
condition: service_started
environment:
PORT: "8080"
GRPC_PORT: "9090"
FIXTURE_HTTPS_BASE: https://fixture-service:8443
FIXTURE_HTTP2_ORIGIN: https://fixture-service:9443
FIXTURE_GRPC_TARGET: fixture-service:50051
FIXTURE_GENERIC_HOST: fixture-service
FIXTURE_GENERIC_PORT: "9445"
MYSQL_URL: mysql://root@mysql:3306/matrix
POSTGRES_URL: postgresql://postgres@postgres:5432/matrix
MONGO_URL: mongodb://mongo-tls:27017/matrix?tls=true
REDIS_URL: rediss://redis-tls:6380
KAFKA_BROKERS: redpanda:9092
KAFKA_TOPIC: matrix-events
SQS_ENDPOINT: https://sqs-tls:4567
SQS_QUEUE_URL: https://sqs-tls:4567/000000000000/dependency-matrix
SAMPLE_CA_CERT_PATH: /etc/sample-certs/ca.crt
COMBINED_CA_CERT_PATH: /tmp/node-dependency-matrix-ca-bundle.crt
NODE_EXTRA_CA_CERTS: /tmp/node-dependency-matrix-ca-bundle.crt
SSL_CERT_FILE: /tmp/node-dependency-matrix-ca-bundle.crt
ports:
- "${APP_HTTP_PORT:-38081}:8080"
- "${APP_GRPC_PORT:-39090}:9090"
volumes:
- ./.generated/certs:/etc/sample-certs:ro

fixture-service:
<<: *node_matrix_image
command: ["node", "dist/bin/dependencyFixture.js"]
environment:
TLS_CERT_PATH: /etc/sample-certs/proxy.crt
TLS_KEY_PATH: /etc/sample-certs/proxy.key
volumes:
- ./.generated/certs:/etc/sample-certs:ro

mysql:
image: mysql:8.0
command: ["mysqld", "--default-authentication-plugin=mysql_native_password"]
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
MYSQL_DATABASE: matrix
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot"]
interval: 5s
timeout: 5s
retries: 20

postgres:
image: postgres:16
environment:
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_DB: matrix
POSTGRES_USER: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d matrix"]
interval: 5s
timeout: 5s
retries: 20

mongo:
image: mongo:7
command: ["--bind_ip_all"]

redis:
image: redis:7-alpine

redpanda:
image: docker.redpanda.com/redpandadata/redpanda:v25.1.2
command:
- redpanda
- start
- --overprovisioned
- --smp
- "1"
- --memory
- 512M
- --reserve-memory
- 0M
- --check=false
- --node-id
- "0"
- --kafka-addr
- PLAINTEXT://0.0.0.0:9092
- --advertise-kafka-addr
- PLAINTEXT://redpanda:9092
- --set
- redpanda.auto_create_topics_enabled=true

localstack:
image: localstack/localstack:3.3
environment:
SERVICES: sqs
AWS_DEFAULT_REGION: us-east-1
volumes:
- ./scripts/localstack-init:/etc/localstack/init/ready.d:ro

mysql-tls:
<<: *node_matrix_image
command: ["node", "dist/bin/tlsProxy.js"]
depends_on:
mysql:
condition: service_healthy
environment:
LISTEN_PORT: "3306"
TARGET_HOST: mysql
TARGET_PORT: "3306"
TLS_CERT_PATH: /etc/sample-certs/proxy.crt
TLS_KEY_PATH: /etc/sample-certs/proxy.key
volumes:
- ./.generated/certs:/etc/sample-certs:ro

postgres-tls:
<<: *node_matrix_image
command: ["node", "dist/bin/tlsProxy.js"]
depends_on:
postgres:
condition: service_healthy
environment:
LISTEN_PORT: "5432"
TARGET_HOST: postgres
TARGET_PORT: "5432"
TLS_CERT_PATH: /etc/sample-certs/proxy.crt
TLS_KEY_PATH: /etc/sample-certs/proxy.key
volumes:
- ./.generated/certs:/etc/sample-certs:ro

mongo-tls:
<<: *node_matrix_image
command: ["node", "dist/bin/tlsProxy.js"]
depends_on:
- mongo
environment:
LISTEN_PORT: "27017"
TARGET_HOST: mongo
TARGET_PORT: "27017"
TLS_CERT_PATH: /etc/sample-certs/proxy.crt
TLS_KEY_PATH: /etc/sample-certs/proxy.key
volumes:
- ./.generated/certs:/etc/sample-certs:ro

redis-tls:
<<: *node_matrix_image
command: ["node", "dist/bin/tlsProxy.js"]
depends_on:
- redis
environment:
LISTEN_PORT: "6380"
TARGET_HOST: redis
TARGET_PORT: "6379"
TLS_CERT_PATH: /etc/sample-certs/proxy.crt
TLS_KEY_PATH: /etc/sample-certs/proxy.key
volumes:
- ./.generated/certs:/etc/sample-certs:ro

kafka-tls:
<<: *node_matrix_image
command: ["node", "dist/bin/tlsProxy.js"]
depends_on:
- redpanda
environment:
LISTEN_PORT: "9094"
TARGET_HOST: redpanda
TARGET_PORT: "9092"
TLS_CERT_PATH: /etc/sample-certs/proxy.crt
TLS_KEY_PATH: /etc/sample-certs/proxy.key
volumes:
- ./.generated/certs:/etc/sample-certs:ro

sqs-tls:
<<: *node_matrix_image
command: ["node", "dist/bin/tlsProxy.js"]
depends_on:
- localstack
environment:
LISTEN_PORT: "4567"
TARGET_HOST: localstack
TARGET_PORT: "4566"
TLS_CERT_PATH: /etc/sample-certs/proxy.crt
TLS_KEY_PATH: /etc/sample-certs/proxy.key
volumes:
- ./.generated/certs:/etc/sample-certs:ro
23 changes: 23 additions & 0 deletions node-dependency-matrix/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh
set -eu

COMBINED_CA_CERT_PATH="${COMBINED_CA_CERT_PATH:-/tmp/node-dependency-matrix-ca-bundle.crt}"

rm -f "${COMBINED_CA_CERT_PATH}"

if [ -n "${SAMPLE_CA_CERT_PATH:-}" ] && [ -f "${SAMPLE_CA_CERT_PATH}" ]; then
cat "${SAMPLE_CA_CERT_PATH}" > "${COMBINED_CA_CERT_PATH}"
cp "${SAMPLE_CA_CERT_PATH}" /usr/local/share/ca-certificates/node-dependency-matrix.crt
update-ca-certificates >/dev/null 2>&1 || true
fi

if [ -f /tmp/keploy-tls/ca.crt ]; then
cat /tmp/keploy-tls/ca.crt >> "${COMBINED_CA_CERT_PATH}"
fi

if [ ! -f "${COMBINED_CA_CERT_PATH}" ]; then
: > "${COMBINED_CA_CERT_PATH}"
>&2 echo "Warning: No CA certificates were found to create the combined CA bundle at '${COMBINED_CA_CERT_PATH}'. To fix this, either set SAMPLE_CA_CERT_PATH to a valid CA bundle file or mount /tmp/keploy-tls/ca.crt before starting this container so fixture endpoints can establish TLS correctly."
Comment on lines +19 to +20
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

This startup message is labeled as "Warning" and the container continues with an empty CA bundle, which will later cause TLS-dependent scenarios to fail in less obvious ways. Consider failing fast with a clear error (and remediation steps) unless an explicit env flag allows running without CA certs; also avoid adding warning-level messaging if the project’s logging policy is to not emit warnings.

Suggested change
: > "${COMBINED_CA_CERT_PATH}"
>&2 echo "Warning: No CA certificates were found to create the combined CA bundle at '${COMBINED_CA_CERT_PATH}'. To fix this, either set SAMPLE_CA_CERT_PATH to a valid CA bundle file or mount /tmp/keploy-tls/ca.crt before starting this container so fixture endpoints can establish TLS correctly."
if [ "${ALLOW_EMPTY_CA_BUNDLE:-}" = "true" ]; then
: > "${COMBINED_CA_CERT_PATH}"
>&2 echo "Running without any CA certificates at '${COMBINED_CA_CERT_PATH}' because ALLOW_EMPTY_CA_BUNDLE=true. TLS connections that rely on system CAs may fail. To fix this, set SAMPLE_CA_CERT_PATH to a valid CA bundle file or mount /tmp/keploy-tls/ca.crt before starting this container."
else
>&2 echo "Error: No CA certificates were found to create the combined CA bundle at '${COMBINED_CA_CERT_PATH}'."
>&2 echo "Remediation: Set SAMPLE_CA_CERT_PATH to a valid CA bundle file or mount /tmp/keploy-tls/ca.crt before starting this container so fixture endpoints can establish TLS correctly. To bypass this check (not recommended), set ALLOW_EMPTY_CA_BUNDLE=true."
exit 1
fi

Copilot uses AI. Check for mistakes.
fi

exec "$@"
Loading