Complete refactor to new grpc control plane and only http proxy for carts #4

Merged
mats merged 75 commits from refactor/http-proxy into main 2025-10-14 22:31:28 +02:00
7 changed files with 152 additions and 18 deletions
Showing only changes of commit 6c44a03dd1 - Show all commits

View File

@@ -8,6 +8,7 @@ import (
"time"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
"git.tornberg.me/go-cart-actor/pkg/voucher"
)
// Legacy padded [16]byte CartId and its helper methods removed.
@@ -63,17 +64,18 @@ type CartGrain struct {
lastItemId int
lastDeliveryId int
lastAccess time.Time
lastChange time.Time // unix seconds of last successful mutation (replay sets from event ts)
Id CartId `json:"id"`
Items []*CartItem `json:"items"`
TotalPrice int64 `json:"totalPrice"`
TotalTax int64 `json:"totalTax"`
TotalDiscount int64 `json:"totalDiscount"`
Deliveries []*CartDelivery `json:"deliveries,omitempty"`
Processing bool `json:"processing"`
PaymentInProgress bool `json:"paymentInProgress"`
OrderReference string `json:"orderReference,omitempty"`
PaymentStatus string `json:"paymentStatus,omitempty"`
lastChange time.Time // unix seconds of last successful mutation (replay sets from event ts)
Id CartId `json:"id"`
Items []*CartItem `json:"items"`
TotalPrice int64 `json:"totalPrice"`
TotalTax int64 `json:"totalTax"`
TotalDiscount int64 `json:"totalDiscount"`
Deliveries []*CartDelivery `json:"deliveries,omitempty"`
Processing bool `json:"processing"`
PaymentInProgress bool `json:"paymentInProgress"`
OrderReference string `json:"orderReference,omitempty"`
PaymentStatus string `json:"paymentStatus,omitempty"`
Vouchers []*voucher.Voucher `json:"vouchers,omitempty"`
}
func (c *CartGrain) GetId() uint64 {

View File

@@ -16,6 +16,7 @@ import (
"git.tornberg.me/go-cart-actor/pkg/discovery"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
"git.tornberg.me/go-cart-actor/pkg/proxy"
"git.tornberg.me/go-cart-actor/pkg/voucher"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -92,10 +93,14 @@ func GetDiscovery() discovery.Discovery {
return discovery.NewK8sDiscovery(client)
}
type MutationContext struct {
VoucherService voucher.Service
}
func main() {
controlPlaneConfig := actor.DefaultServerConfig()
ctx := MutationContext{}
reg := actor.NewMutationRegistry()
reg.RegisterMutations(
actor.NewMutation(AddItem, func() *messages.AddItem {
@@ -125,6 +130,9 @@ func main() {
actor.NewMutation(ClearCart, func() *messages.ClearCartRequest {
return &messages.ClearCartRequest{}
}),
actor.NewMutation(ctx.AddVoucher, func() *messages.AddVoucher {
return &messages.AddVoucher{}
}),
)
diskStorage := actor.NewDiskStorage[CartGrain]("data", reg)
poolConfig := actor.GrainPoolConfig[CartGrain]{

View File

@@ -0,0 +1,26 @@
package main
import (
"fmt"
"git.tornberg.me/go-cart-actor/pkg/messages"
)
func (ctx *MutationContext) AddVoucher(g *CartGrain, m *messages.AddVoucher) error {
if m == nil {
return fmt.Errorf("AddVoucher: nil payload")
}
voucher, err := ctx.VoucherService.GetVoucher(m.Code)
if err != nil {
return fmt.Errorf("AddVoucher: %w", err)
}
if voucher == nil {
return nil
}
g.Vouchers = append(g.Vouchers, voucher)
g.UpdateTotals()
return nil
}

View File

@@ -437,6 +437,19 @@ func (s *PoolServer) ProxyHandler(fn func(w http.ResponseWriter, r *http.Request
}
}
func (s *PoolServer) AddVoucherHandler(w http.ResponseWriter, r *http.Request, cartId CartId) error {
msg := &messages.AddVoucher{}
json.NewDecoder(r.Body).Decode(msg)
reply, err := s.Apply(uint64(cartId), msg)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return err
}
s.WriteResult(w, reply)
return nil
}
func (s *PoolServer) Serve() *http.ServeMux {
mux := http.NewServeMux()
@@ -458,6 +471,8 @@ func (s *PoolServer) Serve() *http.ServeMux {
mux.HandleFunc("POST /delivery", CookieCartIdHandler(s.ProxyHandler(s.SetDeliveryHandler)))
mux.HandleFunc("DELETE /delivery/{deliveryId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveDeliveryHandler)))
mux.HandleFunc("PUT /delivery/{deliveryId}/pickupPoint", CookieCartIdHandler(s.ProxyHandler(s.SetPickupPointHandler)))
mux.HandleFunc("PUT /voucher", CookieCartIdHandler(s.ProxyHandler(s.AddVoucherHandler)))
//mux.HandleFunc("GET /checkout", CookieCartIdHandler(s.ProxyHandler(s.HandleCheckout)))
//mux.HandleFunc("GET /confirmation/{orderId}", CookieCartIdHandler(s.ProxyHandler(s.HandleConfirmation)))

View File

@@ -977,6 +977,50 @@ func (x *InitializeCheckout) GetPaymentInProgress() bool {
return false
}
type AddVoucher struct {
state protoimpl.MessageState `protogen:"open.v1"`
Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AddVoucher) Reset() {
*x = AddVoucher{}
mi := &file_messages_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AddVoucher) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AddVoucher) ProtoMessage() {}
func (x *AddVoucher) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AddVoucher.ProtoReflect.Descriptor instead.
func (*AddVoucher) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{13}
}
func (x *AddVoucher) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
var File_messages_proto protoreflect.FileDescriptor
var file_messages_proto_rawDesc = string([]byte{
@@ -1107,10 +1151,12 @@ var file_messages_proto_rawDesc = string([]byte{
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x11, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72,
0x65, 0x73, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x74, 0x6f, 0x72, 0x6e, 0x62,
0x65, 0x72, 0x67, 0x2e, 0x6d, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x2d, 0x61,
0x63, 0x74, 0x6f, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x73, 0x73, 0x22, 0x20, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65,
0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x74, 0x6f, 0x72,
0x6e, 0x62, 0x65, 0x72, 0x67, 0x2e, 0x6d, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x61, 0x72, 0x74,
0x2d, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var (
@@ -1125,7 +1171,7 @@ func file_messages_proto_rawDescGZIP() []byte {
return file_messages_proto_rawDescData
}
var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
var file_messages_proto_goTypes = []any{
(*AddRequest)(nil), // 0: messages.AddRequest
(*ClearCartRequest)(nil), // 1: messages.ClearCartRequest
@@ -1140,6 +1186,7 @@ var file_messages_proto_goTypes = []any{
(*OrderCreated)(nil), // 10: messages.OrderCreated
(*Noop)(nil), // 11: messages.Noop
(*InitializeCheckout)(nil), // 12: messages.InitializeCheckout
(*AddVoucher)(nil), // 13: messages.AddVoucher
}
var file_messages_proto_depIdxs = []int32{
7, // 0: messages.SetDelivery.pickupPoint:type_name -> messages.PickupPoint
@@ -1166,7 +1213,7 @@ func file_messages_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)),
NumEnums: 0,
NumMessages: 13,
NumMessages: 14,
NumExtensions: 0,
NumServices: 0,
},

32
pkg/voucher/service.go Normal file
View File

@@ -0,0 +1,32 @@
package voucher
import "math"
type Rule struct {
Type string `json:"type"`
Value int64 `json:"value"`
}
type Voucher struct {
Code string `json:"code"`
Value int64 `json:"discount"`
TaxValue int64 `json:"taxValue"`
TaxRate int `json:"taxRate"`
rules []Rule `json:"rules"`
}
type Service struct {
// Add fields here
}
func (s *Service) GetVoucher(code string) (*Voucher, error) {
value := int64(math.Round(100 * math.Pow(10, 2)))
return &Voucher{
Code: code,
Value: value,
TaxValue: int64(float64(value) * 0.2),
TaxRate: 2500,
rules: nil,
}, nil
}

View File

@@ -103,3 +103,7 @@ message InitializeCheckout {
string status = 2;
bool paymentInProgress = 3;
}
message AddVoucher {
string code = 1;
}