/* * Copyright (C) 2023-2024 * Das Land Schleswig-Holstein vertreten durch den * Ministerpräsidenten des Landes Schleswig-Holstein * Staatskanzlei * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung * * Lizenziert unter der EUPL, Version 1.2 oder - sobald * diese von der Europäischen Kommission genehmigt wurden - * Folgeversionen der EUPL ("Lizenz"); * Sie dürfen dieses Werk ausschließlich gemäß * dieser Lizenz nutzen. * Eine Kopie der Lizenz finden Sie hier: * * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * * Sofern nicht durch anwendbare Rechtsvorschriften * gefordert oder in schriftlicher Form vereinbart, wird * die unter der Lizenz verbreitete Software "so wie sie * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - * ausdrücklich oder stillschweigend - verbreitet. * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ package server import ( "context" "errors" pb "fachstellen-proxy/gen/go" "fachstellen-proxy/internal/config" "fachstellen-proxy/internal/mock" "fmt" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "net" ) const keyClientName = "CLIENT_NAME-bin" const clientName = "FachstellenServer" type collaborationRouter struct { pb.UnimplementedCollaborationServiceServer } func (s *collaborationRouter) FindVorgang(ctx context.Context, in *pb.GrpcFindVorgangRequest) (*pb.GrpcFindVorgangResponse, error) { response, err := s.handleRequest(ctx, func(client pb.CollaborationServiceClient, ctx context.Context) (interface{}, error) { return client.FindVorgang(ctx, in) }) if response == nil { return nil, err } return response.(*pb.GrpcFindVorgangResponse), err } func (s *collaborationRouter) handleRequest(ctx context.Context, handler func(pb.CollaborationServiceClient, context.Context) (interface{}, error)) (interface{}, error) { logger.Info(fmt.Sprintf("setting grpc headers %s: %s", keyClientName, clientName)) ctx = metadata.AppendToOutgoingContext(ctx, keyClientName, clientName) md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, status.Error(codes.InvalidArgument, "unable to retrieve metadata") } grpcAddress := md.Get(GrpcAddressMetadata) if len(grpcAddress) == 0 { return nil, status.Error(codes.InvalidArgument, "grpc address is missing") } client, connCleanUp, err := createCollaborationClient(grpcAddress[0]) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } defer connCleanUp() return handler(client, ctx) } func createCollaborationClient(grpcAddress string) (pb.CollaborationServiceClient, func() error, error) { target := GetCollaborationServerUrl(grpcAddress, conf) conn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { logger.Error("collaboration router failed to route: %v", err) return nil, nil, errors.New("collaboration router failed to route") } return pb.NewCollaborationServiceClient(conn), conn.Close, nil } func GetCollaborationServerUrl(collaborationServerAddress string, c config.Config) string { collaborationServerPort := c.Grpc.Collaboration.Server.Port if c.Grpc.Mock { collaborationServerPort = mock.GrpcMockPort } return fmt.Sprintf("%v:%d", collaborationServerAddress, collaborationServerPort) } func StartCollaborationRouter() *grpc.Server { s := grpc.NewServer() pb.RegisterCollaborationServiceServer(s, &collaborationRouter{}) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.Grpc.Collaboration.Router.Port)) if err != nil { logger.Fatal("collaboration router failed to listen: %v", err) } logger.Info("collaboration router listening on port %d", conf.Grpc.Collaboration.Router.Port) if err := s.Serve(lis); err != nil { logger.Fatal("collaboration router failed to serve: %v", err) } return s }