diff --git a/go.work b/go.work index dcea92909512d2a9c9a27bf8ce438202182d95c5..388e4b05be1b931421e176194ac7fb199dc6c4c9 100644 --- a/go.work +++ b/go.work @@ -2,3 +2,4 @@ go 1.24.2 use ./src/myaktion use ./src/genjwt +use ./src/banktransfer \ No newline at end of file diff --git a/go.work.sum b/go.work.sum index 92ca04a7bf6c91850e4e86b2789838e771b99f42..5e0a558945871e3223f6c8f78549b1b5364c53ac 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,3 +1,36 @@ +cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8= diff --git a/src/banktransfer/go.mod b/src/banktransfer/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..a57e52d1ed4a9b290b7ba9a7f325acad7c9e6f31 --- /dev/null +++ b/src/banktransfer/go.mod @@ -0,0 +1,12 @@ +module gitlab.reutlingen-university.de/petrinov/myaktion-go/src/banktransfer + +go 1.24.2 + +require ( + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect + google.golang.org/grpc v1.73.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/src/banktransfer/go.sum b/src/banktransfer/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..e1c22a4792060083d83edad588ad609e35cec1b2 --- /dev/null +++ b/src/banktransfer/go.sum @@ -0,0 +1,12 @@ +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= diff --git a/src/banktransfer/grpc/banktransfer/banktransfer.pb.go b/src/banktransfer/grpc/banktransfer/banktransfer.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..f154457f949361bc0370bf56c0b39815666edca8 --- /dev/null +++ b/src/banktransfer/grpc/banktransfer/banktransfer.pb.go @@ -0,0 +1,292 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v6.31.1 +// source: banktransfer.proto + +package banktransfer + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Account struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + BankName string `protobuf:"bytes,2,opt,name=bank_name,json=bankName,proto3" json:"bank_name,omitempty"` + Number string `protobuf:"bytes,3,opt,name=number,proto3" json:"number,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Account) Reset() { + *x = Account{} + mi := &file_banktransfer_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Account) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Account) ProtoMessage() {} + +func (x *Account) ProtoReflect() protoreflect.Message { + mi := &file_banktransfer_proto_msgTypes[0] + 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 Account.ProtoReflect.Descriptor instead. +func (*Account) Descriptor() ([]byte, []int) { + return file_banktransfer_proto_rawDescGZIP(), []int{0} +} + +func (x *Account) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Account) GetBankName() string { + if x != nil { + return x.BankName + } + return "" +} + +func (x *Account) GetNumber() string { + if x != nil { + return x.Number + } + return "" +} + +type Transaction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + DonationId int32 `protobuf:"varint,2,opt,name=donation_id,json=donationId,proto3" json:"donation_id,omitempty"` + Amount float32 `protobuf:"fixed32,3,opt,name=amount,proto3" json:"amount,omitempty"` + Reference string `protobuf:"bytes,4,opt,name=reference,proto3" json:"reference,omitempty"` + FromAccount *Account `protobuf:"bytes,5,opt,name=from_account,json=fromAccount,proto3" json:"from_account,omitempty"` + ToAccount *Account `protobuf:"bytes,6,opt,name=to_account,json=toAccount,proto3" json:"to_account,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Transaction) Reset() { + *x = Transaction{} + mi := &file_banktransfer_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Transaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Transaction) ProtoMessage() {} + +func (x *Transaction) ProtoReflect() protoreflect.Message { + mi := &file_banktransfer_proto_msgTypes[1] + 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 Transaction.ProtoReflect.Descriptor instead. +func (*Transaction) Descriptor() ([]byte, []int) { + return file_banktransfer_proto_rawDescGZIP(), []int{1} +} + +func (x *Transaction) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Transaction) GetDonationId() int32 { + if x != nil { + return x.DonationId + } + return 0 +} + +func (x *Transaction) GetAmount() float32 { + if x != nil { + return x.Amount + } + return 0 +} + +func (x *Transaction) GetReference() string { + if x != nil { + return x.Reference + } + return "" +} + +func (x *Transaction) GetFromAccount() *Account { + if x != nil { + return x.FromAccount + } + return nil +} + +func (x *Transaction) GetToAccount() *Account { + if x != nil { + return x.ToAccount + } + return nil +} + +type ProcessingResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProcessingResponse) Reset() { + *x = ProcessingResponse{} + mi := &file_banktransfer_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProcessingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessingResponse) ProtoMessage() {} + +func (x *ProcessingResponse) ProtoReflect() protoreflect.Message { + mi := &file_banktransfer_proto_msgTypes[2] + 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 ProcessingResponse.ProtoReflect.Descriptor instead. +func (*ProcessingResponse) Descriptor() ([]byte, []int) { + return file_banktransfer_proto_rawDescGZIP(), []int{2} +} + +func (x *ProcessingResponse) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +var File_banktransfer_proto protoreflect.FileDescriptor + +const file_banktransfer_proto_rawDesc = "" + + "\n" + + "\x12banktransfer.proto\x12\fbanktransfer\x1a\x1bgoogle/protobuf/empty.proto\"R\n" + + "\aAccount\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1b\n" + + "\tbank_name\x18\x02 \x01(\tR\bbankName\x12\x16\n" + + "\x06number\x18\x03 \x01(\tR\x06number\"\xe4\x01\n" + + "\vTransaction\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x05R\x02id\x12\x1f\n" + + "\vdonation_id\x18\x02 \x01(\x05R\n" + + "donationId\x12\x16\n" + + "\x06amount\x18\x03 \x01(\x02R\x06amount\x12\x1c\n" + + "\treference\x18\x04 \x01(\tR\treference\x128\n" + + "\ffrom_account\x18\x05 \x01(\v2\x15.banktransfer.AccountR\vfromAccount\x124\n" + + "\n" + + "to_account\x18\x06 \x01(\v2\x15.banktransfer.AccountR\ttoAccount\"$\n" + + "\x12ProcessingResponse\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x05R\x02id2\xae\x01\n" + + "\fBankTransfer\x12D\n" + + "\rTransferMoney\x12\x19.banktransfer.Transaction\x1a\x16.google.protobuf.Empty\"\x00\x12X\n" + + "\x13ProcessTransactions\x12 .banktransfer.ProcessingResponse\x1a\x19.banktransfer.Transaction\"\x00(\x010\x01BDZBgithub.com/turngeek/myaktion-go/src/banktransfer/grpc/banktransferb\x06proto3" + +var ( + file_banktransfer_proto_rawDescOnce sync.Once + file_banktransfer_proto_rawDescData []byte +) + +func file_banktransfer_proto_rawDescGZIP() []byte { + file_banktransfer_proto_rawDescOnce.Do(func() { + file_banktransfer_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_banktransfer_proto_rawDesc), len(file_banktransfer_proto_rawDesc))) + }) + return file_banktransfer_proto_rawDescData +} + +var file_banktransfer_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_banktransfer_proto_goTypes = []any{ + (*Account)(nil), // 0: banktransfer.Account + (*Transaction)(nil), // 1: banktransfer.Transaction + (*ProcessingResponse)(nil), // 2: banktransfer.ProcessingResponse + (*emptypb.Empty)(nil), // 3: google.protobuf.Empty +} +var file_banktransfer_proto_depIdxs = []int32{ + 0, // 0: banktransfer.Transaction.from_account:type_name -> banktransfer.Account + 0, // 1: banktransfer.Transaction.to_account:type_name -> banktransfer.Account + 1, // 2: banktransfer.BankTransfer.TransferMoney:input_type -> banktransfer.Transaction + 2, // 3: banktransfer.BankTransfer.ProcessTransactions:input_type -> banktransfer.ProcessingResponse + 3, // 4: banktransfer.BankTransfer.TransferMoney:output_type -> google.protobuf.Empty + 1, // 5: banktransfer.BankTransfer.ProcessTransactions:output_type -> banktransfer.Transaction + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_banktransfer_proto_init() } +func file_banktransfer_proto_init() { + if File_banktransfer_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_banktransfer_proto_rawDesc), len(file_banktransfer_proto_rawDesc)), + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_banktransfer_proto_goTypes, + DependencyIndexes: file_banktransfer_proto_depIdxs, + MessageInfos: file_banktransfer_proto_msgTypes, + }.Build() + File_banktransfer_proto = out.File + file_banktransfer_proto_goTypes = nil + file_banktransfer_proto_depIdxs = nil +} diff --git a/src/banktransfer/grpc/banktransfer/banktransfer.proto b/src/banktransfer/grpc/banktransfer/banktransfer.proto new file mode 100644 index 0000000000000000000000000000000000000000..a42a7e1e1e07e0e9359ea3f8adf02570955e2bc8 --- /dev/null +++ b/src/banktransfer/grpc/banktransfer/banktransfer.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package banktransfer; + +import "google/protobuf/empty.proto"; + +option go_package = "github.com/turngeek/myaktion-go/src/banktransfer/grpc/banktransfer"; + +service BankTransfer { +rpc TransferMoney (Transaction) returns (google.protobuf.Empty) {} +rpc ProcessTransactions (stream ProcessingResponse) returns (stream Transaction) {} +} + +message Account { +string name = 1; +string bank_name =2; +string number = 3; +} + +message Transaction { +int32 id = 1; +int32 donation_id = 2; +float amount = 3; +string reference = 4; +Account from_account = 5; +Account to_account = 6; +} + +message ProcessingResponse { +int32 id = 1; +} \ No newline at end of file diff --git a/src/banktransfer/grpc/banktransfer/banktransfer_grpc.pb.go b/src/banktransfer/grpc/banktransfer/banktransfer_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..96b53c359ad8782a9cabed6a44c096324cdbabed --- /dev/null +++ b/src/banktransfer/grpc/banktransfer/banktransfer_grpc.pb.go @@ -0,0 +1,155 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.1 +// source: banktransfer.proto + +package banktransfer + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + BankTransfer_TransferMoney_FullMethodName = "/banktransfer.BankTransfer/TransferMoney" + BankTransfer_ProcessTransactions_FullMethodName = "/banktransfer.BankTransfer/ProcessTransactions" +) + +// BankTransferClient is the client API for BankTransfer service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type BankTransferClient interface { + TransferMoney(ctx context.Context, in *Transaction, opts ...grpc.CallOption) (*emptypb.Empty, error) + ProcessTransactions(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ProcessingResponse, Transaction], error) +} + +type bankTransferClient struct { + cc grpc.ClientConnInterface +} + +func NewBankTransferClient(cc grpc.ClientConnInterface) BankTransferClient { + return &bankTransferClient{cc} +} + +func (c *bankTransferClient) TransferMoney(ctx context.Context, in *Transaction, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, BankTransfer_TransferMoney_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bankTransferClient) ProcessTransactions(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ProcessingResponse, Transaction], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &BankTransfer_ServiceDesc.Streams[0], BankTransfer_ProcessTransactions_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[ProcessingResponse, Transaction]{ClientStream: stream} + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type BankTransfer_ProcessTransactionsClient = grpc.BidiStreamingClient[ProcessingResponse, Transaction] + +// BankTransferServer is the server API for BankTransfer service. +// All implementations must embed UnimplementedBankTransferServer +// for forward compatibility. +type BankTransferServer interface { + TransferMoney(context.Context, *Transaction) (*emptypb.Empty, error) + ProcessTransactions(grpc.BidiStreamingServer[ProcessingResponse, Transaction]) error + mustEmbedUnimplementedBankTransferServer() +} + +// UnimplementedBankTransferServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedBankTransferServer struct{} + +func (UnimplementedBankTransferServer) TransferMoney(context.Context, *Transaction) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method TransferMoney not implemented") +} +func (UnimplementedBankTransferServer) ProcessTransactions(grpc.BidiStreamingServer[ProcessingResponse, Transaction]) error { + return status.Errorf(codes.Unimplemented, "method ProcessTransactions not implemented") +} +func (UnimplementedBankTransferServer) mustEmbedUnimplementedBankTransferServer() {} +func (UnimplementedBankTransferServer) testEmbeddedByValue() {} + +// UnsafeBankTransferServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to BankTransferServer will +// result in compilation errors. +type UnsafeBankTransferServer interface { + mustEmbedUnimplementedBankTransferServer() +} + +func RegisterBankTransferServer(s grpc.ServiceRegistrar, srv BankTransferServer) { + // If the following call pancis, it indicates UnimplementedBankTransferServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&BankTransfer_ServiceDesc, srv) +} + +func _BankTransfer_TransferMoney_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Transaction) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BankTransferServer).TransferMoney(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: BankTransfer_TransferMoney_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BankTransferServer).TransferMoney(ctx, req.(*Transaction)) + } + return interceptor(ctx, in, info, handler) +} + +func _BankTransfer_ProcessTransactions_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(BankTransferServer).ProcessTransactions(&grpc.GenericServerStream[ProcessingResponse, Transaction]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type BankTransfer_ProcessTransactionsServer = grpc.BidiStreamingServer[ProcessingResponse, Transaction] + +// BankTransfer_ServiceDesc is the grpc.ServiceDesc for BankTransfer service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var BankTransfer_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "banktransfer.BankTransfer", + HandlerType: (*BankTransferServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "TransferMoney", + Handler: _BankTransfer_TransferMoney_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "ProcessTransactions", + Handler: _BankTransfer_ProcessTransactions_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "banktransfer.proto", +} diff --git a/src/banktransfer/grpc/banktransfer/gen.go b/src/banktransfer/grpc/banktransfer/gen.go new file mode 100644 index 0000000000000000000000000000000000000000..12461a64cdc2cc0c8e9c79be0d30c245f20722bd --- /dev/null +++ b/src/banktransfer/grpc/banktransfer/gen.go @@ -0,0 +1,3 @@ +package grpc + +//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative banktransfer.proto diff --git a/src/banktransfer/main.go b/src/banktransfer/main.go new file mode 100644 index 0000000000000000000000000000000000000000..eb221de37657970a408e689e790290ba57a3e806 --- /dev/null +++ b/src/banktransfer/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "net" + "os" + + log "github.com/sirupsen/logrus" + "gitlab.reutlingen-university.de/petrinov/myaktion-go/src/banktransfer/grpc/banktransfer" + "google.golang.org/grpc" +) + +func init() { + log.SetFormatter(&log.TextFormatter{}) + log.SetReportCaller(true) + level, err := log.ParseLevel(os.Getenv("LOG_LEVEL")) + if err != nil { + log.Info("Log level not specified , set default to: INFO") + log.SetLevel(log.InfoLevel) + return + } + log.SetLevel(level) +} + +var grpcPort = 9111 + +func main() { + log.Info("Starting Banktransfer server") + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort)) + if err != nil { + log.Fatalf("failed to listen on grpc port %d: %v", grpcPort, err) + } + grpcServer := grpc.NewServer() + banktransfer.RegisterBankTransferServer(grpcServer, service.NewBankTransferService()) + if err := grpcServer.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} diff --git a/src/banktransfer/service/banktransfer.go b/src/banktransfer/service/banktransfer.go new file mode 100644 index 0000000000000000000000000000000000000000..64e262bae85d36f34d71211cb8109db6afd8a1a9 --- /dev/null +++ b/src/banktransfer/service/banktransfer.go @@ -0,0 +1,54 @@ +package banktransfer + +type BankTransferService struct { + banktransfer.BankTransferServer + counter int32 +} +func NewBankTransferService() * BankTransferService { + return &BankTransferService { + counter: 1, + } +} +func(s * BankTransferService) TransferMoney(_ context.Context, transaction * banktransfer.Transaction)( * emptypb.Empty, error) { + log.Infof("Received transaction: %v", transaction) + return &emptypb.Empty {}, nil +} + +func(s * BankTransferService) ProcessTransactions(stream banktransfer.BankTransfer_ProcessTransactionsServer) error { + ticker := time.NewTicker(2 * time.Second) + defer ticker.Stop() + return func() error { + for { + select { + case <-stream.Context().Done(): + log.Info("Watching transactions cancelled from the client side") + return nil + case <-ticker.C: + transaction: = & banktransfer.Transaction { + Id: s.counter, + Amount: 20 + } + entry: = log.WithField("transaction", transaction) + entry.Info("Sending transaction") + if err: = stream.Send(transaction); + err != nil { + entry.WithError(err).Error("Error sending transaction") + return err + } + entry.Info("Transaction sent. Waiting for processing response") + response, err: = stream.Recv() + if err != nil { + entry.WithError(err).Error("Error receiving processing response") + return err + } + if response.Id != s.counter { + // NOTE: this is just a guard and not happening as transaction is local per connection + entry.Error("Received processing response of a different transaction") + } else { + entry.Info("Processing response received") + s.counter++ + } + } + } + }() +}