Complete refactor to new grpc control plane and only http proxy for carts #4
@@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
messages "git.tornberg.me/go-cart-actor/pkg/messages"
|
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.
|
// Legacy padded [16]byte CartId and its helper methods removed.
|
||||||
@@ -63,17 +64,18 @@ type CartGrain struct {
|
|||||||
lastItemId int
|
lastItemId int
|
||||||
lastDeliveryId int
|
lastDeliveryId int
|
||||||
lastAccess time.Time
|
lastAccess time.Time
|
||||||
lastChange time.Time // unix seconds of last successful mutation (replay sets from event ts)
|
lastChange time.Time // unix seconds of last successful mutation (replay sets from event ts)
|
||||||
Id CartId `json:"id"`
|
Id CartId `json:"id"`
|
||||||
Items []*CartItem `json:"items"`
|
Items []*CartItem `json:"items"`
|
||||||
TotalPrice int64 `json:"totalPrice"`
|
TotalPrice int64 `json:"totalPrice"`
|
||||||
TotalTax int64 `json:"totalTax"`
|
TotalTax int64 `json:"totalTax"`
|
||||||
TotalDiscount int64 `json:"totalDiscount"`
|
TotalDiscount int64 `json:"totalDiscount"`
|
||||||
Deliveries []*CartDelivery `json:"deliveries,omitempty"`
|
Deliveries []*CartDelivery `json:"deliveries,omitempty"`
|
||||||
Processing bool `json:"processing"`
|
Processing bool `json:"processing"`
|
||||||
PaymentInProgress bool `json:"paymentInProgress"`
|
PaymentInProgress bool `json:"paymentInProgress"`
|
||||||
OrderReference string `json:"orderReference,omitempty"`
|
OrderReference string `json:"orderReference,omitempty"`
|
||||||
PaymentStatus string `json:"paymentStatus,omitempty"`
|
PaymentStatus string `json:"paymentStatus,omitempty"`
|
||||||
|
Vouchers []*voucher.Voucher `json:"vouchers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CartGrain) GetId() uint64 {
|
func (c *CartGrain) GetId() uint64 {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"git.tornberg.me/go-cart-actor/pkg/discovery"
|
"git.tornberg.me/go-cart-actor/pkg/discovery"
|
||||||
messages "git.tornberg.me/go-cart-actor/pkg/messages"
|
messages "git.tornberg.me/go-cart-actor/pkg/messages"
|
||||||
"git.tornberg.me/go-cart-actor/pkg/proxy"
|
"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"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
@@ -92,10 +93,14 @@ func GetDiscovery() discovery.Discovery {
|
|||||||
return discovery.NewK8sDiscovery(client)
|
return discovery.NewK8sDiscovery(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MutationContext struct {
|
||||||
|
VoucherService voucher.Service
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
controlPlaneConfig := actor.DefaultServerConfig()
|
controlPlaneConfig := actor.DefaultServerConfig()
|
||||||
|
ctx := MutationContext{}
|
||||||
reg := actor.NewMutationRegistry()
|
reg := actor.NewMutationRegistry()
|
||||||
reg.RegisterMutations(
|
reg.RegisterMutations(
|
||||||
actor.NewMutation(AddItem, func() *messages.AddItem {
|
actor.NewMutation(AddItem, func() *messages.AddItem {
|
||||||
@@ -125,6 +130,9 @@ func main() {
|
|||||||
actor.NewMutation(ClearCart, func() *messages.ClearCartRequest {
|
actor.NewMutation(ClearCart, func() *messages.ClearCartRequest {
|
||||||
return &messages.ClearCartRequest{}
|
return &messages.ClearCartRequest{}
|
||||||
}),
|
}),
|
||||||
|
actor.NewMutation(ctx.AddVoucher, func() *messages.AddVoucher {
|
||||||
|
return &messages.AddVoucher{}
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
diskStorage := actor.NewDiskStorage[CartGrain]("data", reg)
|
diskStorage := actor.NewDiskStorage[CartGrain]("data", reg)
|
||||||
poolConfig := actor.GrainPoolConfig[CartGrain]{
|
poolConfig := actor.GrainPoolConfig[CartGrain]{
|
||||||
|
|||||||
26
cmd/cart/mutation_add_voucher.go
Normal file
26
cmd/cart/mutation_add_voucher.go
Normal 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
|
||||||
|
}
|
||||||
@@ -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 {
|
func (s *PoolServer) Serve() *http.ServeMux {
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
@@ -458,6 +471,8 @@ func (s *PoolServer) Serve() *http.ServeMux {
|
|||||||
mux.HandleFunc("POST /delivery", CookieCartIdHandler(s.ProxyHandler(s.SetDeliveryHandler)))
|
mux.HandleFunc("POST /delivery", CookieCartIdHandler(s.ProxyHandler(s.SetDeliveryHandler)))
|
||||||
mux.HandleFunc("DELETE /delivery/{deliveryId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveDeliveryHandler)))
|
mux.HandleFunc("DELETE /delivery/{deliveryId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveDeliveryHandler)))
|
||||||
mux.HandleFunc("PUT /delivery/{deliveryId}/pickupPoint", CookieCartIdHandler(s.ProxyHandler(s.SetPickupPointHandler)))
|
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 /checkout", CookieCartIdHandler(s.ProxyHandler(s.HandleCheckout)))
|
||||||
//mux.HandleFunc("GET /confirmation/{orderId}", CookieCartIdHandler(s.ProxyHandler(s.HandleConfirmation)))
|
//mux.HandleFunc("GET /confirmation/{orderId}", CookieCartIdHandler(s.ProxyHandler(s.HandleConfirmation)))
|
||||||
|
|
||||||
|
|||||||
@@ -977,6 +977,50 @@ func (x *InitializeCheckout) GetPaymentInProgress() bool {
|
|||||||
return false
|
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 protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_messages_proto_rawDesc = string([]byte{
|
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,
|
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,
|
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,
|
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, 0x73, 0x73, 0x22, 0x20, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65,
|
||||||
0x65, 0x72, 0x67, 0x2e, 0x6d, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x2d, 0x61,
|
0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
0x63, 0x74, 0x6f, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x74, 0x6f, 0x72,
|
||||||
0x67, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
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 (
|
var (
|
||||||
@@ -1125,7 +1171,7 @@ func file_messages_proto_rawDescGZIP() []byte {
|
|||||||
return file_messages_proto_rawDescData
|
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{
|
var file_messages_proto_goTypes = []any{
|
||||||
(*AddRequest)(nil), // 0: messages.AddRequest
|
(*AddRequest)(nil), // 0: messages.AddRequest
|
||||||
(*ClearCartRequest)(nil), // 1: messages.ClearCartRequest
|
(*ClearCartRequest)(nil), // 1: messages.ClearCartRequest
|
||||||
@@ -1140,6 +1186,7 @@ var file_messages_proto_goTypes = []any{
|
|||||||
(*OrderCreated)(nil), // 10: messages.OrderCreated
|
(*OrderCreated)(nil), // 10: messages.OrderCreated
|
||||||
(*Noop)(nil), // 11: messages.Noop
|
(*Noop)(nil), // 11: messages.Noop
|
||||||
(*InitializeCheckout)(nil), // 12: messages.InitializeCheckout
|
(*InitializeCheckout)(nil), // 12: messages.InitializeCheckout
|
||||||
|
(*AddVoucher)(nil), // 13: messages.AddVoucher
|
||||||
}
|
}
|
||||||
var file_messages_proto_depIdxs = []int32{
|
var file_messages_proto_depIdxs = []int32{
|
||||||
7, // 0: messages.SetDelivery.pickupPoint:type_name -> messages.PickupPoint
|
7, // 0: messages.SetDelivery.pickupPoint:type_name -> messages.PickupPoint
|
||||||
@@ -1166,7 +1213,7 @@ func file_messages_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)),
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 13,
|
NumMessages: 14,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
|||||||
32
pkg/voucher/service.go
Normal file
32
pkg/voucher/service.go
Normal 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
|
||||||
|
}
|
||||||
@@ -103,3 +103,7 @@ message InitializeCheckout {
|
|||||||
string status = 2;
|
string status = 2;
|
||||||
bool paymentInProgress = 3;
|
bool paymentInProgress = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message AddVoucher {
|
||||||
|
string code = 1;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user