diff --git a/.gitignore b/.gitignore index f33b340..c344205 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ **/.score-compose **/compose.yaml **/manifests.yaml +**/demo-magic.sh diff --git a/.scripts/setup-kind-cluster.sh b/.scripts/setup-kind-cluster.sh index df9a472..9c9c901 100755 --- a/.scripts/setup-kind-cluster.sh +++ b/.scripts/setup-kind-cluster.sh @@ -22,6 +22,15 @@ helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric \ --set service.type=NodePort \ --set-json 'service.ports=[{"port":80,"nodePort":31000}]' +kubectl wait deployments/ngf-nginx-gateway-fabric \ + -n nginx-gateway \ + --for condition=Available \ + --timeout=90s +kubectl wait --namespace nginx-gateway \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/name=nginx-gateway-fabric \ + --timeout=120s + kubectl apply -f - <trade-feed trade-processor-->database trade-service-->account-service - trade-service-->database trade-service-->people-service trade-service-->reference-data trade-service-->trade-feed diff --git a/samples/traderx/account-service/score.yaml b/samples/traderx/account-service/score.yaml index 6634336..cf7a75e 100644 --- a/samples/traderx/account-service/score.yaml +++ b/samples/traderx/account-service/score.yaml @@ -7,8 +7,9 @@ containers: account-service: image: ghcr.io/finos/traderx/account-service:latest variables: + ACCOUNT_SERVICE_PORT: '18088' DATABASE_TCP_HOST: "${resources.database.name}" - PEOPLE_SERVICE_HOST: "${resources.people-service.name}" + PEOPLE_SERVICE_URL: "${resources.people-service.url}" service: ports: web: @@ -17,5 +18,10 @@ service: resources: people-service: type: service + params: + port: 18089 + artifacts: api-mocks/people-service-openapi.json:true,api-mocks/people-service-metadata.yaml:false,api-mocks/people-service-examples.yaml:false + name: FINOS TraderX People Service + version: v1 database: type: service \ No newline at end of file diff --git a/samples/traderx/api-mocks/people-service-metadata.yaml b/samples/traderx/api-mocks/people-service-metadata.yaml index f508212..dacbc25 100644 --- a/samples/traderx/api-mocks/people-service-metadata.yaml +++ b/samples/traderx/api-mocks/people-service-metadata.yaml @@ -11,3 +11,5 @@ operations: return mockRequest.getRequest().parameters.LoginId[0]; } return "789"; + GET /People/GetMatchingPeople: + dispatcher: null diff --git a/samples/traderx/api-mocks/position-service-examples.yaml b/samples/traderx/api-mocks/position-service-examples.yaml index 26c114b..0aaf886 100644 --- a/samples/traderx/api-mocks/position-service-examples.yaml +++ b/samples/traderx/api-mocks/position-service-examples.yaml @@ -5,15 +5,15 @@ metadata: version: 0.1.0 operations: GET /trades/{accountId}: - '52355': + '52335': request: parameters: - accountId: 52355 + accountId: 52335 response: mediaType: application/json body: - - id: TRADE-52355-AABBCC - accountId: 52355 + - id: TRADE-52335-AABBCC + accountId: 52335 security: BAC side: Sell state: Settled @@ -21,14 +21,14 @@ operations: updated: 2026-03-11T08:57:54.758+00:00 created: 2026-03-11T08:57:54.758+00:00 GET /positions/{accountId}: - '52355': + '52335': request: parameters: - accountId: 52355 + accountId: 52335 response: mediaType: application/json body: - - accountId: 52355 + - accountId: 52335 security: BAC quantity: -2400 updated: 2026-03-11T08:57:54.763+00:00 diff --git a/samples/traderx/api-mocks/trade-processor-examples.yaml b/samples/traderx/api-mocks/trade-processor-examples.yaml index 633c72e..7658e84 100644 --- a/samples/traderx/api-mocks/trade-processor-examples.yaml +++ b/samples/traderx/api-mocks/trade-processor-examples.yaml @@ -26,4 +26,4 @@ operations: quantity: 100 side: Buy state: Processing - createdAt: {{ now()}} \ No newline at end of file + createdAt: '{{ now()}}' \ No newline at end of file diff --git a/samples/traderx/demo-0.sh b/samples/traderx/demo-0.sh new file mode 100755 index 0000000..2f20954 --- /dev/null +++ b/samples/traderx/demo-0.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# setup +if [ ! -f demo-magic.sh ]; then + curl -LO https://github.com/paxtonhare/demo-magic/raw/master/demo-magic.sh +fi +. demo-magic.sh -d #-n +clear + +# Demo setup +alias k=kubectl +make k8s-down +make compose-down +rm -rf .score-compose +rm -rf .score-k8s +clear + +# Demo #0 +pe "echo \"Demo #0 - score-k8s\"" +pe "make k8s-up" +pe "kubectl get all" +pe "kubectl get pods" +pe "score-k8s resources get-outputs dns.default#ingress.dns --format 'http://{{ .host }}'" \ No newline at end of file diff --git a/samples/traderx/demo-1-2.sh b/samples/traderx/demo-1-2.sh new file mode 100755 index 0000000..552cbff --- /dev/null +++ b/samples/traderx/demo-1-2.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# setup +if [ ! -f demo-magic.sh ]; then + curl -LO https://github.com/paxtonhare/demo-magic/raw/master/demo-magic.sh +fi +. demo-magic.sh -d #-n +clear + +# Demo #1 +pe "echo \"Demo #1 - score-k8s\"" +pe "code trade-service/score.yaml" +pe "code -g Makefile:72" +pe "code manifests.yaml" +pe "kubectl get all" +pe "kubectl get pods" +pe "score-k8s resources get-outputs dns.default#ingress.dns --format 'http://{{ .host }}'" + +# Demo #2 +pe "echo \"Demo #2 - score-compose\"" +clear +pe "code trade-service/score.yaml" +pe "code -g Makefile:21" +pe "make compose-up" +pe "code compose.yaml" +pe "docker ps" +pe "echo http://localhost:8080" + diff --git a/samples/traderx/demo-3.sh b/samples/traderx/demo-3.sh new file mode 100755 index 0000000..2fca7cc --- /dev/null +++ b/samples/traderx/demo-3.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# setup +if [ ! -f demo-magic.sh ]; then + curl -LO https://github.com/paxtonhare/demo-magic/raw/master/demo-magic.sh +fi +. demo-magic.sh -d #-n +clear + +# Demo setup +make compose-down +rm -rf .score-compose +clear + +# Demo #3 +pe "echo \"Demo #3 - score-compose (Mocks)\"" +pe "code trade-service/score.yaml" +pe "code -g Makefile:47" +pe "make compose-mock-up" +pe "code compose.yaml" +pe "docker ps" +pe "echo http://localhost:8080" +pe "echo http://localhost:9090" + diff --git a/samples/traderx/demo-4.sh b/samples/traderx/demo-4.sh new file mode 100755 index 0000000..a189f62 --- /dev/null +++ b/samples/traderx/demo-4.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# setup +if [ ! -f demo-magic.sh ]; then + curl -LO https://github.com/paxtonhare/demo-magic/raw/master/demo-magic.sh +fi +. demo-magic.sh -d #-n +clear + +# Demo setup +alias k=kubectl +make k8s-down +rm -rf .score-k8s +clear + +# Demo #4 +clear +pe "echo \"Demo #4 - score-k8s (Mocks)\"" +pe "code trade-service/score.yaml" +pe "code -g Makefile:88" +pe "make k8s-mock-up" +pe "code manifests.yaml" +pe "kubectl get all" +pe "kubectl get pods" +pe "score-k8s resources get-outputs dns.default#ingress.dns --format 'http://{{ .host }}'" +pe "echo https://microcks.127.0.0.1.nip.io/" + diff --git a/samples/traderx/ingress/Dockerfile b/samples/traderx/ingress/Dockerfile index 9f5c8fd..93abe89 100644 --- a/samples/traderx/ingress/Dockerfile +++ b/samples/traderx/ingress/Dockerfile @@ -1,13 +1,35 @@ 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 +ARG DATABASE_URL="http://database:18084/" +ENV DATABASE_URL=$DATABASE_URL + +ARG TRADE_PROCESSOR_URL="http://trade-processor:18091/" +ENV TRADE_PROCESSOR_URL=$TRADE_PROCESSOR_URL + +ARG ACCOUNT_SERVICE_URL="http://account-service:18088/" +ENV ACCOUNT_SERVICE_URL=$ACCOUNT_SERVICE_URL + +ARG PEOPLE_SERVICE_URL="http://people-service:18089/" +ENV PEOPLE_SERVICE_URL=$PEOPLE_SERVICE_URL + +ARG POSITION_SERVICE_URL="http://position-service:18090/" +ENV POSITION_SERVICE_URL=$POSITION_SERVICE_URL + +ARG REFERENCE_DATA_URL="http://reference-data:18085/" +ENV REFERENCE_DATA_URL=$REFERENCE_DATA_URL + +ARG TRADE_FEED_URL="http://trade-feed:18086/" +ENV TRADE_FEED_URL=$TRADE_FEED_URL + +ARG WEB_FRONTEND_URL="http://web-frontend:18093/" +ENV WEB_FRONTEND_URL=$WEB_FRONTEND_URL -COPY nginx.traderx.conf.template /etc/nginx/conf.d/nginx.traderx.conf.template +ARG TRADE_SERVICE_URL="http://trade-service:18092/" +ENV TRADE_SERVICE_URL=$TRADE_SERVICE_URL -RUN envsubst < /etc/nginx/conf.d/nginx.traderx.conf.template > /etc/nginx/conf.d/default.conf \ No newline at end of file +COPY nginx.traderx.conf.template /etc/nginx/templates/ \ No newline at end of file diff --git a/samples/traderx/ingress/nginx.traderx.conf.template b/samples/traderx/ingress/nginx.traderx.conf.template index 9cb542d..dc0fa55 100644 --- a/samples/traderx/ingress/nginx.traderx.conf.template +++ b/samples/traderx/ingress/nginx.traderx.conf.template @@ -1,61 +1,59 @@ server { listen 8080; - server_name $NGINX_HOST; + server_name ${NGINX_HOST}; location /db-web/ { - proxy_pass http://database-database:18084/; + proxy_pass ${DATABASE_URL}; } location /reference-data/ { - proxy_pass http://reference-data-reference-data:18085/; + proxy_pass ${REFERENCE_DATA_URL}; } location /ng-cli-ws { - proxy_pass http://web-frontend-web-frontend:18093/ng-cli-ws; + proxy_pass ${WEB_FRONTEND_URL}/ng-cli-ws; proxy_http_version 1.1; - proxy_set_header Upgrade ${DOLLAR}http_upgrade; + proxy_set_header Upgrade $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_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; - proxy_pass http://trade-feed-trade-feed:18086/; + proxy_pass ${TRADE_FEED_URL}; proxy_http_version 1.1; - proxy_set_header Upgrade ${DOLLAR}http_upgrade; + proxy_set_header Upgrade $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; + location /socket.io/ { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; - proxy_pass http://trade-feed-trade-feed:18086/socket.io/; + proxy_pass ${TRADE_FEED_URL}/socket.io/; proxy_http_version 1.1; - proxy_set_header Upgrade ${DOLLAR}http_upgrade; + proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - } location /people-service/ { - proxy_pass http://people-service-people-service:18089/; + proxy_pass ${PEOPLE_SERVICE_URL}; } location /account-service/ { - proxy_pass http://account-service-account-service:18088/; + proxy_pass ${ACCOUNT_SERVICE_URL}; } location /position-service/ { - proxy_pass http://position-service-position-service:18090/; + proxy_pass ${POSITION_SERVICE_URL}; } location /trade-service/ { - proxy_pass http://trade-service-trade-service:18092/; + proxy_pass ${TRADE_SERVICE_URL}; } location /trade-processor/ { - proxy_pass http://trade-processor-trade-processor:18091/; + proxy_pass ${TRADE_PROCESSOR_URL}; } location / { - proxy_pass http://web-frontend-web-frontend:18093/; + proxy_pass ${WEB_FRONTEND_URL}; } } \ No newline at end of file diff --git a/samples/traderx/ingress/score.yaml b/samples/traderx/ingress/score.yaml index 7b14fec..1599f12 100644 --- a/samples/traderx/ingress/score.yaml +++ b/samples/traderx/ingress/score.yaml @@ -7,7 +7,15 @@ containers: ingress: image: . variables: - DATABASE_TCP_HOST: "${resources.database.name}" + DATABASE_URL: "${resources.database.url}" + TRADE_PROCESSOR_URL: "${resources.trade-processor.url}" + POSITION_SERVICE_URL: "${resources.position-service.url}" + PEOPLE_SERVICE_URL: "${resources.people-service.url}" + REFERENCE_DATA_URL: "${resources.reference-data.url}" + ACCOUNT_SERVICE_URL: "${resources.account-service.url}" + WEB_FRONTEND_URL: "${resources.web-frontend.url}" + TRADE_SERVICE_URL: "${resources.trade-service.url}" + TRADE_FEED_URL: "${resources.trade-feed.url}" service: ports: web: @@ -16,20 +24,55 @@ service: resources: people-service: type: service + params: + port: 18089 + artifacts: api-mocks/people-service-openapi.json:true,api-mocks/people-service-metadata.yaml:false,api-mocks/people-service-examples.yaml:false + name: FINOS TraderX People Service + version: v1 + position-service: + type: service + params: + port: 18090 + artifacts: api-mocks/position-service-openapi.json:true,api-mocks/position-service-examples.yaml:false + name: FINOS TraderX Position Service + version: 0.1.0 trade-service: type: service + params: + port: 18092 account-service: type: service + params: + port: 18088 + artifacts: api-mocks/account-service-openapi.json:true,api-mocks/account-service-examples.yaml:false + name: FINOS TraderX Account Service + version: 0.1.0 reference-data: type: service + params: + port: 18085 + artifacts: api-mocks/reference-data-openapi.json:true,api-mocks/reference-data-examples.yaml:false + name: FINOS TraderX Reference Data + version: '1.0' trade-feed: type: service + params: + port: 18086 trade-processor: type: service + params: + port: 18091 + artifacts: api-mocks/trade-processor-openapi.json:true,api-mocks/trade-processor-examples.yaml:false + name: FINOS TraderX Trade Processor + version: 0.1.0 web-frontend: type: service + params: + port: 18093 database: type: service + params: + port: 18084 dns: type: dns route: diff --git a/samples/traderx/position-service/score.yaml b/samples/traderx/position-service/score.yaml index 51c9be4..491138e 100644 --- a/samples/traderx/position-service/score.yaml +++ b/samples/traderx/position-service/score.yaml @@ -7,6 +7,7 @@ containers: position-service: image: ghcr.io/finos/traderx/position-service:latest variables: + POSITION_SERVICE_PORT: '18090' DATABASE_TCP_HOST: "${resources.database.name}" service: ports: diff --git a/samples/traderx/score-provisioners/compose/10-service-with-microcks.provisioners.yaml b/samples/traderx/score-provisioners/compose/10-service-with-microcks.provisioners.yaml new file mode 100644 index 0000000..cdb0c97 --- /dev/null +++ b/samples/traderx/score-provisioners/compose/10-service-with-microcks.provisioners.yaml @@ -0,0 +1,59 @@ +# Custom updates for now, will need to contribute back to the community provisioners repository later on. +- uri: template://custom-provisioners/service-with-microcks + type: service + description: Outputs a service URL for connecting to an other workload (a Microcks mock is generated if not found). + init: | + hostname: {{ splitList "." .Id | last }} + {{ if .Params.artifacts }} + {{ $artifacts := .Params.artifacts | splitList "," }} + {{ $parsedPath := $artifacts | first | splitList "/" }} + {{ if eq (len $parsedPath) 0 }} + resourcesPath: "." + {{ else }} + resourcesPath: {{ trimSuffix (last $parsedPath) (first $artifacts) | trimSuffix "/" }} + {{ end }} + {{ end }} + supported_params: + - port + - artifacts + - name + - version + outputs: | + {{ $w := (index .WorkloadServices .Init.hostname) }} + {{ if or (not $w) (not $w.ServiceName) }} + url: http://microcks:8080/rest/{{ .Params.name | replace " " "+" }}/{{ .Params.version }}/ + {{ else }} + url: http://{{ .Init.hostname }}:{{ .Params.port }}/ + {{ end }} + name: {{ .Init.hostname }} + expected_outputs: + - url + - name + services: | + {{ $w := (index .WorkloadServices .Init.hostname) }} + {{ if or (not $w) (not $w.ServiceName) }} + {{ .Init.hostname }}-mock: + image: quay.io/microcks/microcks-cli:latest + restart: on-failure + entrypoint: + - "microcks" + - "import" + - "{{ .Params.artifacts }}" + - "--microcksURL=http://microcks:8080/api" + - "--insecure-tls" + - "--keycloakClientId=foo" + - "--keycloakClientSecret=bar" + cap_drop: + - ALL + read_only: true + user: "65532" + volumes: + - type: bind + source: {{ .Init.resourcesPath }} + target: /{{ .Init.resourcesPath }} + read_only: true + depends_on: + microcks: + condition: service_started + required: true + {{ end }} \ No newline at end of file diff --git a/samples/traderx/score-provisioners/k8s/10-service-with-microcks-cli.provisioners.yaml b/samples/traderx/score-provisioners/k8s/10-service-with-microcks-cli.provisioners.yaml new file mode 100644 index 0000000..652e75e --- /dev/null +++ b/samples/traderx/score-provisioners/k8s/10-service-with-microcks-cli.provisioners.yaml @@ -0,0 +1,33 @@ +# Custom updates for now, will need to contribute back to the community provisioners repository later on. +- uri: cmd://bash#service-with-microcks-cli + type: service + description: Outputs a service URL for connecting to an other workload (a Microcks mock is generated if not found). + supported_params: + - port + - artifacts + - name + - version + expected_outputs: + - url + - name + args: + - -c + - | + STDIN=$(cat) + PARAM_PORT=$(echo $STDIN | yq eval -p json '.resource_params.port') + PARAM_NAME=$(echo $STDIN | yq eval -p json '.resource_params.name') + PARAM_VERSION=$(echo $STDIN | yq eval -p json '.resource_params.version') + PARAM_ARTIFACTS=$(echo $STDIN | yq eval -p json '.resource_params.artifacts') + WORKLOAD=$(echo $STDIN | yq eval -p json '.resource_id | split(".") | .[-1]') + WORKLOAD_EXISTS=$(echo $STDIN | WORKLOAD=${WORKLOAD} yq eval -p json '.workload_services | has(strenv(WORKLOAD))') + URL_HOSTNAME=${WORKLOAD}:${PARAM_PORT} + URL_SCHEME="http" + URL_PATH="" + if [ "$WORKLOAD_EXISTS" != "true" ]; then + URL_HOSTNAME="microcks.microcks.svc.cluster.local:8080" + URL_PATH=/rest/$(echo $PARAM_NAME | yq '. |= sub(" ", "+")')/$PARAM_VERSION + set -eu -o pipefail + microcks import ${PARAM_ARTIFACTS} --microcksURL=https://microcks.127.0.0.1.nip.io --insecure-tls --keycloakClientId=foo --keycloakClientSecret=bar >&2 + fi + OUTPUTS='{"resource_outputs":{"url":"%s://%s%s/","name":"%s"},"manifests":[]}' + printf "$OUTPUTS" "$URL_SCHEME" "$URL_HOSTNAME" "$URL_PATH" "$WORKLOAD" \ No newline at end of file diff --git a/samples/traderx/setup-kind-cluster.sh b/samples/traderx/setup-kind-cluster.sh new file mode 100755 index 0000000..f4774b8 --- /dev/null +++ b/samples/traderx/setup-kind-cluster.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -o errexit + +cat <