diff --git a/docker-compose.yml b/docker-compose.yml index 2f48889d803edc4f1d12617a7667d21312def625..2a7c51013c13468884910091b657bc15025af9f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,20 @@ services: + banktransfer: + build: + context: ./src + dockerfile: banktransfer/Dockerfile + ports: + - "9111:9111" myaktion: - build: ./src/myaktion + build: + context: ./src + dockerfile: myaktion/Dockerfile ports: - "8000:8000" environment: - DB_CONNECT=mariadb:3306 - - LOG_LEVEL=info + - BANKTRANSFER_CONNECT=banktransfer:9111 + - LOG_LEVEL=info # change to trace for debugging mariadb: image: mariadb:10.5 environment: diff --git a/go.work b/go.work index b8c8690d95eb733e44c62cb0ee1c9adc2346cf24..0471fe4939d682c6a2df735a2b9a0ccba366724d 100644 --- a/go.work +++ b/go.work @@ -1,3 +1,4 @@ go 1.20 -use ./src/myaktion \ No newline at end of file +use ./src/myaktion +use ./src/banktransfer \ No newline at end of file diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 0000000000000000000000000000000000000000..a5044ec15a4c3501c9662f1b3e2d99a190752eb2 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,7 @@ +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/src/banktransfer/Dockerfile b/src/banktransfer/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..808cebe062459b3c434fd713d79b76e226d8cf4d --- /dev/null +++ b/src/banktransfer/Dockerfile @@ -0,0 +1,18 @@ +FROM golang:1.20-buster + +WORKDIR /go/src/app +COPY ./banktransfer . + +RUN apt update +RUN apt install -y protobuf-compiler + +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 + +RUN go mod download +RUN go generate ./... +RUN go install + +CMD ["banktransfer"] + +EXPOSE 9111 diff --git a/src/banktransfer/go.mod b/src/banktransfer/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..c00b0a4e19077863c09c2fd1f6f350163d949ec4 --- /dev/null +++ b/src/banktransfer/go.mod @@ -0,0 +1,17 @@ +module gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/banktransfer + +go 1.20 + +require ( + github.com/sirupsen/logrus v1.9.0 + google.golang.org/grpc v1.55.0 + google.golang.org/protobuf v1.30.0 +) + +require ( + github.com/golang/protobuf v1.5.3 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect +) diff --git a/src/banktransfer/go.sum b/src/banktransfer/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..fb01c1e07192678cd415679aee90e5d3ff41b917 --- /dev/null +++ b/src/banktransfer/go.sum @@ -0,0 +1,34 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/banktransfer/grpc/banktransfer/banktransfer.pb.go b/src/banktransfer/grpc/banktransfer/banktransfer.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..93f5ffc07e107e63fba5d273c5a69c674dad5d0e --- /dev/null +++ b/src/banktransfer/grpc/banktransfer/banktransfer.pb.go @@ -0,0 +1,365 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.17.0 +// source: banktransfer/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" +) + +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 + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + 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"` +} + +func (x *Account) Reset() { + *x = Account{} + if protoimpl.UnsafeEnabled { + mi := &file_banktransfer_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_banktransfer_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && 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_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 + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + 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"` +} + +func (x *Transaction) Reset() { + *x = Transaction{} + if protoimpl.UnsafeEnabled { + mi := &file_banktransfer_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_banktransfer_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && 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_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 + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ProcessingResponse) Reset() { + *x = ProcessingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_banktransfer_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_banktransfer_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && 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_banktransfer_proto_rawDescGZIP(), []int{2} +} + +func (x *ProcessingResponse) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +var File_banktransfer_banktransfer_proto protoreflect.FileDescriptor + +var file_banktransfer_banktransfer_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2f, 0x62, + 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0c, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x1a, + 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x52, 0x0a, 0x07, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, + 0x61, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x62, 0x61, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x22, 0xe4, 0x01, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x64, 0x6f, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x02, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x34, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x09, 0x74, 0x6f, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x24, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x32, 0xae, 0x01, + 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x44, + 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x12, + 0x19, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x62, 0x61, + 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x19, 0x2e, + 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x64, + 0x5a, 0x62, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x72, 0x65, 0x75, 0x74, 0x6c, 0x69, 0x6e, + 0x67, 0x65, 0x6e, 0x2d, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x2e, 0x64, + 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x73, 0x2f, 0x6d, + 0x79, 0x61, 0x6b, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x73, 0x73, 0x32, 0x30, 0x32, + 0x33, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_banktransfer_banktransfer_proto_rawDescOnce sync.Once + file_banktransfer_banktransfer_proto_rawDescData = file_banktransfer_banktransfer_proto_rawDesc +) + +func file_banktransfer_banktransfer_proto_rawDescGZIP() []byte { + file_banktransfer_banktransfer_proto_rawDescOnce.Do(func() { + file_banktransfer_banktransfer_proto_rawDescData = protoimpl.X.CompressGZIP(file_banktransfer_banktransfer_proto_rawDescData) + }) + return file_banktransfer_banktransfer_proto_rawDescData +} + +var file_banktransfer_banktransfer_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_banktransfer_banktransfer_proto_goTypes = []interface{}{ + (*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_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_banktransfer_proto_init() } +func file_banktransfer_banktransfer_proto_init() { + if File_banktransfer_banktransfer_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_banktransfer_banktransfer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Account); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_banktransfer_banktransfer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Transaction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_banktransfer_banktransfer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_banktransfer_banktransfer_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_banktransfer_banktransfer_proto_goTypes, + DependencyIndexes: file_banktransfer_banktransfer_proto_depIdxs, + MessageInfos: file_banktransfer_banktransfer_proto_msgTypes, + }.Build() + File_banktransfer_banktransfer_proto = out.File + file_banktransfer_banktransfer_proto_rawDesc = nil + file_banktransfer_banktransfer_proto_goTypes = nil + file_banktransfer_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..6b8844804562b426494f9ae58d111866c6c79767 --- /dev/null +++ b/src/banktransfer/grpc/banktransfer/banktransfer.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package banktransfer; + +import "google/protobuf/empty.proto"; + +option go_package = "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/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; +} 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..02af0f7c343852c91d51beb9b2850b4e8be423fb --- /dev/null +++ b/src/banktransfer/grpc/banktransfer/banktransfer_grpc.pb.go @@ -0,0 +1,171 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// 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) (BankTransfer_ProcessTransactionsClient, 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) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/banktransfer.BankTransfer/TransferMoney", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bankTransferClient) ProcessTransactions(ctx context.Context, opts ...grpc.CallOption) (BankTransfer_ProcessTransactionsClient, error) { + stream, err := c.cc.NewStream(ctx, &BankTransfer_ServiceDesc.Streams[0], "/banktransfer.BankTransfer/ProcessTransactions", opts...) + if err != nil { + return nil, err + } + x := &bankTransferProcessTransactionsClient{stream} + return x, nil +} + +type BankTransfer_ProcessTransactionsClient interface { + Send(*ProcessingResponse) error + Recv() (*Transaction, error) + grpc.ClientStream +} + +type bankTransferProcessTransactionsClient struct { + grpc.ClientStream +} + +func (x *bankTransferProcessTransactionsClient) Send(m *ProcessingResponse) error { + return x.ClientStream.SendMsg(m) +} + +func (x *bankTransferProcessTransactionsClient) Recv() (*Transaction, error) { + m := new(Transaction) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// 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(BankTransfer_ProcessTransactionsServer) error + mustEmbedUnimplementedBankTransferServer() +} + +// UnimplementedBankTransferServer must be embedded to have forward compatible implementations. +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(BankTransfer_ProcessTransactionsServer) error { + return status.Errorf(codes.Unimplemented, "method ProcessTransactions not implemented") +} +func (UnimplementedBankTransferServer) mustEmbedUnimplementedBankTransferServer() {} + +// 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) { + 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.BankTransfer/TransferMoney", + } + 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(&bankTransferProcessTransactionsServer{stream}) +} + +type BankTransfer_ProcessTransactionsServer interface { + Send(*Transaction) error + Recv() (*ProcessingResponse, error) + grpc.ServerStream +} + +type bankTransferProcessTransactionsServer struct { + grpc.ServerStream +} + +func (x *bankTransferProcessTransactionsServer) Send(m *Transaction) error { + return x.ServerStream.SendMsg(m) +} + +func (x *bankTransferProcessTransactionsServer) Recv() (*ProcessingResponse, error) { + m := new(ProcessingResponse) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// 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/banktransfer.proto", +} diff --git a/src/banktransfer/grpc/gen.go b/src/banktransfer/grpc/gen.go new file mode 100644 index 0000000000000000000000000000000000000000..3ffe6f4a5695753675fc62ae4dca7d7d863513d6 --- /dev/null +++ b/src/banktransfer/grpc/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/banktransfer.proto diff --git a/src/banktransfer/main.go b/src/banktransfer/main.go new file mode 100644 index 0000000000000000000000000000000000000000..6ddf1f1308f7c08e49a73fad3d79dcd31ece5dfc --- /dev/null +++ b/src/banktransfer/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "net" + "os" + + log "github.com/sirupsen/logrus" + "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/banktransfer/grpc/banktransfer" + "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/banktransfer/service" + "google.golang.org/grpc" +) + +func init() { + // init logger + 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..a76ac70f3e9896f44789a18e6f05c59abeaff761 --- /dev/null +++ b/src/banktransfer/service/banktransfer.go @@ -0,0 +1,59 @@ +package service + +import ( + "context" + "time" + + log "github.com/sirupsen/logrus" + "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/banktransfer/grpc/banktransfer" + "google.golang.org/protobuf/types/known/emptypb" +) + +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++ + } + } + } + }() +} diff --git a/src/myaktion/Dockerfile b/src/myaktion/Dockerfile index 4a7fcaa02cafd447b229904362eb2b53ff55f477..e18fcf753f634b9b9104c982d7cdcb5911568928 100644 --- a/src/myaktion/Dockerfile +++ b/src/myaktion/Dockerfile @@ -1,9 +1,24 @@ FROM golang:1.20-buster +# non-go modules dependencies +RUN apt update +RUN apt install -y protobuf-compiler + +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 + +# copy code and protobuf WORKDIR /go/src/app -COPY . . +COPY ./myaktion . +COPY ./banktransfer/grpc/banktransfer/banktransfer.proto ./client/banktransfer/ + RUN go mod download +RUN go generate ./... RUN go install + +RUN wget https://raw.githubusercontent.com/vishnubob/wait-for-it/81b1373f17855a4dc21156cfe1694c31d7d1792e/wait-for-it.sh RUN chmod +x ./wait-for-it.sh ./docker-entrypoint.sh + ENTRYPOINT ["./docker-entrypoint.sh"] -CMD ["myaktion"] +CMD ["myaktion"] + EXPOSE 8000 \ No newline at end of file diff --git a/src/myaktion/client/banktransfer.go b/src/myaktion/client/banktransfer.go new file mode 100644 index 0000000000000000000000000000000000000000..99151ce5e41ece5dfd0f346fea4d6198f8dc170d --- /dev/null +++ b/src/myaktion/client/banktransfer.go @@ -0,0 +1,26 @@ +package client + +import ( + "context" + "os" + + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +var ( + bankTransferTarget = os.Getenv("BANKTRANSFER_CONNECT") +) + +func GetBankTransferConnection(ctx context.Context) (*grpc.ClientConn, error) { + var err error + log.WithFields(log.Fields{ + "target": bankTransferTarget, + }).Infoln("Connecting to banktransfer service") + var conn *grpc.ClientConn + conn, err = grpc.DialContext(ctx, bankTransferTarget, grpc.WithInsecure(), grpc.WithBlock()) + if err != nil { + return nil, err + } + return conn, nil +} diff --git a/src/myaktion/client/banktransfer/banktransfer.pb.go b/src/myaktion/client/banktransfer/banktransfer.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..93f5ffc07e107e63fba5d273c5a69c674dad5d0e --- /dev/null +++ b/src/myaktion/client/banktransfer/banktransfer.pb.go @@ -0,0 +1,365 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.17.0 +// source: banktransfer/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" +) + +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 + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + 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"` +} + +func (x *Account) Reset() { + *x = Account{} + if protoimpl.UnsafeEnabled { + mi := &file_banktransfer_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_banktransfer_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && 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_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 + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + 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"` +} + +func (x *Transaction) Reset() { + *x = Transaction{} + if protoimpl.UnsafeEnabled { + mi := &file_banktransfer_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_banktransfer_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && 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_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 + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ProcessingResponse) Reset() { + *x = ProcessingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_banktransfer_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_banktransfer_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && 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_banktransfer_proto_rawDescGZIP(), []int{2} +} + +func (x *ProcessingResponse) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +var File_banktransfer_banktransfer_proto protoreflect.FileDescriptor + +var file_banktransfer_banktransfer_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2f, 0x62, + 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0c, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x1a, + 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x52, 0x0a, 0x07, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, + 0x61, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x62, 0x61, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x22, 0xe4, 0x01, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x64, 0x6f, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x02, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x34, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x09, 0x74, 0x6f, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x24, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x32, 0xae, 0x01, + 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x44, + 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x12, + 0x19, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x62, 0x61, + 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x19, 0x2e, + 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x64, + 0x5a, 0x62, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x72, 0x65, 0x75, 0x74, 0x6c, 0x69, 0x6e, + 0x67, 0x65, 0x6e, 0x2d, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x2e, 0x64, + 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x73, 0x2f, 0x6d, + 0x79, 0x61, 0x6b, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x73, 0x73, 0x32, 0x30, 0x32, + 0x33, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x62, 0x61, 0x6e, 0x6b, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_banktransfer_banktransfer_proto_rawDescOnce sync.Once + file_banktransfer_banktransfer_proto_rawDescData = file_banktransfer_banktransfer_proto_rawDesc +) + +func file_banktransfer_banktransfer_proto_rawDescGZIP() []byte { + file_banktransfer_banktransfer_proto_rawDescOnce.Do(func() { + file_banktransfer_banktransfer_proto_rawDescData = protoimpl.X.CompressGZIP(file_banktransfer_banktransfer_proto_rawDescData) + }) + return file_banktransfer_banktransfer_proto_rawDescData +} + +var file_banktransfer_banktransfer_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_banktransfer_banktransfer_proto_goTypes = []interface{}{ + (*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_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_banktransfer_proto_init() } +func file_banktransfer_banktransfer_proto_init() { + if File_banktransfer_banktransfer_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_banktransfer_banktransfer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Account); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_banktransfer_banktransfer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Transaction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_banktransfer_banktransfer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_banktransfer_banktransfer_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_banktransfer_banktransfer_proto_goTypes, + DependencyIndexes: file_banktransfer_banktransfer_proto_depIdxs, + MessageInfos: file_banktransfer_banktransfer_proto_msgTypes, + }.Build() + File_banktransfer_banktransfer_proto = out.File + file_banktransfer_banktransfer_proto_rawDesc = nil + file_banktransfer_banktransfer_proto_goTypes = nil + file_banktransfer_banktransfer_proto_depIdxs = nil +} diff --git a/src/myaktion/client/banktransfer/banktransfer.proto b/src/myaktion/client/banktransfer/banktransfer.proto new file mode 100644 index 0000000000000000000000000000000000000000..6b8844804562b426494f9ae58d111866c6c79767 --- /dev/null +++ b/src/myaktion/client/banktransfer/banktransfer.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package banktransfer; + +import "google/protobuf/empty.proto"; + +option go_package = "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/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; +} diff --git a/src/myaktion/client/banktransfer/banktransfer_grpc.pb.go b/src/myaktion/client/banktransfer/banktransfer_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..02af0f7c343852c91d51beb9b2850b4e8be423fb --- /dev/null +++ b/src/myaktion/client/banktransfer/banktransfer_grpc.pb.go @@ -0,0 +1,171 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// 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) (BankTransfer_ProcessTransactionsClient, 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) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/banktransfer.BankTransfer/TransferMoney", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bankTransferClient) ProcessTransactions(ctx context.Context, opts ...grpc.CallOption) (BankTransfer_ProcessTransactionsClient, error) { + stream, err := c.cc.NewStream(ctx, &BankTransfer_ServiceDesc.Streams[0], "/banktransfer.BankTransfer/ProcessTransactions", opts...) + if err != nil { + return nil, err + } + x := &bankTransferProcessTransactionsClient{stream} + return x, nil +} + +type BankTransfer_ProcessTransactionsClient interface { + Send(*ProcessingResponse) error + Recv() (*Transaction, error) + grpc.ClientStream +} + +type bankTransferProcessTransactionsClient struct { + grpc.ClientStream +} + +func (x *bankTransferProcessTransactionsClient) Send(m *ProcessingResponse) error { + return x.ClientStream.SendMsg(m) +} + +func (x *bankTransferProcessTransactionsClient) Recv() (*Transaction, error) { + m := new(Transaction) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// 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(BankTransfer_ProcessTransactionsServer) error + mustEmbedUnimplementedBankTransferServer() +} + +// UnimplementedBankTransferServer must be embedded to have forward compatible implementations. +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(BankTransfer_ProcessTransactionsServer) error { + return status.Errorf(codes.Unimplemented, "method ProcessTransactions not implemented") +} +func (UnimplementedBankTransferServer) mustEmbedUnimplementedBankTransferServer() {} + +// 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) { + 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.BankTransfer/TransferMoney", + } + 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(&bankTransferProcessTransactionsServer{stream}) +} + +type BankTransfer_ProcessTransactionsServer interface { + Send(*Transaction) error + Recv() (*ProcessingResponse, error) + grpc.ServerStream +} + +type bankTransferProcessTransactionsServer struct { + grpc.ServerStream +} + +func (x *bankTransferProcessTransactionsServer) Send(m *Transaction) error { + return x.ServerStream.SendMsg(m) +} + +func (x *bankTransferProcessTransactionsServer) Recv() (*ProcessingResponse, error) { + m := new(ProcessingResponse) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// 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/banktransfer.proto", +} diff --git a/src/myaktion/client/gen.go b/src/myaktion/client/gen.go new file mode 100644 index 0000000000000000000000000000000000000000..b45f11ff5ebca441fe314bbdb36dcdb1c602bc15 --- /dev/null +++ b/src/myaktion/client/gen.go @@ -0,0 +1,3 @@ +package client + +//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative banktransfer/banktransfer.proto diff --git a/src/myaktion/docker-entrypoint.sh b/src/myaktion/docker-entrypoint.sh index c3ab7f554d8e5e396c18bb012c5b77d3d531f30c..ab3b0d48e06de3d272f8e10365f2b125063ff2e0 100644 --- a/src/myaktion/docker-entrypoint.sh +++ b/src/myaktion/docker-entrypoint.sh @@ -7,5 +7,10 @@ if [ -n "$DB_CONNECT" ]; then /go/src/app/wait-for-it.sh "$DB_CONNECT" -t 20 fi +# Wait for banktransfer +if [ -n "$BANKTRANSFER_CONNECT" ]; then + /go/src/app/wait-for-it.sh "$BANKTRANSFER_CONNECT" -t 20 +fi + # Run the main container command. exec "$@" \ No newline at end of file diff --git a/src/myaktion/go.mod b/src/myaktion/go.mod index 9a54c3f656dfbb64e16de7479a1a2036da66164a..e6d0f8f0b13e1180279a30209879f1997aac99d8 100644 --- a/src/myaktion/go.mod +++ b/src/myaktion/go.mod @@ -5,6 +5,8 @@ go 1.20 require ( github.com/gorilla/mux v1.8.0 github.com/sirupsen/logrus v1.9.0 + google.golang.org/grpc v1.55.0 + google.golang.org/protobuf v1.30.0 ) require ( @@ -18,6 +20,7 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect @@ -30,7 +33,10 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect golang.org/x/mod v0.9.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/tools v0.7.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect ) @@ -40,6 +46,6 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/ory/dockertest/v3 v3.10.0 golang.org/x/sys v0.7.0 // indirect - gorm.io/driver/mysql v1.5.0 // indirect - gorm.io/gorm v1.25.0 // indirect + gorm.io/driver/mysql v1.5.0 + gorm.io/gorm v1.25.0 ) diff --git a/src/myaktion/go.sum b/src/myaktion/go.sum index 8ce9d43cc47ed16e34a758fb08b54142d44feb0c..de6d10a85db211201013b3614b462e97f038d34b 100644 --- a/src/myaktion/go.sum +++ b/src/myaktion/go.sum @@ -14,6 +14,7 @@ github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvA github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -36,10 +37,13 @@ github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= @@ -55,6 +59,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= @@ -86,8 +91,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= @@ -113,9 +118,12 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -128,13 +136,14 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -146,17 +155,26 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gorm.io/driver/mysql v1.5.0 h1:6hSAT5QcyIaty0jfnff0z0CLDjyRgZ8mlMHLqSt7uXM= gorm.io/driver/mysql v1.5.0/go.mod h1:FFla/fJuCvyTi7rJQd27qlNX2v3L6deTR1GgTjSOLPo= gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU= gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= diff --git a/src/myaktion/main.go b/src/myaktion/main.go index 0643a493e70eff5642eff52af8ab57601f339f88..3602b0f7ba5c97d06f4020855cbad483ef6bb3fb 100644 --- a/src/myaktion/main.go +++ b/src/myaktion/main.go @@ -38,6 +38,7 @@ func main() { router.HandleFunc("/campaigns/{id}", handler.UpdateCampaign).Methods("PUT") router.HandleFunc("/campaigns/{id}", handler.DeleteCampaign).Methods("DELETE") router.HandleFunc("/campaigns/{id}/donation", handler.AddDonation).Methods("POST") + go monitortransactions() if err := http.ListenAndServe(":8000", router); err != nil { log.Fatal(err) } diff --git a/src/myaktion/monitor.go b/src/myaktion/monitor.go new file mode 100644 index 0000000000000000000000000000000000000000..16ae2f4e463941e71356f761a744063c331c0eca --- /dev/null +++ b/src/myaktion/monitor.go @@ -0,0 +1,53 @@ +package main + +import ( + "context" + "time" + + log "github.com/sirupsen/logrus" + "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/myaktion/client" + "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/myaktion/client/banktransfer" +) + +func monitortransactions() { + for { + connectandmonitor() + time.Sleep(time.Second) + } +} + +func connectandmonitor() { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + conn, err := client.GetBankTransferConnection(ctx) + if err != nil { + log.WithError(err).Fatal("error connecting to the banktransfer service") + } + defer conn.Close() + + banktransferClient := banktransfer.NewBankTransferClient(conn) + watcher, err := banktransferClient.ProcessTransactions(ctx) + if err != nil { + log.WithError(err).Fatal("error watching transactions") + } + log.Info("Successfully connected to banktransfer service for processing transactions") + for { + transaction, err := watcher.Recv() + if err != nil { + if _, deadline := ctx.Deadline(); deadline { + log.Info("deadline reached. reconnect client") + break + } + log.WithError(err).Error("error receiving transaction") + continue + } + entry := log.WithField("transaction", transaction) + entry.Info("Received transaction. Sending processing response") + err = watcher.Send(&banktransfer.ProcessingResponse{Id: transaction.Id}) + if err != nil { + entry.WithError(err).Error("error sending processing response") + continue + } + entry.Info("Processing response sent") + } +} diff --git a/src/myaktion/service/donation.go b/src/myaktion/service/donation.go index 5655d406e5dca3aa75e5b626927aafbd72a40295..aefb75e1dc72522e0416663855537c3a85affe26 100644 --- a/src/myaktion/service/donation.go +++ b/src/myaktion/service/donation.go @@ -1,20 +1,76 @@ package service import ( + "context" + "time" + log "github.com/sirupsen/logrus" + "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/myaktion/client" + "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/myaktion/client/banktransfer" "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/myaktion/db" "gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss2023/src/myaktion/model" ) func AddDonation(campaignId uint, donation *model.Donation) error { + campaign, err := GetCampaign(campaignId) + if err != nil { + return err + } + donation.CampaignID = campaignId result := db.DB.Create(donation) if result.Error != nil { return result.Error } + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + conn, err := client.GetBankTransferConnection(ctx) + if err != nil { + log.Errorf("error connecting to the banktransfer service: %v", err) + deleteDonation(donation) + return err + } + defer conn.Close() + + banktransferClient := banktransfer.NewBankTransferClient(conn) + _, err = banktransferClient.TransferMoney(ctx, &banktransfer.Transaction{ + DonationId: int32(donation.ID), + Amount: float32(donation.Amount), + Reference: "Donation", + FromAccount: convertAccount(&donation.Account), + ToAccount: convertAccount(&campaign.Account), + }) + if err != nil { + log.Errorf("error calling the banktransfer service: %v", err) + deleteDonation(donation) + return err + } + entry := log.WithField("ID", campaignId) entry.Info("Successfully added new donation to campaign in database.") entry.Tracef("Stored: %v", donation) return nil } + +func convertAccount(account *model.Account) *banktransfer.Account { + return &banktransfer.Account{ + Name: account.Name, + BankName: account.BankName, + Number: account.Number, + } +} + +func deleteDonation(donation *model.Donation) error { + entry := log.WithField("donationID", donation.ID) + entry.Info("Trying to delete donation to make state consistent.") + result := db.DB.Delete(donation) + if result.Error != nil { + // Note: configure logger to raise an alarm to compensate inconsistent state + entry.WithField("alarm", true).Error("") + return result.Error + } + entry.Info("Successfully deleted campaign.") + return nil +}