diff --git a/cmd/cart/main.go b/cmd/cart/main.go index 6400d78..6c3a1e7 100644 --- a/cmd/cart/main.go +++ b/cmd/cart/main.go @@ -16,6 +16,7 @@ import ( "git.tornberg.me/go-cart-actor/pkg/cart" "git.tornberg.me/go-cart-actor/pkg/discovery" messages "git.tornberg.me/go-cart-actor/pkg/messages" + "git.tornberg.me/go-cart-actor/pkg/promotions" "git.tornberg.me/go-cart-actor/pkg/proxy" "git.tornberg.me/go-cart-actor/pkg/voucher" "github.com/prometheus/client_golang/prometheus" @@ -108,7 +109,25 @@ func main() { controlPlaneConfig := actor.DefaultServerConfig() + promotionData, err := promotions.LoadStateFile("data/promotions.json") + if err != nil { + log.Printf("Error loading promotions: %v\n", err) + } + + promotionService := promotions.NewPromotionService(nil) + reg := cart.NewCartMultationRegistry() + reg.RegisterProcessor(actor.NewMutationProcessor(func(g *cart.CartGrain) error { + ctx := promotions.NewContextFromCart(g) + _, actions := promotionService.EvaluateAll(promotionData.State.Promotions, ctx) + for _, action := range actions { + log.Printf("apply: %V", action) + } + return nil + }), actor.NewMutationProcessor(func(g *cart.CartGrain) error { + g.UpdateTotals() + return nil + })) diskStorage := actor.NewDiskStorage[cart.CartGrain]("data", reg) poolConfig := actor.GrainPoolConfig[cart.CartGrain]{ MutationRegistry: reg, @@ -323,19 +342,7 @@ func main() { w.WriteHeader(http.StatusBadRequest) } log.Printf("Klarna order validation: %s", order.ID) - //err = confirmOrder(order, orderHandler) - //if err != nil { - // log.Printf("Error validating order: %v\n", err) - // w.WriteHeader(http.StatusInternalServerError) - // return - //} - // - //err = triggerOrderCompleted(err, syncedServer, order) - //if err != nil { - // log.Printf("Error processing cart message: %v\n", err) - // w.WriteHeader(http.StatusInternalServerError) - // return - //} + w.WriteHeader(http.StatusOK) }) diff --git a/pkg/actor/mutation_registry.go b/pkg/actor/mutation_registry.go index 72b7f91..ca7d774 100644 --- a/pkg/actor/mutation_registry.go +++ b/pkg/actor/mutation_registry.go @@ -15,11 +15,32 @@ type ApplyResult struct { Error error `json:"error,omitempty"` } +type MutationProcessor interface { + Process(grain any) error +} + +type BasicMutationProcessor[V any] struct { + processor func(any) error +} + +func NewMutationProcessor[V any](process func(V) error) MutationProcessor { + return &BasicMutationProcessor[V]{ + processor: func(v any) error { + return process(v.(V)) + }, + } +} + +func (p *BasicMutationProcessor[V]) Process(grain any) error { + return p.processor(grain) +} + type MutationRegistry interface { Apply(grain any, msg ...proto.Message) ([]ApplyResult, error) RegisterMutations(handlers ...MutationHandler) Create(typeName string) (proto.Message, bool) GetTypeName(msg proto.Message) (string, bool) + RegisterProcessor(processor ...MutationProcessor) //GetStorageEvent(msg proto.Message) StorageEvent //FromStorageEvent(event StorageEvent) (proto.Message, error) } @@ -27,6 +48,7 @@ type MutationRegistry interface { type ProtoMutationRegistry struct { mutationRegistryMu sync.RWMutex mutationRegistry map[reflect.Type]MutationHandler + processors []MutationProcessor } var ( @@ -114,9 +136,14 @@ func NewMutationRegistry() MutationRegistry { return &ProtoMutationRegistry{ mutationRegistry: make(map[reflect.Type]MutationHandler), mutationRegistryMu: sync.RWMutex{}, + processors: make([]MutationProcessor, 0), } } +func (r *ProtoMutationRegistry) RegisterProcessor(processors ...MutationProcessor) { + r.processors = append(r.processors, processors...) +} + func (r *ProtoMutationRegistry) RegisterMutations(handlers ...MutationHandler) { r.mutationRegistryMu.Lock() defer r.mutationRegistryMu.Unlock() @@ -198,6 +225,12 @@ func (r *ProtoMutationRegistry) Apply(grain any, msg ...proto.Message) ([]ApplyR results = append(results, ApplyResult{Error: err, Type: rt.Name(), Mutation: m}) } + for _, processor := range r.processors { + err := processor.Process(grain) + if err != nil { + return results, err + } + } return results, nil } diff --git a/pkg/promotions/types.go b/pkg/promotions/types.go index d23061e..17a684c 100644 --- a/pkg/promotions/types.go +++ b/pkg/promotions/types.go @@ -380,7 +380,7 @@ func WalkConditions(conds []Condition, fn func(c Condition) bool) { } type PromotionState struct { - Vouchers []PromotionRule `json:"promotions"` + Promotions []PromotionRule `json:"promotions"` } type StateFile struct { @@ -389,7 +389,7 @@ type StateFile struct { } func (sf *StateFile) GetPromotion(id string) (*PromotionRule, bool) { - for _, v := range sf.State.Vouchers { + for _, v := range sf.State.Promotions { if v.ID == id { return &v, true } @@ -397,14 +397,14 @@ func (sf *StateFile) GetPromotion(id string) (*PromotionRule, bool) { return nil, false } -func LoadStateFile(fileName string) (*PromotionState, error) { +func LoadStateFile(fileName string) (*StateFile, error) { f, err := os.Open(fileName) if err != nil { return nil, err } defer f.Close() dec := json.NewDecoder(f) - sf := &PromotionState{} + sf := &StateFile{} err = dec.Decode(sf) if err != nil { return nil, err