From acc048a80af42492be9eff810902bc26b206b70b Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 23:46:23 +0200 Subject: [PATCH] feat:#36 updated feed service with more protobuf endpoints --- services/Makefile | 2 +- services/data-manager/service/db/dbFeeds.go | 2 +- .../data-manager/service/grpc/feedService.go | 33 +++++++++ services/data-manager/service/grpc/mapper.go | 10 +++ .../service/grpc/moduleService.go | 69 ++++++++++++++++++ services/data-manager/service/grpc/server.go | 71 ++----------------- services/ical/model/icalModel.go | 2 - services/ical/service/connector/grpc/feeds.go | 52 ++++++++++++++ services/ical/service/ical/ical.go | 2 +- services/protobuf/feeds.proto | 23 ++++++ 10 files changed, 197 insertions(+), 69 deletions(-) create mode 100644 services/data-manager/service/grpc/feedService.go create mode 100644 services/data-manager/service/grpc/moduleService.go create mode 100644 services/ical/service/connector/grpc/feeds.go create mode 100644 services/protobuf/feeds.proto diff --git a/services/Makefile b/services/Makefile index 94269fa..1cf2ba8 100644 --- a/services/Makefile +++ b/services/Makefile @@ -9,7 +9,7 @@ build-ical: gen: @protoc \ - --proto_path=protobuf "protobuf/modules.proto" \ + --proto_path=protobuf "protobuf/*" \ --go_out="common/genproto/modules" \ --go_opt=paths=source_relative \ --go-grpc_out="common/genproto/modules" \ diff --git a/services/data-manager/service/db/dbFeeds.go b/services/data-manager/service/db/dbFeeds.go index 1ad6ad3..2ae46e1 100644 --- a/services/data-manager/service/db/dbFeeds.go +++ b/services/data-manager/service/db/dbFeeds.go @@ -37,7 +37,7 @@ func SaveFeed(feed model.Feed, collection *models.Collection, app *pocketbase.Po return record, nil } -func FindFeedByToken(token string, app *pocketbase.PocketBase) (*model.Feed, error) { +func FindFeedByToken(app *pocketbase.PocketBase, token string) (*model.Feed, error) { record, err := app.Dao().FindRecordById("feeds", token) diff --git a/services/data-manager/service/grpc/feedService.go b/services/data-manager/service/grpc/feedService.go new file mode 100644 index 0000000..67870c8 --- /dev/null +++ b/services/data-manager/service/grpc/feedService.go @@ -0,0 +1,33 @@ +package grpc + +import ( + "context" + "github.com/pocketbase/pocketbase" + pb "htwkalender/common/genproto/modules" + "htwkalender/data-manager/service/db" +) + +type FeedServiceHandler struct { + app *pocketbase.PocketBase + pb.UnimplementedFeedServiceServer +} + +func (s *FeedServiceHandler) GetFeed(ctx context.Context, in *pb.GetFeedRequest) (*pb.GetFeedResponse, error) { + + s.app.Logger().Info( + "Protobuf - GetFeed", + "uuid", in.Id, + ) + + // get feed from database by UUID + feed, err := db.FindFeedByToken(s.app, in.Id) + if err != nil { + return nil, err + } + + // Implement your logic here to fetch feed data based on the UUID + // Example response + return &pb.GetFeedResponse{ + Feed: feedToProto(feed), + }, nil +} diff --git a/services/data-manager/service/grpc/mapper.go b/services/data-manager/service/grpc/mapper.go index 01f439c..ee3ea58 100644 --- a/services/data-manager/service/grpc/mapper.go +++ b/services/data-manager/service/grpc/mapper.go @@ -31,3 +31,13 @@ func eventsToProto(events model.Events) []*pb.Event { } return protoEvents } + +func feedToProto(feed *model.Feed) *pb.Feed { + return &pb.Feed{ + Id: feed.Id, + Created: feed.Created.String(), + Updated: feed.Updated.String(), + Retrieved: feed.Retrieved.String(), + Modules: feed.Modules, + } +} diff --git a/services/data-manager/service/grpc/moduleService.go b/services/data-manager/service/grpc/moduleService.go new file mode 100644 index 0000000..b220809 --- /dev/null +++ b/services/data-manager/service/grpc/moduleService.go @@ -0,0 +1,69 @@ +package grpc + +import ( + "context" + "github.com/pocketbase/pocketbase" + pb "htwkalender/common/genproto/modules" + "htwkalender/data-manager/service/db" +) + +type ModuleServiceHandler struct { + app *pocketbase.PocketBase + pb.UnimplementedModuleServiceServer +} + +func (s *ModuleServiceHandler) GetModule(ctx context.Context, in *pb.GetModuleRequest) (*pb.GetModuleResponse, error) { + + s.app.Logger().Info( + "Protobuf - GetModule", + "uuid", in.Uuid, + ) + + // get module from database by UUID + module, err := db.FindModuleByUUID(s.app, in.Uuid) + if err != nil { + return nil, err + } + + events, err := db.FindAllEventsByModule(s.app, module) + if err != nil { + return nil, err + } + + //map module Events to proto struct Events + protoEvents := make([]*pb.Event, 0) + for _, event := range events { + protoEvents = append(protoEvents, eventToProto(&event)) + } + //map module to proto struct + protoModule := &pb.Module{ + Uuid: module.UUID, + Name: module.Name, + Prof: module.Prof, + Course: module.Course, + Semester: module.Semester, + Events: protoEvents, + } + // Implement your logic here to fetch module data based on the UUID + // Example response + return &pb.GetModuleResponse{ + Module: protoModule, + }, nil +} + +func (s *ModuleServiceHandler) GetEventsForModules(ctx context.Context, in *pb.GetModulesRequest) (*pb.GetEventsResponse, error) { + + s.app.Logger().Info( + "Protobuf - GetEventsForModules", + "uuids", in.Uuids, + ) + + events, err := db.GetPlanForModules(s.app, in.Uuids) + if err != nil { + return nil, err + } + + return &pb.GetEventsResponse{ + Events: eventsToProto(events), + }, nil +} diff --git a/services/data-manager/service/grpc/server.go b/services/data-manager/service/grpc/server.go index edf3191..f5b6ad3 100644 --- a/services/data-manager/service/grpc/server.go +++ b/services/data-manager/service/grpc/server.go @@ -1,9 +1,7 @@ package grpc import ( - "context" "github.com/pocketbase/pocketbase" - "htwkalender/data-manager/service/db" "log" "net" @@ -11,78 +9,23 @@ import ( pb "htwkalender/common/genproto/modules" ) -type ModulesGrpcHandler struct { - app *pocketbase.PocketBase - pb.UnimplementedModuleServiceServer -} - -func (s *ModulesGrpcHandler) GetModule(ctx context.Context, in *pb.GetModuleRequest) (*pb.GetModuleResponse, error) { - - s.app.Logger().Info( - "Protobuf - GetModule", - "uuid", in.Uuid, - ) - - // get module from database by UUID - module, err := db.FindModuleByUUID(s.app, in.Uuid) - if err != nil { - return nil, err - } - - events, err := db.FindAllEventsByModule(s.app, module) - if err != nil { - return nil, err - } - - //map module Events to proto struct Events - protoEvents := make([]*pb.Event, 0) - for _, event := range events { - protoEvents = append(protoEvents, eventToProto(&event)) - } - //map module to proto struct - protoModule := &pb.Module{ - Uuid: module.UUID, - Name: module.Name, - Prof: module.Prof, - Course: module.Course, - Semester: module.Semester, - Events: protoEvents, - } - // Implement your logic here to fetch module data based on the UUID - // Example response - return &pb.GetModuleResponse{ - Module: protoModule, - }, nil -} - func StartGRPCServer(app *pocketbase.PocketBase) { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterModuleServiceServer(s, &ModulesGrpcHandler{ + + pb.RegisterModuleServiceServer(s, &ModuleServiceHandler{ app: app, }) + + pb.RegisterFeedServiceServer(s, &FeedServiceHandler{ + app: app, + }) + log.Printf("server listening at %v", lis.Addr()) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } - -func (s *ModulesGrpcHandler) GetEventsForModules(ctx context.Context, in *pb.GetModulesRequest) (*pb.GetEventsResponse, error) { - - s.app.Logger().Info( - "Protobuf - GetEventsForModules", - "uuids", in.Uuids, - ) - - events, err := db.GetPlanForModules(s.app, in.Uuids) - if err != nil { - return nil, err - } - - return &pb.GetEventsResponse{ - Events: eventsToProto(events), - }, nil -} diff --git a/services/ical/model/icalModel.go b/services/ical/model/icalModel.go index cbd11bf..7ff9263 100644 --- a/services/ical/model/icalModel.go +++ b/services/ical/model/icalModel.go @@ -19,7 +19,6 @@ package model import ( "encoding/json" "fmt" - "log/slog" "strings" "time" ) @@ -88,7 +87,6 @@ func (jt *JSONTime) UnmarshalJSON(b []byte) error { func ToJSONTime(timeString string) JSONTime { t, err := time.Parse(DefaultDateLayout, timeString) if err != nil { - slog.Error("error parsing time string: ", "error", err) return JSONTime(time.Time{}) } return JSONTime(t) diff --git a/services/ical/service/connector/grpc/feeds.go b/services/ical/service/connector/grpc/feeds.go new file mode 100644 index 0000000..0f1f082 --- /dev/null +++ b/services/ical/service/connector/grpc/feeds.go @@ -0,0 +1,52 @@ +package grpc + +import ( + "context" + "github.com/goccy/go-json" + "google.golang.org/grpc" + pb "htwkalender/common/genproto/modules" + "htwkalender/ical/model" + "log/slog" + "time" +) + +func GetFeed(feedId string, conn *grpc.ClientConn) (model.FeedRecord, error) { + c := pb.NewFeedServiceClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + r, err := c.GetFeed(ctx, &pb.GetFeedRequest{Id: feedId}) + if err != nil { + slog.Error("could not get modules: %v", "error", err) + return model.FeedRecord{}, err + } + + feed, err := protoToFeed(r.GetFeed()) + if err != nil { + slog.Error("could not convert feed: %v", "error", err) + return model.FeedRecord{}, err + } + + return feed, nil +} + +func protoToFeed(feed *pb.Feed) (model.FeedRecord, error) { + + // unmarshal the []model.FeedModule from json + var modules []model.FeedModule + err := json.Unmarshal([]byte(feed.Modules), &modules) + if err != nil { + slog.Error("could not unmarshal modules: %v", "error", err) + return model.FeedRecord{}, err + } + + return model.FeedRecord{ + BaseModel: model.BaseModel{ + Id: feed.Id, + Created: model.ToJSONTime(feed.Created), + Updated: model.ToJSONTime(feed.Updated), + }, + Retrieved: model.ToJSONTime(feed.Retrieved), + Modules: modules, + }, nil +} diff --git a/services/ical/service/ical/ical.go b/services/ical/service/ical/ical.go index be57533..baa6160 100644 --- a/services/ical/service/ical/ical.go +++ b/services/ical/service/ical/ical.go @@ -14,7 +14,7 @@ const expirationTime = 5 * time.Minute func Feed(app model.AppType, token string) (string, error) { // get feed by token - feed, err := connector.GetFeedByToken(app.DataManagerURL, token) + feed, err := htwkalenderGrpc.GetFeed(token, app.GrpcClient) if err != nil { return "", err } diff --git a/services/protobuf/feeds.proto b/services/protobuf/feeds.proto new file mode 100644 index 0000000..7580cbd --- /dev/null +++ b/services/protobuf/feeds.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +option go_package = "htwkalender/common/modules"; + +service FeedService { + rpc GetFeed(GetFeedRequest) returns (GetFeedResponse) {} +} + +message Feed { + string id = 1; + string modules = 2; + string retrieved = 3; + string created = 4; + string updated = 5; +} + +message GetFeedRequest { + string id = 1; +} + +message GetFeedResponse { + Feed feed = 1; +} \ No newline at end of file