From 34e044585729d1cd724eda28d6553888ca84777a Mon Sep 17 00:00:00 2001 From: matst80 Date: Mon, 10 Nov 2025 22:28:58 +0100 Subject: [PATCH 01/18] Update main.go --- cmd/inventory/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/inventory/main.go b/cmd/inventory/main.go index db5bf1a..c914d49 100644 --- a/cmd/inventory/main.go +++ b/cmd/inventory/main.go @@ -103,6 +103,7 @@ func main() { amqpUrl, ok := os.LookupEnv("RABBIT_HOST") if ok { + log.Printf("Connecting to rabbitmq") conn, err := amqp.DialConfig(amqpUrl, amqp.Config{ Properties: amqp.NewConnectionProperties(), }) From ed9a02227e80e247349776666a590f8e2bb69146 Mon Sep 17 00:00:00 2001 From: matst80 Date: Mon, 10 Nov 2025 22:34:38 +0100 Subject: [PATCH 02/18] update deployment --- deployment/deployment.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deployment/deployment.yaml b/deployment/deployment.yaml index 16dc40f..cc49370 100644 --- a/deployment/deployment.yaml +++ b/deployment/deployment.yaml @@ -452,6 +452,8 @@ spec: env: - name: TZ value: "Europe/Stockholm" + - name: RABBIT_HOST + value: amqp://admin:12bananer@rabbitmq.s10n:5672/ - name: REDIS_ADDRESS value: "10.10.3.18:6379" - name: REDIS_PASSWORD From af7ce205570e8e0ad7c0b2057025c17b63c7fdee Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 08:51:56 +0100 Subject: [PATCH 03/18] update --- cmd/cart/checkout_server.go | 14 ++++++++++++++ cmd/cart/pool-server.go | 1 + 2 files changed, 15 insertions(+) diff --git a/cmd/cart/checkout_server.go b/cmd/cart/checkout_server.go index 7d41e9a..4c4e6a9 100644 --- a/cmd/cart/checkout_server.go +++ b/cmd/cart/checkout_server.go @@ -12,6 +12,20 @@ import ( amqp "github.com/rabbitmq/amqp091-go" ) +var tpl = ` + + + + + s10r testing - checkout + + + + %s + + +` + func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux) { conn, err := amqp.Dial(amqpUrl) if err != nil { diff --git a/cmd/cart/pool-server.go b/cmd/cart/pool-server.go index 499c5b4..296ff64 100644 --- a/cmd/cart/pool-server.go +++ b/cmd/cart/pool-server.go @@ -552,6 +552,7 @@ func (s *PoolServer) CheckoutHandler(fn func(order *CheckoutOrder, w http.Respon if orderId == "" { order, err := s.CreateOrUpdateCheckout(r.Context(), r.Host, cartId) if err != nil { + logger.Error("unable to create klarna session", err) return err } s.ApplyCheckoutStarted(order, cartId) From 5d4d917f6aa09547f0ced45d5cd1467c59c58633 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 09:06:51 +0100 Subject: [PATCH 04/18] Update main.go --- cmd/cart/main.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/cmd/cart/main.go b/cmd/cart/main.go index 30d515f..c6a479b 100644 --- a/cmd/cart/main.go +++ b/cmd/cart/main.go @@ -46,20 +46,6 @@ var podIp = os.Getenv("POD_IP") var name = os.Getenv("POD_NAME") var amqpUrl = os.Getenv("AMQP_URL") -var tpl = ` - - - - - s10r testing - checkout - - - - %s - - -` - func getCountryFromHost(host string) string { if strings.Contains(strings.ToLower(host), "-no") { return "no" From ab5d9cb2b7c877c681498ca1935a6ec05ad4d5e4 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 09:29:51 +0100 Subject: [PATCH 05/18] try to reserve --- cmd/cart/checkout_server.go | 7 +++++++ cmd/cart/main.go | 15 +++++++++++++- cmd/cart/pool-server.go | 41 +++++++++++++++++++++++++++++++------ 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/cmd/cart/checkout_server.go b/cmd/cart/checkout_server.go index 4c4e6a9..b724fc0 100644 --- a/cmd/cart/checkout_server.go +++ b/cmd/cart/checkout_server.go @@ -129,6 +129,13 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux) { } log.Printf("Klarna order validation: %s", order.ID) + // inventoryRequests := getInventoryRequests(grain.Items) + // failingRequest, err := s.inventoryService.ReservationCheck(inventoryRequests...) + // if err != nil { + // logger.WarnContext(ctx, "inventory check failed", string(failingRequest.SKU), string(failingRequest.LocationID)) + // return nil, err + // } + w.WriteHeader(http.StatusOK) }) } diff --git a/cmd/cart/main.go b/cmd/cart/main.go index c6a479b..8b8f38b 100644 --- a/cmd/cart/main.go +++ b/cmd/cart/main.go @@ -19,9 +19,11 @@ import ( "git.tornberg.me/go-cart-actor/pkg/promotions" "git.tornberg.me/go-cart-actor/pkg/proxy" "git.tornberg.me/go-cart-actor/pkg/voucher" + "git.tornberg.me/mats/go-redis-inventory/pkg/inventory" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/redis/go-redis/v9" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) @@ -45,6 +47,8 @@ type App struct { var podIp = os.Getenv("POD_IP") var name = os.Getenv("POD_NAME") var amqpUrl = os.Getenv("AMQP_URL") +var redisAddress = os.Getenv("REDIS_ADDRESS") +var redisPassword = os.Getenv("REDIS_PASSWORD") func getCountryFromHost(host string) string { if strings.Contains(strings.ToLower(host), "-no") { @@ -119,8 +123,17 @@ func main() { } klarnaClient := NewKlarnaClient(KlarnaPlaygroundUrl, os.Getenv("KLARNA_API_USERNAME"), os.Getenv("KLARNA_API_PASSWORD")) + rdb := redis.NewClient(&redis.Options{ + Addr: redisAddress, + Password: redisPassword, + DB: 0, + }) + inventoryService, err := inventory.NewRedisInventoryService(rdb, context.Background()) + if err != nil { + log.Fatalf("Error creating inventory service: %v\n", err) + } - syncedServer := NewPoolServer(pool, fmt.Sprintf("%s, %s", name, podIp), klarnaClient) + syncedServer := NewPoolServer(pool, fmt.Sprintf("%s, %s", name, podIp), klarnaClient, inventoryService) app := &App{ pool: pool, diff --git a/cmd/cart/pool-server.go b/cmd/cart/pool-server.go index 296ff64..436ce66 100644 --- a/cmd/cart/pool-server.go +++ b/cmd/cart/pool-server.go @@ -15,6 +15,7 @@ import ( "git.tornberg.me/go-cart-actor/pkg/cart" messages "git.tornberg.me/go-cart-actor/pkg/messages" "git.tornberg.me/go-cart-actor/pkg/voucher" + "git.tornberg.me/mats/go-redis-inventory/pkg/inventory" "github.com/gogo/protobuf/proto" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -40,15 +41,17 @@ var ( type PoolServer struct { actor.GrainPool[*cart.CartGrain] - pod_name string - klarnaClient *KlarnaClient + pod_name string + klarnaClient *KlarnaClient + inventoryService inventory.InventoryService } -func NewPoolServer(pool actor.GrainPool[*cart.CartGrain], pod_name string, klarnaClient *KlarnaClient) *PoolServer { +func NewPoolServer(pool actor.GrainPool[*cart.CartGrain], pod_name string, klarnaClient *KlarnaClient, inventoryService inventory.InventoryService) *PoolServer { return &PoolServer{ - GrainPool: pool, - pod_name: pod_name, - klarnaClient: klarnaClient, + GrainPool: pool, + pod_name: pod_name, + klarnaClient: klarnaClient, + inventoryService: inventoryService, } } @@ -310,6 +313,25 @@ func getLocale(country string) string { return "sv-se" } +func getLocationId(item *cart.CartItem) inventory.LocationID { + if item.StoreId == nil || *item.StoreId == "" { + return "se" + } + return inventory.LocationID(*item.StoreId) +} + +func getInventoryRequests(items []*cart.CartItem) []inventory.ReserveRequest { + var requests []inventory.ReserveRequest + for _, item := range items { + requests = append(requests, inventory.ReserveRequest{ + SKU: inventory.SKU(item.Sku), + LocationID: getLocationId(item), + Quantity: uint32(item.Quantity), + }) + } + return requests +} + func (s *PoolServer) CreateOrUpdateCheckout(ctx context.Context, host string, id cart.CartId) (*CheckoutOrder, error) { country := getCountryFromHost(host) meta := &CheckoutMeta{ @@ -329,6 +351,13 @@ func (s *PoolServer) CreateOrUpdateCheckout(ctx context.Context, host string, id return nil, err } + inventoryRequests := getInventoryRequests(grain.Items) + failingRequest, err := s.inventoryService.ReservationCheck(inventoryRequests...) + if err != nil { + logger.WarnContext(ctx, "inventory check failed", string(failingRequest.SKU), string(failingRequest.LocationID)) + return nil, err + } + // Build pure checkout payload payload, _, err := BuildCheckoutOrderPayload(grain, meta) if err != nil { From 19fc5a9553632f28780197f74867eaacd6a818d3 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 09:40:12 +0100 Subject: [PATCH 06/18] correct the discount sums --- pkg/cart/cart-grain.go | 2 +- pkg/cart/cart_grain_totals_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/cart/cart-grain.go b/pkg/cart/cart-grain.go index 5c5816b..f9c0e3d 100644 --- a/pkg/cart/cart-grain.go +++ b/pkg/cart/cart-grain.go @@ -249,7 +249,7 @@ func (c *CartGrain) UpdateTotals() { c.TotalDiscount = NewPrice() for _, item := range c.Items { - rowTotal := MultiplyPrice(item.Price, int64(item.Quantity)) + rowTotal := MultiplyPrice(*item.OrgPrice, int64(item.Quantity)) if item.OrgPrice != nil { diff := NewPrice() diff --git a/pkg/cart/cart_grain_totals_test.go b/pkg/cart/cart_grain_totals_test.go index 135a6a7..b05b069 100644 --- a/pkg/cart/cart_grain_totals_test.go +++ b/pkg/cart/cart_grain_totals_test.go @@ -34,8 +34,8 @@ func TestCartGrainUpdateTotalsBasic(t *testing.T) { } // Discount: current implementation computes (OrgPrice - Price) ignoring quantity -> 1500-1250=250 - if c.TotalDiscount.IncVat != 250 { - t.Fatalf("TotalDiscount expected 250 got %d", c.TotalDiscount.IncVat) + if c.TotalDiscount.IncVat != 500 { + t.Fatalf("TotalDiscount expected 500 got %d", c.TotalDiscount.IncVat) } } From 3fa0009b9592a0ddd6eec800f9288c30ca6c30ac Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 09:44:40 +0100 Subject: [PATCH 07/18] Update deployment.yaml --- deployment/deployment.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/deployment/deployment.yaml b/deployment/deployment.yaml index cc49370..264640d 100644 --- a/deployment/deployment.yaml +++ b/deployment/deployment.yaml @@ -177,6 +177,10 @@ spec: secretKeyRef: name: klarna-api-credentials key: username + - name: REDIS_ADDRESS + value: "redis.home:6379" + - name: REDIS_PASSWORD + value: "slaskredis" - name: OTEL_RESOURCE_ATTRIBUTES value: "service.name=cart,service.version=0.1.2" - name: OTEL_EXPORTER_OTLP_ENDPOINT @@ -280,6 +284,10 @@ spec: env: - name: TZ value: "Europe/Stockholm" + - name: REDIS_ADDRESS + value: "redis.home:6379" + - name: REDIS_PASSWORD + value: "slaskredis" - name: OTEL_RESOURCE_ATTRIBUTES value: "service.name=cart,service.version=0.1.2" - name: OTEL_EXPORTER_OTLP_ENDPOINT @@ -455,6 +463,6 @@ spec: - name: RABBIT_HOST value: amqp://admin:12bananer@rabbitmq.s10n:5672/ - name: REDIS_ADDRESS - value: "10.10.3.18:6379" + value: "redis.home:6379" - name: REDIS_PASSWORD value: "slaskredis" From 81246fe4979c049e96ff7129fab4733891a40d32 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 09:52:52 +0100 Subject: [PATCH 08/18] Update cart-grain.go --- pkg/cart/cart-grain.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cart/cart-grain.go b/pkg/cart/cart-grain.go index f9c0e3d..937933b 100644 --- a/pkg/cart/cart-grain.go +++ b/pkg/cart/cart-grain.go @@ -249,14 +249,14 @@ func (c *CartGrain) UpdateTotals() { c.TotalDiscount = NewPrice() for _, item := range c.Items { - rowTotal := MultiplyPrice(*item.OrgPrice, int64(item.Quantity)) + rowTotal := MultiplyPrice(item.Price, int64(item.Quantity)) if item.OrgPrice != nil { diff := NewPrice() diff.Add(*item.OrgPrice) diff.Subtract(item.Price) diff.Multiply(int64(item.Quantity)) - rowTotal.Subtract(*diff) + //rowTotal.Subtract(*diff) item.Discount = diff if diff.IncVat > 0 { c.TotalDiscount.Add(*diff) From 756a43b34253594bbf921b84e4fd7125ca002f0e Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 11:47:05 +0100 Subject: [PATCH 09/18] reserve inventory when order placed --- cmd/cart/checkout_server.go | 27 ++++++++++++++++++++------- cmd/cart/main.go | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/cmd/cart/checkout_server.go b/cmd/cart/checkout_server.go index b724fc0..9cdb49f 100644 --- a/cmd/cart/checkout_server.go +++ b/cmd/cart/checkout_server.go @@ -9,6 +9,7 @@ import ( "git.tornberg.me/go-cart-actor/pkg/actor" "git.tornberg.me/go-cart-actor/pkg/cart" + "git.tornberg.me/mats/go-redis-inventory/pkg/inventory" amqp "github.com/rabbitmq/amqp091-go" ) @@ -26,7 +27,7 @@ var tpl = ` ` -func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux) { +func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, inventoryService inventory.InventoryService) { conn, err := amqp.Dial(amqpUrl) if err != nil { log.Fatalf("failed to connect to RabbitMQ: %v", err) @@ -128,13 +129,25 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux) { w.WriteHeader(http.StatusBadRequest) } log.Printf("Klarna order validation: %s", order.ID) + cartId, ok := cart.ParseCartId(order.MerchantReference1) + if !ok { + w.WriteHeader(http.StatusBadRequest) + return + } - // inventoryRequests := getInventoryRequests(grain.Items) - // failingRequest, err := s.inventoryService.ReservationCheck(inventoryRequests...) - // if err != nil { - // logger.WarnContext(ctx, "inventory check failed", string(failingRequest.SKU), string(failingRequest.LocationID)) - // return nil, err - // } + grain, err := a.pool.Get(uint64(cartId)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + inventoryRequests := getInventoryRequests(grain.Items) + err = inventoryService.ReserveInventory(inventoryRequests...) + if err != nil { + logger.WarnContext(r.Context(), "placeorder inventory reservation failed") + w.WriteHeader(http.StatusNotAcceptable) + return + } w.WriteHeader(http.StatusOK) }) diff --git a/cmd/cart/main.go b/cmd/cart/main.go index 8b8f38b..66da5b7 100644 --- a/cmd/cart/main.go +++ b/cmd/cart/main.go @@ -147,7 +147,7 @@ func main() { if amqpUrl == "" { log.Printf("no connection to amqp defined") } else { - app.HandleCheckoutRequests(amqpUrl, mux) + app.HandleCheckoutRequests(amqpUrl, mux, inventoryService) } grpcSrv, err := actor.NewControlServer[*cart.CartGrain](controlPlaneConfig, pool) From cc6d48c879928149331347b2c80ce4328577c948 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 13:32:31 +0100 Subject: [PATCH 10/18] update urls --- cmd/cart/checkout_server.go | 15 ++++++++------- cmd/cart/pool-server.go | 22 +++++++++++++--------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/cmd/cart/checkout_server.go b/cmd/cart/checkout_server.go index 9cdb49f..4085a7c 100644 --- a/cmd/cart/checkout_server.go +++ b/cmd/cart/checkout_server.go @@ -140,13 +140,14 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, invento w.WriteHeader(http.StatusInternalServerError) return } - - inventoryRequests := getInventoryRequests(grain.Items) - err = inventoryService.ReserveInventory(inventoryRequests...) - if err != nil { - logger.WarnContext(r.Context(), "placeorder inventory reservation failed") - w.WriteHeader(http.StatusNotAcceptable) - return + if inventoryService != nil { + inventoryRequests := getInventoryRequests(grain.Items) + err = inventoryService.ReserveInventory(inventoryRequests...) + if err != nil { + logger.WarnContext(r.Context(), "placeorder inventory reservation failed") + w.WriteHeader(http.StatusNotAcceptable) + return + } } w.WriteHeader(http.StatusOK) diff --git a/cmd/cart/pool-server.go b/cmd/cart/pool-server.go index 436ce66..8b344d8 100644 --- a/cmd/cart/pool-server.go +++ b/cmd/cart/pool-server.go @@ -323,6 +323,9 @@ func getLocationId(item *cart.CartItem) inventory.LocationID { func getInventoryRequests(items []*cart.CartItem) []inventory.ReserveRequest { var requests []inventory.ReserveRequest for _, item := range items { + if item == nil { + continue + } requests = append(requests, inventory.ReserveRequest{ SKU: inventory.SKU(item.Sku), LocationID: getLocationId(item), @@ -338,8 +341,8 @@ func (s *PoolServer) CreateOrUpdateCheckout(ctx context.Context, host string, id Terms: fmt.Sprintf("https://%s/terms", host), Checkout: fmt.Sprintf("https://%s/checkout?order_id={checkout.order.id}", host), Confirmation: fmt.Sprintf("https://%s/confirmation/{checkout.order.id}", host), - Validation: fmt.Sprintf("https://%s/validate", host), - Push: fmt.Sprintf("https://%s/push?order_id={checkout.order.id}", host), + Validation: "https://cart.tornberg.me/validate", + Push: "https://cart.tornberg.me/push?order_id={checkout.order.id}", Country: country, Currency: getCurrency(country), Locale: getLocale(country), @@ -350,12 +353,13 @@ func (s *PoolServer) CreateOrUpdateCheckout(ctx context.Context, host string, id if err != nil { return nil, err } - - inventoryRequests := getInventoryRequests(grain.Items) - failingRequest, err := s.inventoryService.ReservationCheck(inventoryRequests...) - if err != nil { - logger.WarnContext(ctx, "inventory check failed", string(failingRequest.SKU), string(failingRequest.LocationID)) - return nil, err + if s.inventoryService != nil { + inventoryRequests := getInventoryRequests(grain.Items) + failingRequest, err := s.inventoryService.ReservationCheck(inventoryRequests...) + if err != nil { + logger.WarnContext(ctx, "inventory check failed", string(failingRequest.SKU), string(failingRequest.LocationID)) + return nil, err + } } // Build pure checkout payload @@ -581,7 +585,7 @@ func (s *PoolServer) CheckoutHandler(fn func(order *CheckoutOrder, w http.Respon if orderId == "" { order, err := s.CreateOrUpdateCheckout(r.Context(), r.Host, cartId) if err != nil { - logger.Error("unable to create klarna session", err) + logger.Error("unable to create klarna session: %v", err) return err } s.ApplyCheckoutStarted(order, cartId) From 7161c2a8b6355c474dfe6ffcdf201531892cb52c Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 16:00:59 +0100 Subject: [PATCH 11/18] Update amqp-order-handler.go --- cmd/cart/amqp-order-handler.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/cart/amqp-order-handler.go b/cmd/cart/amqp-order-handler.go index dddaac9..14e79e4 100644 --- a/cmd/cart/amqp-order-handler.go +++ b/cmd/cart/amqp-order-handler.go @@ -51,13 +51,14 @@ func (h *AmqpOrderHandler) OrderCompleted(body []byte) error { defer cancel() return ch.PublishWithContext(ctx, - "orders", // exchange - "new", // routing key + "", // exchange + "orders", // routing key false, // mandatory false, // immediate amqp.Publishing{ - ContentType: "application/json", - Body: body, + DeliveryMode: amqp.Persistent, + ContentType: "application/json", + Body: body, }) } From 5223fef2fa2a9a3c310e0359d6dad6f3fbdd3ae2 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 16:44:41 +0100 Subject: [PATCH 12/18] Update amqp-order-handler.go --- cmd/cart/amqp-order-handler.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cmd/cart/amqp-order-handler.go b/cmd/cart/amqp-order-handler.go index 14e79e4..972cbb9 100644 --- a/cmd/cart/amqp-order-handler.go +++ b/cmd/cart/amqp-order-handler.go @@ -9,7 +9,8 @@ import ( ) type AmqpOrderHandler struct { - conn *amqp.Connection + conn *amqp.Connection + queue *amqp.Queue } func NewAmqpOrderHandler(conn *amqp.Connection) *AmqpOrderHandler { @@ -25,19 +26,18 @@ func (h *AmqpOrderHandler) DefineTopics() error { } defer ch.Close() - err = ch.ExchangeDeclare( + queue, err := ch.QueueDeclare( "orders", // name - "direct", // type - true, // durable - false, // auto-deleted - false, // internal - false, // no-wait - nil, // arguments + false, + false, + false, + false, + nil, ) if err != nil { return fmt.Errorf("failed to declare an exchange: %w", err) } - + h.queue = &queue return nil } From 3f9c790dc2fbabf67fee275bbcb30bb4a4447a11 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 16:57:45 +0100 Subject: [PATCH 13/18] update again. with more logs --- cmd/cart/checkout_server.go | 7 ++++--- go.mod | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/cart/checkout_server.go b/cmd/cart/checkout_server.go index 4085a7c..3eac2a9 100644 --- a/cmd/cart/checkout_server.go +++ b/cmd/cart/checkout_server.go @@ -44,8 +44,8 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, invento orderHandler := NewAmqpOrderHandler(conn) orderHandler.DefineTopics() - mux.HandleFunc("POST /push", func(w http.ResponseWriter, r *http.Request) { - + mux.HandleFunc("/push", func(w http.ResponseWriter, r *http.Request) { + log.Printf("Klarna order confirmation push, method: %s", r.Method) if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return @@ -128,9 +128,10 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, invento if err != nil { w.WriteHeader(http.StatusBadRequest) } - log.Printf("Klarna order validation: %s", order.ID) + log.Printf("Klarna order validation: %s, cart id: %s", order.ID, order.MerchantReference1) cartId, ok := cart.ParseCartId(order.MerchantReference1) if !ok { + log.Printf("Invalid cart id in order reference: %s", order.MerchantReference1) w.WriteHeader(http.StatusBadRequest) return } diff --git a/go.mod b/go.mod index b884be2..92f53ef 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module git.tornberg.me/go-cart-actor go 1.25.3 require ( + git.tornberg.me/mats/go-redis-inventory v0.0.0-20251110193851-19d7ad0de6e5 github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.6.0 github.com/matst80/slask-finder v0.0.0-20251023104024-f788e5a51d68 @@ -29,7 +30,6 @@ require ( ) require ( - git.tornberg.me/mats/go-redis-inventory v0.0.0-20251110193851-19d7ad0de6e5 // indirect github.com/RoaringBitmap/roaring/v2 v2.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.24.1 // indirect From 529e70fc68fe379451084ed319a19b1165ef841c Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 17:01:57 +0100 Subject: [PATCH 14/18] more testing --- cmd/cart/checkout_builder.go | 2 +- pkg/cart/cart-grain.go | 15 ++++++++------- pkg/cart/mutation_add_item.go | 1 + 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cmd/cart/checkout_builder.go b/cmd/cart/checkout_builder.go index e4a152a..2d33703 100644 --- a/cmd/cart/checkout_builder.go +++ b/cmd/cart/checkout_builder.go @@ -69,7 +69,7 @@ func BuildCheckoutOrderPayload(grain *cart.CartGrain, meta *CheckoutMeta) ([]byt Name: it.Meta.Name, Quantity: it.Quantity, UnitPrice: int(it.Price.IncVat), - TaxRate: 2500, // TODO: derive if variable tax rates are introduced + TaxRate: it.Tax, // TODO: derive if variable tax rates are introduced QuantityUnit: "st", TotalAmount: int(it.TotalPrice.IncVat), TotalTaxAmount: int(it.TotalPrice.TotalVat()), diff --git a/pkg/cart/cart-grain.go b/pkg/cart/cart-grain.go index 937933b..d8a48bc 100644 --- a/pkg/cart/cart-grain.go +++ b/pkg/cart/cart-grain.go @@ -30,13 +30,14 @@ type ItemMeta struct { } type CartItem struct { - Id uint32 `json:"id"` - ItemId uint32 `json:"itemId,omitempty"` - ParentId *uint32 `json:"parentId,omitempty"` - Sku string `json:"sku"` - Price Price `json:"price"` - TotalPrice Price `json:"totalPrice"` - OrgPrice *Price `json:"orgPrice,omitempty"` + Id uint32 `json:"id"` + ItemId uint32 `json:"itemId,omitempty"` + ParentId *uint32 `json:"parentId,omitempty"` + Sku string `json:"sku"` + Price Price `json:"price"` + TotalPrice Price `json:"totalPrice"` + OrgPrice *Price `json:"orgPrice,omitempty"` + Tax int Stock StockStatus `json:"stock"` Quantity int `json:"qty"` Discount *Price `json:"discount,omitempty"` diff --git a/pkg/cart/mutation_add_item.go b/pkg/cart/mutation_add_item.go index 94d7a43..dd8cfc6 100644 --- a/pkg/cart/mutation_add_item.go +++ b/pkg/cart/mutation_add_item.go @@ -63,6 +63,7 @@ func AddItem(g *CartGrain, m *messages.AddItem) error { ItemId: uint32(m.ItemId), Quantity: int(m.Quantity), Sku: m.Sku, + Tax: int(taxRate * 100), Meta: &ItemMeta{ Name: m.Name, Image: m.Image, From a54435ebbb2475f5b90c41f40f04aa4cdc757420 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 17:20:29 +0100 Subject: [PATCH 15/18] test external ip --- deployment/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/deployment.yaml b/deployment/deployment.yaml index 264640d..bc399c8 100644 --- a/deployment/deployment.yaml +++ b/deployment/deployment.yaml @@ -178,7 +178,7 @@ spec: name: klarna-api-credentials key: username - name: REDIS_ADDRESS - value: "redis.home:6379" + value: "10.10.3.18:6379" - name: REDIS_PASSWORD value: "slaskredis" - name: OTEL_RESOURCE_ATTRIBUTES From 6d9f9bec1178aa0dac3fd0d3aa50cbbde707f33c Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 17:26:43 +0100 Subject: [PATCH 16/18] Update amqp-order-handler.go --- cmd/cart/amqp-order-handler.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/cart/amqp-order-handler.go b/cmd/cart/amqp-order-handler.go index 972cbb9..0552c3e 100644 --- a/cmd/cart/amqp-order-handler.go +++ b/cmd/cart/amqp-order-handler.go @@ -27,7 +27,7 @@ func (h *AmqpOrderHandler) DefineTopics() error { defer ch.Close() queue, err := ch.QueueDeclare( - "orders", // name + "order-queue", // name false, false, false, @@ -51,10 +51,10 @@ func (h *AmqpOrderHandler) OrderCompleted(body []byte) error { defer cancel() return ch.PublishWithContext(ctx, - "", // exchange - "orders", // routing key - false, // mandatory - false, // immediate + "", // exchange + h.queue.Name, // routing key + false, // mandatory + false, // immediate amqp.Publishing{ DeliveryMode: amqp.Persistent, ContentType: "application/json", From e0d8afae925e9ec011b679ce8b48788c72fbe924 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 17:27:05 +0100 Subject: [PATCH 17/18] change name --- cmd/cart/amqp-order-handler.go | 2 +- cmd/cart/checkout_server.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/cart/amqp-order-handler.go b/cmd/cart/amqp-order-handler.go index 0552c3e..7e2c274 100644 --- a/cmd/cart/amqp-order-handler.go +++ b/cmd/cart/amqp-order-handler.go @@ -19,7 +19,7 @@ func NewAmqpOrderHandler(conn *amqp.Connection) *AmqpOrderHandler { } } -func (h *AmqpOrderHandler) DefineTopics() error { +func (h *AmqpOrderHandler) DefineQueue() error { ch, err := h.conn.Channel() if err != nil { return fmt.Errorf("failed to open a channel: %w", err) diff --git a/cmd/cart/checkout_server.go b/cmd/cart/checkout_server.go index 3eac2a9..e44d251 100644 --- a/cmd/cart/checkout_server.go +++ b/cmd/cart/checkout_server.go @@ -42,7 +42,7 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, invento amqpListener.DefineTopics() a.pool.AddListener(amqpListener) orderHandler := NewAmqpOrderHandler(conn) - orderHandler.DefineTopics() + orderHandler.DefineQueue() mux.HandleFunc("/push", func(w http.ResponseWriter, r *http.Request) { log.Printf("Klarna order confirmation push, method: %s", r.Method) From 0c9780f36c0f9c305af2ed490aeb90d107d953f2 Mon Sep 17 00:00:00 2001 From: matst80 Date: Tue, 11 Nov 2025 17:47:49 +0100 Subject: [PATCH 18/18] Update amqp-order-handler.go --- cmd/cart/amqp-order-handler.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/cart/amqp-order-handler.go b/cmd/cart/amqp-order-handler.go index 7e2c274..674d249 100644 --- a/cmd/cart/amqp-order-handler.go +++ b/cmd/cart/amqp-order-handler.go @@ -56,9 +56,9 @@ func (h *AmqpOrderHandler) OrderCompleted(body []byte) error { false, // mandatory false, // immediate amqp.Publishing{ - DeliveryMode: amqp.Persistent, - ContentType: "application/json", - Body: body, + //DeliveryMode: amqp., + ContentType: "application/json", + Body: body, }) }