From 59f0f31fb03a25ff42d9c79b183a512d8dff490d Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 13 Feb 2026 13:07:35 -0500 Subject: [PATCH 1/4] Add traderx demo Signed-off-by: Mathieu Benoit --- samples/traderx/Makefile | 134 ++++++++++++++++++ samples/traderx/README.md | 51 +++++++ samples/traderx/account-service/score.yaml | 21 +++ samples/traderx/database/score.yaml | 19 +++ samples/traderx/ingress/Dockerfile | 13 ++ .../ingress/nginx.traderx.conf.template | 61 ++++++++ samples/traderx/ingress/score.yaml | 40 ++++++ samples/traderx/people-service/score.yaml | 13 ++ samples/traderx/position-service/score.yaml | 18 +++ samples/traderx/reference-data/score.yaml | 13 ++ samples/traderx/trade-feed/score.yaml | 13 ++ samples/traderx/trade-processor/score.yaml | 21 +++ samples/traderx/trade-service/score.yaml | 30 ++++ samples/traderx/web-frontend/score.yaml | 20 +++ 14 files changed, 467 insertions(+) create mode 100644 samples/traderx/Makefile create mode 100644 samples/traderx/README.md create mode 100644 samples/traderx/account-service/score.yaml create mode 100644 samples/traderx/database/score.yaml create mode 100644 samples/traderx/ingress/Dockerfile create mode 100644 samples/traderx/ingress/nginx.traderx.conf.template create mode 100644 samples/traderx/ingress/score.yaml create mode 100644 samples/traderx/people-service/score.yaml create mode 100644 samples/traderx/position-service/score.yaml create mode 100644 samples/traderx/reference-data/score.yaml create mode 100644 samples/traderx/trade-feed/score.yaml create mode 100644 samples/traderx/trade-processor/score.yaml create mode 100644 samples/traderx/trade-service/score.yaml create mode 100644 samples/traderx/web-frontend/score.yaml diff --git a/samples/traderx/Makefile b/samples/traderx/Makefile new file mode 100644 index 0000000..eae87c5 --- /dev/null +++ b/samples/traderx/Makefile @@ -0,0 +1,134 @@ +# Disable all the default make stuff +MAKEFLAGS += --no-builtin-rules +.SUFFIXES: + +## Display a list of the documented make targets +.PHONY: help +help: + @echo Documented Make targets: + @perl -e 'undef $$/; while (<>) { while ($$_ =~ /## (.*?)(?:\n# .*)*\n.PHONY:\s+(\S+).*/mg) { printf "\033[36m%-30s\033[0m %s\n", $$2, $$1 } }' $(MAKEFILE_LIST) | sort + +.PHONY: .FORCE +.FORCE: + +.score-compose/state.yaml: + score-compose init \ + --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-compose/10-service.provisioners.yaml + +compose.yaml: account-service/score.yaml database/score.yaml ingress/score.yaml people-service/score.yaml position-service/score.yaml reference-data/score.yaml trade-feed/score.yaml trade-processor/score.yaml trade-service/score.yaml web-frontend/score.yaml .score-compose/state.yaml Makefile + score-compose generate \ + account-service/score.yaml \ + database/score.yaml \ + people-service/score.yaml \ + position-service/score.yaml \ + reference-data/score.yaml \ + trade-feed/score.yaml \ + trade-processor/score.yaml \ + trade-service/score.yaml \ + web-frontend/score.yaml + score-compose generate \ + ingress/score.yaml \ + --build 'ingress={"context":"ingress/","tags":["ingress:local"]}' + +## Generate a compose.yaml file from the score specs and launch it. +.PHONY: compose-up +compose-up: compose.yaml + docker compose up --build -d --remove-orphans + +## Generate a compose.yaml file from the score spec, launch it and test (curl) the exposed container. +.PHONY: compose-test +compose-test: compose-up + sleep 5 + curl $$(score-compose resources get-outputs 'dns.default#ingress.dns' --format '{{ .host }}:8080') + +## Delete the containers running via compose down. +.PHONY: compose-down +compose-down: + docker compose down -v --remove-orphans || true + +.score-k8s/state.yaml: + score-k8s init \ + --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-k8s/10-service.provisioners.yaml + +manifests.yaml: apps/account-service/score.yaml apps/database/score.yaml apps/ingress/score.yaml apps/people-service/score.yaml apps/position-service/score.yaml apps/reference-data/score.yaml apps/trade-feed/score.yaml apps/trade-processor/score.yaml apps/trade-service/score.yaml apps/web-frontend/score.yaml .score-k8s/state.yaml Makefile + score-k8s generate \ + apps/account-service/score.yaml \ + apps/database/score.yaml \ + apps/people-service/score.yaml \ + apps/position-service/score.yaml \ + apps/reference-data/score.yaml \ + apps/trade-feed/score.yaml \ + apps/trade-processor/score.yaml \ + apps/trade-service/score.yaml \ + apps/web-frontend/score.yaml + score-k8s generate \ + apps/ingress/score.yaml \ + --image ingress:local + +## Create a local Kind cluster. +.PHONY: kind-create-cluster +kind-create-cluster: + ./scripts/setup-kind-cluster.sh + +## Load the local container image in the current Kind cluster. +.PHONY: kind-load-image +kind-load-image: + kind load docker-image ingress:local + +NAMESPACE ?= default +## Generate a manifests.yaml file from the score spec and apply it in Kubernetes. +.PHONY: k8s-up +k8s-up: manifests.yaml + kubectl apply \ + -f manifests.yaml \ + -n ${NAMESPACE} + kubectl wait deployments/ingress \ + -n ${NAMESPACE} \ + --for condition=Available \ + --timeout=90s + kubectl wait pods \ + -n ${NAMESPACE} \ + -l app.kubernetes.io/name=ingress \ + --for condition=Ready \ + --timeout=90s + +## Expose the container deployed in Kubernetes via port-forward. +.PHONY: k8s-test +k8s-test: k8s-up + curl $$(score-k8s resources get-outputs dns.default#ingress.dns --format '{{ .host }}') + +## Delete the deployment of the local container in Kubernetes. +.PHONY: k8s-down +k8s-down: + kubectl delete \ + -f manifests.yaml \ + -n ${NAMESPACE} + +## Generate catalog-info.yaml for Backstage. +.PHONY: generate-catalog-info +generate-catalog-info: + score-k8s init \ + --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-k8s/10-service.provisioners.yaml \ + --patch-templates https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-k8s/backstage-catalog-entities.tpl + score-k8s generate \ + --namespace traderx-demo \ + apps/account-service/score.yaml \ + apps/database/score.yaml \ + apps/people-service/score.yaml \ + apps/position-service/score.yaml \ + apps/reference-data/score.yaml \ + apps/trade-feed/score.yaml \ + apps/trade-processor/score.yaml \ + apps/trade-service/score.yaml \ + apps/web-frontend/score.yaml + --output catalog-info.yaml + score-k8s generate \ + --namespace traderx-demo \ + --generate-namespace \ + apps/ingress/score.yaml \ + --image ingress:local \ + --output catalog-info.yaml + sed 's,$$GITHUB_REPO,score-spec/examples,g' -i catalog-info.yaml diff --git a/samples/traderx/README.md b/samples/traderx/README.md new file mode 100644 index 0000000..37e8ab3 --- /dev/null +++ b/samples/traderx/README.md @@ -0,0 +1,51 @@ +Deploy the [finos/traderX](https://github.com/finos/traderX) with Score (`score-compose` and `score-k8s`). + +```mermaid +flowchart TD + dns[DNS] --> ingress(ingress) + subgraph Workloads + ingress-->reference-data(reference-data) + ingress-->trade-service(trade-service) + ingress-->trade-feed(trade-feed) + ingress-->trade-processor(trade-processor) + ingress-->web-frontend(web-frontend) + ingress-->position-service(position-service) + ingress-->people-service(people-service) + ingress-->account-service(account-service) + ingress-->database[(database)] + web-frontend-->trade-feed + web-frontend-->database + account-service-->people-service + account-service-->database + position-service-->database + trade-processor-->trade-feed + trade-processor-->database + trade-service-->account-service + trade-service-->database + trade-service-->people-service + trade-service-->reference-data + trade-service-->trade-feed + end +``` + +## Local deployment with Docker Compose + +You need to be in the `samples/traderx` folder to run the following commands. + +Deploy and test locally with Docker compose: +```bash +make compose-up +``` + +You can now browse http://localhost:8080. + +## Local deployment with Kind cluster + +Deploy and test locally with Kind cluster: +```bash +make kind-create-cluster + +make k8s-up +``` + +You can now browse http://localhost:80. \ No newline at end of file diff --git a/samples/traderx/account-service/score.yaml b/samples/traderx/account-service/score.yaml new file mode 100644 index 0000000..6634336 --- /dev/null +++ b/samples/traderx/account-service/score.yaml @@ -0,0 +1,21 @@ +apiVersion: score.dev/v1b1 +metadata: + name: account-service + annotations: + tags: "java,spring" +containers: + account-service: + image: ghcr.io/finos/traderx/account-service:latest + variables: + DATABASE_TCP_HOST: "${resources.database.name}" + PEOPLE_SERVICE_HOST: "${resources.people-service.name}" +service: + ports: + web: + port: 18088 + targetPort: 18088 +resources: + people-service: + type: service + database: + type: service \ No newline at end of file diff --git a/samples/traderx/database/score.yaml b/samples/traderx/database/score.yaml new file mode 100644 index 0000000..4fe0df0 --- /dev/null +++ b/samples/traderx/database/score.yaml @@ -0,0 +1,19 @@ +apiVersion: score.dev/v1b1 +metadata: + name: database + annotations: + tags: "java,h2" +containers: + database: + image: ghcr.io/finos/traderx/database:latest +service: + ports: + tcp: + port: 18082 + targetPort: 18082 + pg: + port: 18083 + targetPort: 18083 + web: + port: 18084 + targetPort: 18084 \ No newline at end of file diff --git a/samples/traderx/ingress/Dockerfile b/samples/traderx/ingress/Dockerfile new file mode 100644 index 0000000..9f5c8fd --- /dev/null +++ b/samples/traderx/ingress/Dockerfile @@ -0,0 +1,13 @@ +FROM nginx:alpine-slim + +EXPOSE 8080 +ARG NGINX_HOST="localhost" +ENV NGINX_HOST=$NGINX_HOST + +# This is a workaround for the dollar sign in the envsubst command +ARG DOLLAR="$" +ENV DOLLAR=$DOLLAR + +COPY nginx.traderx.conf.template /etc/nginx/conf.d/nginx.traderx.conf.template + +RUN envsubst < /etc/nginx/conf.d/nginx.traderx.conf.template > /etc/nginx/conf.d/default.conf \ No newline at end of file diff --git a/samples/traderx/ingress/nginx.traderx.conf.template b/samples/traderx/ingress/nginx.traderx.conf.template new file mode 100644 index 0000000..9cb542d --- /dev/null +++ b/samples/traderx/ingress/nginx.traderx.conf.template @@ -0,0 +1,61 @@ +server { + listen 8080; + server_name $NGINX_HOST; + + location /db-web/ { + proxy_pass http://database-database:18084/; + } + location /reference-data/ { + proxy_pass http://reference-data-reference-data:18085/; + } + + location /ng-cli-ws { + proxy_pass http://web-frontend-web-frontend:18093/ng-cli-ws; + proxy_http_version 1.1; + proxy_set_header Upgrade ${DOLLAR}http_upgrade; + proxy_set_header Connection "upgrade"; + } + + location /trade-feed/ { + proxy_set_header X-Forwarded-For ${DOLLAR}proxy_add_x_forwarded_for; + proxy_set_header Host ${DOLLAR}http_host; + + proxy_pass http://trade-feed-trade-feed:18086/; + + proxy_http_version 1.1; + proxy_set_header Upgrade ${DOLLAR}http_upgrade; + proxy_set_header Connection "upgrade"; + + } + + location /socket.io/ { + proxy_set_header X-Forwarded-For ${DOLLAR}proxy_add_x_forwarded_for; + proxy_set_header Host ${DOLLAR}http_host; + + proxy_pass http://trade-feed-trade-feed:18086/socket.io/; + + proxy_http_version 1.1; + proxy_set_header Upgrade ${DOLLAR}http_upgrade; + proxy_set_header Connection "upgrade"; + + } + + location /people-service/ { + proxy_pass http://people-service-people-service:18089/; + } + location /account-service/ { + proxy_pass http://account-service-account-service:18088/; + } + location /position-service/ { + proxy_pass http://position-service-position-service:18090/; + } + location /trade-service/ { + proxy_pass http://trade-service-trade-service:18092/; + } + location /trade-processor/ { + proxy_pass http://trade-processor-trade-processor:18091/; + } + location / { + proxy_pass http://web-frontend-web-frontend:18093/; + } + } \ No newline at end of file diff --git a/samples/traderx/ingress/score.yaml b/samples/traderx/ingress/score.yaml new file mode 100644 index 0000000..7b14fec --- /dev/null +++ b/samples/traderx/ingress/score.yaml @@ -0,0 +1,40 @@ +apiVersion: score.dev/v1b1 +metadata: + name: ingress + annotations: + tags: "nginx,ingress" +containers: + ingress: + image: . + variables: + DATABASE_TCP_HOST: "${resources.database.name}" +service: + ports: + web: + port: 8080 + targetPort: 8080 +resources: + people-service: + type: service + trade-service: + type: service + account-service: + type: service + reference-data: + type: service + trade-feed: + type: service + trade-processor: + type: service + web-frontend: + type: service + database: + type: service + dns: + type: dns + route: + type: route + params: + host: ${resources.dns.host} + path: / + port: 8080 \ No newline at end of file diff --git a/samples/traderx/people-service/score.yaml b/samples/traderx/people-service/score.yaml new file mode 100644 index 0000000..700c389 --- /dev/null +++ b/samples/traderx/people-service/score.yaml @@ -0,0 +1,13 @@ +apiVersion: score.dev/v1b1 +metadata: + name: people-service + annotations: + tags: "dotnet" +containers: + people-service: + image: ghcr.io/finos/traderx/people-service:latest +service: + ports: + web: + port: 18089 + targetPort: 18089 \ No newline at end of file diff --git a/samples/traderx/position-service/score.yaml b/samples/traderx/position-service/score.yaml new file mode 100644 index 0000000..51c9be4 --- /dev/null +++ b/samples/traderx/position-service/score.yaml @@ -0,0 +1,18 @@ +apiVersion: score.dev/v1b1 +metadata: + name: position-service + annotations: + tags: "java,spring" +containers: + position-service: + image: ghcr.io/finos/traderx/position-service:latest + variables: + DATABASE_TCP_HOST: "${resources.database.name}" +service: + ports: + web: + port: 18090 + targetPort: 18090 +resources: + database: + type: service \ No newline at end of file diff --git a/samples/traderx/reference-data/score.yaml b/samples/traderx/reference-data/score.yaml new file mode 100644 index 0000000..d2ba5c1 --- /dev/null +++ b/samples/traderx/reference-data/score.yaml @@ -0,0 +1,13 @@ +apiVersion: score.dev/v1b1 +metadata: + name: reference-data + annotations: + tags: "nodejs,nestjs" +containers: + reference-data: + image: ghcr.io/finos/traderx/reference-data:latest +service: + ports: + web: + port: 18085 + targetPort: 18085 \ No newline at end of file diff --git a/samples/traderx/trade-feed/score.yaml b/samples/traderx/trade-feed/score.yaml new file mode 100644 index 0000000..6eedb42 --- /dev/null +++ b/samples/traderx/trade-feed/score.yaml @@ -0,0 +1,13 @@ +apiVersion: score.dev/v1b1 +metadata: + name: trade-feed + annotations: + tags: "nodejs,socketio" +containers: + trade-feed: + image: ghcr.io/finos/traderx/trade-feed:latest +service: + ports: + web: + port: 18086 + targetPort: 18086 \ No newline at end of file diff --git a/samples/traderx/trade-processor/score.yaml b/samples/traderx/trade-processor/score.yaml new file mode 100644 index 0000000..1f4218d --- /dev/null +++ b/samples/traderx/trade-processor/score.yaml @@ -0,0 +1,21 @@ +apiVersion: score.dev/v1b1 +metadata: + name: trade-processor + annotations: + tags: "java,spring" +containers: + trade-processor: + image: ghcr.io/finos/traderx/trade-processor:latest + variables: + DATABASE_TCP_HOST: "${resources.database.name}" + TRADE_FEED_HOST: "${resources.trade-feed.name}" +service: + ports: + web: + port: 18091 + targetPort: 18091 +resources: + trade-feed: + type: service + database: + type: service \ No newline at end of file diff --git a/samples/traderx/trade-service/score.yaml b/samples/traderx/trade-service/score.yaml new file mode 100644 index 0000000..74c3fd6 --- /dev/null +++ b/samples/traderx/trade-service/score.yaml @@ -0,0 +1,30 @@ +apiVersion: score.dev/v1b1 +metadata: + name: trade-service + annotations: + tags: "java,spring" +containers: + trade-service: + image: ghcr.io/finos/traderx/trade-service:latest + variables: + DATABASE_TCP_HOST: "${resources.database.name}" + PEOPLE_SERVICE_HOST: "${resources.people-service.name}" + ACCOUNT_SERVICE_HOST: "${resources.account-service.name}" + REFERENCE_DATA_HOST: "${resources.reference-data.name}" + TRADE_FEED_HOST: "${resources.trade-feed.name}" +service: + ports: + web: + port: 18092 + targetPort: 18092 +resources: + people-service: + type: service + trade-feed: + type: service + account-service: + type: service + reference-data: + type: service + database: + type: service \ No newline at end of file diff --git a/samples/traderx/web-frontend/score.yaml b/samples/traderx/web-frontend/score.yaml new file mode 100644 index 0000000..de400ba --- /dev/null +++ b/samples/traderx/web-frontend/score.yaml @@ -0,0 +1,20 @@ +apiVersion: score.dev/v1b1 +metadata: + name: web-frontend + annotations: + tags: "html,website,ui,css,javascript,angular,react" +containers: + web-frontend: + image: ghcr.io/finos/traderx/web-front-end-angular:latest + variables: + DATABASE_TCP_HOST: "${resources.database.name}" +service: + ports: + web: + port: 18093 + targetPort: 18093 +resources: + trade-feed: + type: service + database: + type: service \ No newline at end of file From 5b3f8d8b376604f91bb83d19bd9a77af41975b33 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 13 Feb 2026 13:08:21 -0500 Subject: [PATCH 2/4] docs Signed-off-by: Mathieu Benoit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fe671f6..cf75506 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,5 @@ - [Resources](./resources/) - [Samples](./samples/) - [OnlineBoutique](./samples/onlineboutique/) - - [AKS Store Demo](./samples/aks-store-demo/) \ No newline at end of file + - [AKS Store Demo](./samples/aks-store-demo/) + - [TraderX](./samples/traderx/) \ No newline at end of file From 671c295f0bd981daa42507d15762b8122422e8f5 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 13 Feb 2026 13:12:53 -0500 Subject: [PATCH 3/4] remove apps/ prefix Signed-off-by: Mathieu Benoit --- samples/traderx/Makefile | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/samples/traderx/Makefile b/samples/traderx/Makefile index eae87c5..9cb0263 100644 --- a/samples/traderx/Makefile +++ b/samples/traderx/Makefile @@ -52,19 +52,19 @@ compose-down: --no-sample \ --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-k8s/10-service.provisioners.yaml -manifests.yaml: apps/account-service/score.yaml apps/database/score.yaml apps/ingress/score.yaml apps/people-service/score.yaml apps/position-service/score.yaml apps/reference-data/score.yaml apps/trade-feed/score.yaml apps/trade-processor/score.yaml apps/trade-service/score.yaml apps/web-frontend/score.yaml .score-k8s/state.yaml Makefile +manifests.yaml: account-service/score.yaml database/score.yaml ingress/score.yaml people-service/score.yaml position-service/score.yaml reference-data/score.yaml trade-feed/score.yaml trade-processor/score.yaml trade-service/score.yaml web-frontend/score.yaml .score-k8s/state.yaml Makefile score-k8s generate \ - apps/account-service/score.yaml \ - apps/database/score.yaml \ - apps/people-service/score.yaml \ - apps/position-service/score.yaml \ - apps/reference-data/score.yaml \ - apps/trade-feed/score.yaml \ - apps/trade-processor/score.yaml \ - apps/trade-service/score.yaml \ - apps/web-frontend/score.yaml + account-service/score.yaml \ + database/score.yaml \ + people-service/score.yaml \ + position-service/score.yaml \ + reference-data/score.yaml \ + trade-feed/score.yaml \ + trade-processor/score.yaml \ + trade-service/score.yaml \ + web-frontend/score.yaml score-k8s generate \ - apps/ingress/score.yaml \ + ingress/score.yaml \ --image ingress:local ## Create a local Kind cluster. @@ -115,20 +115,20 @@ generate-catalog-info: --patch-templates https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-k8s/backstage-catalog-entities.tpl score-k8s generate \ --namespace traderx-demo \ - apps/account-service/score.yaml \ - apps/database/score.yaml \ - apps/people-service/score.yaml \ - apps/position-service/score.yaml \ - apps/reference-data/score.yaml \ - apps/trade-feed/score.yaml \ - apps/trade-processor/score.yaml \ - apps/trade-service/score.yaml \ - apps/web-frontend/score.yaml + account-service/score.yaml \ + database/score.yaml \ + people-service/score.yaml \ + position-service/score.yaml \ + reference-data/score.yaml \ + trade-feed/score.yaml \ + trade-processor/score.yaml \ + trade-service/score.yaml \ + web-frontend/score.yaml --output catalog-info.yaml score-k8s generate \ --namespace traderx-demo \ --generate-namespace \ - apps/ingress/score.yaml \ + ingress/score.yaml \ --image ingress:local \ --output catalog-info.yaml sed 's,$$GITHUB_REPO,score-spec/examples,g' -i catalog-info.yaml From a9f6971fe202553747b4cc855b5dbdadfe03ee6b Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 13 Feb 2026 13:20:06 -0500 Subject: [PATCH 4/4] k8s-up: kind-load-image Signed-off-by: Mathieu Benoit --- samples/traderx/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/traderx/Makefile b/samples/traderx/Makefile index 9cb0263..aaa9f98 100644 --- a/samples/traderx/Makefile +++ b/samples/traderx/Makefile @@ -80,7 +80,7 @@ kind-load-image: NAMESPACE ?= default ## Generate a manifests.yaml file from the score spec and apply it in Kubernetes. .PHONY: k8s-up -k8s-up: manifests.yaml +k8s-up: manifests.yaml kind-load-image kubectl apply \ -f manifests.yaml \ -n ${NAMESPACE}