Skip to content

Commit

Permalink
Merge pull request #97 from steadybit/feat/order-go
Browse files Browse the repository at this point in the history
orders in go
  • Loading branch information
ansgarschulte authored Jan 29, 2025
2 parents aff83f4 + 6ab5143 commit 9eff233
Show file tree
Hide file tree
Showing 12 changed files with 272 additions and 17 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ jobs:
- {folder: inventory-service-mock, name: inventory}
- {folder: inventory-service-mock-go, name: inventory-go}
- {folder: order, name: orders}
- {folder: order, name: orders-go}
steps:
- uses: actions/checkout@v4

Expand Down
Binary file removed bestseller-toys-go/products.db
Binary file not shown.
2 changes: 1 addition & 1 deletion charts/steadybit-shopping-demo/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v2
name: steadybit-shopping-demo
description: Steadybit shopping-demo application Helm chart for Kubernetes.
version: 1.1.9
version: 1.1.10
appVersion: latest
type: application
home: https://www.steadybit.com/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ manifest should match snapshot:
valueFrom:
fieldRef:
fieldPath: metadata.labels['tags.datadoghq.com/version']
image: steadybit/orders:develop
image: steadybit/orders-go:develop
imagePullPolicy: Always
livenessProbe:
httpGet:
Expand Down Expand Up @@ -134,7 +134,7 @@ manifest should match snapshot replica count:
valueFrom:
fieldRef:
fieldPath: metadata.labels['tags.datadoghq.com/version']
image: steadybit/orders:develop
image: steadybit/orders-go:develop
imagePullPolicy: Always
livenessProbe:
httpGet:
Expand Down Expand Up @@ -236,7 +236,7 @@ manifest should match snapshot with horizontalPodAutoscaler and podDisruptionBud
valueFrom:
fieldRef:
fieldPath: metadata.labels['tags.datadoghq.com/version']
image: steadybit/orders:develop
image: steadybit/orders-go:develop
imagePullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion charts/steadybit-shopping-demo/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ orders:
enabled: true
image:
# Container image name
name: steadybit/orders
name: steadybit/orders-go
# Container image tag
tag: develop
# Container resources
Expand Down
25 changes: 13 additions & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,60 @@ version: '3.3'

services:
gateway:
image: steadybit/gateway:1.0.0-SNAPSHOT
image: steadybit/gateway:develop
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: docker

fashion:
image: steadybit/bestseller-fashion:1.0.0-SNAPSHOT
image: steadybit/bestseller-fashion:develop
ports:
- "8082:8082"
environment:
"rest.endpoint.inventory": "http://inventory:8084/inventory"

toys:
image: steadybit/bestseller-toys:1.0.0-SNAPSHOT
image: steadybit/bestseller-toys-go:develop
ports:
- "8081:8081"
environment:
"rest.endpoint.inventory": "http://inventory:8084/inventory"

hot-deals:
image: steadybit/hot-deals:1.0.0-SNAPSHOT
image: steadybit/hot-deals:develop
ports:
- "8083:8083"
environment:
"rest.endpoint.inventory": "http://inventory:8084/inventory"

inventory:
image: steadybit/inventory:1.0.0-SNAPSHOT
image: steadybit/inventory-go:develop
ports:
- "8084:8084"

checkout:
image: steadybit/checkout:1.0.0-SNAPSHOT
image: steadybit/checkout:develop
ports:
- "8085:8085"
environment:
"spring.activemq.broker-url": "tcp://activemq:61616"
depends_on:
- activemq

orders:
image: steadybit/orders:1.0.0-SNAPSHOT
environment:
"spring.activemq.broker-url": "tcp://activemq:61616"
depends_on:
- activemq
# orders:
# image: steadybit/orders:develop
# environment:
# "spring.activemq.broker-url": "tcp://activemq:61616"
# depends_on:
# - activemq

activemq:
image: symptoma/activemq:latest
container_name: 'activemq'
ports:
- "61616:61616"
- "61613:61613"
- "8161:8161"
volumes:
- ${PWD}/activemq.xml:/opt/activemq/conf/activemq.xml
Empty file added order-go/Dockerfile
Empty file.
Empty file added order-go/LICENSE
Empty file.
25 changes: 25 additions & 0 deletions order-go/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
build:
go build -o order main.go

run:
go run main.go

docker-build:
docker build -t order .

docker-run:
docker run -p 8086:8086 order

