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 diff --git a/samples/traderx/Makefile b/samples/traderx/Makefile new file mode 100644 index 0000000..aaa9f98 --- /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: 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 \ + 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 \ + 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 kind-load-image + 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 \ + 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 \ + 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