## licenses-report: generate a report of all licenses
.PHONY: licenses-report
licenses-report:
ifeq ($(SKIP_LICENSES_REPORT), true)
@echo "Skipping licenses report"
rm -rf ./licenses && mkdir -p ./licenses
else
@echo "Generating licenses report"
rm -rf ./licenses
go run github.com/google/[email protected] save . --save_path ./licenses
go run github.com/google/[email protected] report . > ./licenses/THIRD-PARTY.csv
cp LICENSE ./licenses/LICENSE.txt
endif
24 changes: 24 additions & 0 deletions order-go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module order

go 1.23.4

require (
github.com/prometheus/client_golang v1.20.5
github.com/rs/zerolog v1.33.0
github.com/steadybit/extension-kit v1.8.23
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/go-stomp/stomp/v3 v3.1.3 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
golang.org/x/sys v0.29.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
)
80 changes: 80 additions & 0 deletions order-go/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-stomp/stomp/v3 v3.1.3 h1:5/wi+bI38O1Qkf2cc7Gjlw7N5beHMWB/BxpX+4p/MGI=
github.com/go-stomp/stomp/v3 v3.1.3/go.mod h1:ztzZej6T2W4Y6FlD+Tb5n7HQP3/O5UNQiuC169pIp10=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/steadybit/extension-kit v1.8.23 h1:YyHCP1cfETOmOX8Bn21n+E910IhbjQZIWoV4Eu9Ks28=
github.com/steadybit/extension-kit v1.8.23/go.mod h1:qUiOw0OJUkyuz9hkLkGfksc09JRkSyrKEiiIiuVc3+o=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
124 changes: 124 additions & 0 deletions order-go/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright 2025 steadybit GmbH. All rights reserved.
*/

package main

import (
"encoding/json"
stomp "github.com/go-stomp/stomp/v3"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/rs/zerolog/log"
"github.com/steadybit/extension-kit/extlogging"
"net/http"
"os"
"time"
)

func healthHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte("OK"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

func readinessHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte("READY"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

type OrderItem struct {
ProductID string `json:"productId"`
Quantity int `json:"quantity"`
Price float64 `json:"price"`
}
type Order struct {
ID string `json:"id"`
Submitted string `json:"submitted"`
Items []OrderItem `json:"items"`
}

func main() {
log.Info().Msg("Starting Order Application...")
extlogging.InitZeroLog()

// Retrieve ActiveMQ connection info from environment variables (or use defaults).
brokerAddr, found := os.LookupEnv("SPRING_ACTIVEMQ_BROKER_URL")
if !found {
brokerAddr, found = os.LookupEnv("spring.activemq.broker-url")
}
if !found {
brokerAddr = "localhost:61613"
}
user := os.Getenv("ACTIVEMQ_USER")
pass := os.Getenv("ACTIVEMQ_PASS")

// 1) Connect to ActiveMQ using STOMP.
var conn *stomp.Conn
var err error
if user == "" {
conn, err = stomp.Dial("tcp", brokerAddr, stomp.ConnOpt.HeartBeat(5*time.Second, 5*time.Second))
} else {
conn, err = stomp.Dial("tcp", brokerAddr, stomp.ConnOpt.Login(user, pass), stomp.ConnOpt.HeartBeat(5*time.Second, 5*time.Second))
}
if err != nil {
log.Error().Err(err).Msg("Failed to connect to ActiveMQ")
}
defer func() {
if conn != nil {
_ = conn.Disconnect()
}
}()

// 2) Subscribe to the "order_created" queue. (Equivalent of @JmsListener in Java.)
if conn == nil {
log.Error().Msg("Connection to ActiveMQ is nil")
return
}
sub, err := conn.Subscribe("order_created", stomp.AckAuto)
if err != nil {
log.Error().Err(err).Msg("Failed to subscribe to queue")
}

// 3) Consume messages in a separate goroutine.
// Unmarshal into an Order object and log it.
go func() {
for {
msg := <-sub.C
if msg == nil {
continue
}
if msg.Err != nil {
log.Error().Err(msg.Err).Msg("Failed to receive message")
continue
}
if msg.Body == nil {
continue
}
var order Order
if err := json.Unmarshal(msg.Body, &order); err != nil {
log.Error().Err(err).Msg("Failed to unmarshal message")
continue
}

log.Info().Str("orderID", order.ID).Msg("Received order")
}
}()

http.Handle("/metrics", promhttp.Handler())

// Setup HTTP server
http.HandleFunc("/actuator/health/liveness", healthHandler) // Liveness Probe
http.HandleFunc("/actuator/health/readiness", readinessHandler) // Readiness Probe
port := "8086"
println("Server running on port:", port)
if err := http.ListenAndServe(":"+port, nil); err != nil {
panic(err)
}
}

0 comments on commit 9eff233

Please sign in to comment.