Skip to content
Snippets Groups Projects
Commit 0b282fbd authored by OZGCloud's avatar OZGCloud
Browse files

OZG-6730 Config Refactoring + Get File Endpunkt

parent d940c33d
No related branches found
No related tags found
No related merge requests found
Showing
with 187 additions and 338 deletions
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4"> <module type="JAVA_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$" />
......
...@@ -14,7 +14,5 @@ http: ...@@ -14,7 +14,5 @@ http:
body: "*" body: "*"
- selector: de.ozgcloud.vorgang.grpc.command.CommandService.GetCommand - selector: de.ozgcloud.vorgang.grpc.command.CommandService.GetCommand
get: "/api/v1/command/{id}" get: "/api/v1/command/{id}"
- selector: de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileService.GetBinaryFileContent
get: "/api/v1/file/content/{fileId}"
- selector: de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileService.FindBinaryFilesMetaData - selector: de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileService.FindBinaryFilesMetaData
get: "/api/v1/file/metadata/{fileId}" get: "/api/v1/file/metadata/{fileId}"
\ No newline at end of file
...@@ -40,8 +40,6 @@ func main() { ...@@ -40,8 +40,6 @@ func main() {
go mock.StartGrpcServer() go mock.StartGrpcServer()
} }
go server.StartRueckfrageRouter() go server.StartGrpcRouter()
go server.StartCommandRouter()
go server.StartBinaryFileRouter()
server.StartHttpGateway() server.StartHttpGateway()
} }
...@@ -4,13 +4,8 @@ http: ...@@ -4,13 +4,8 @@ http:
grpc: grpc:
server: server:
mock: true mock: true
port: 50054 port: 50052
router: router:
rueckfragen:
port: 50051 port: 50051
commands:
port: 50052
binaryfiles:
port: 50053
logging: logging:
level: "DEBUG" level: "DEBUG"
\ No newline at end of file
...@@ -50,15 +50,7 @@ type Config struct { ...@@ -50,15 +50,7 @@ type Config struct {
Port int `yaml:"port" envconfig:"GRPC_SERVER_PORT"` Port int `yaml:"port" envconfig:"GRPC_SERVER_PORT"`
} `yaml:"server"` } `yaml:"server"`
Router struct { Router struct {
Rueckfragen struct { Port int `yaml:"port" envconfig:"GRPC_ROUTER_PORT"`
Port int `yaml:"port" envconfig:"GRPC_ROUTER_RUECKFRAGEN_PORT"`
} `yaml:"rueckfragen"`
Commands struct {
Port int `yaml:"port" envconfig:"GRPC_ROUTER_COMMANDS_PORT"`
} `yaml:"commands"`
Binaryfiles struct {
Port int `yaml:"port" envconfig:"GRPC_ROUTER_BINARYFILES_PORT"`
} `yaml:"binaryfiles"`
} `yaml:"router"` } `yaml:"router"`
} `yaml:"grpc"` } `yaml:"grpc"`
Logging struct { Logging struct {
......
...@@ -39,10 +39,8 @@ func TestLoadConfig(t *testing.T) { ...@@ -39,10 +39,8 @@ func TestLoadConfig(t *testing.T) {
expectedConfig := Config{} expectedConfig := Config{}
expectedConfig.Grpc.Server.Mock = false expectedConfig.Grpc.Server.Mock = false
expectedConfig.Http.Server.Port = 8082 expectedConfig.Http.Server.Port = 8082
expectedConfig.Grpc.Server.Port = 50054 expectedConfig.Grpc.Server.Port = 50052
expectedConfig.Grpc.Router.Rueckfragen.Port = 50051 expectedConfig.Grpc.Router.Port = 50051
expectedConfig.Grpc.Router.Commands.Port = 50052
expectedConfig.Grpc.Router.Binaryfiles.Port = 50053
expectedConfig.Logging.Level = "DEBUG" expectedConfig.Logging.Level = "DEBUG"
assert.Equal(t, expectedConfig, config) assert.Equal(t, expectedConfig, config)
...@@ -52,9 +50,7 @@ func TestLoadConfig(t *testing.T) { ...@@ -52,9 +50,7 @@ func TestLoadConfig(t *testing.T) {
envVars := map[string]string{ envVars := map[string]string{
"HTTP_SERVER_PORT": "9090", "HTTP_SERVER_PORT": "9090",
"GRPC_SERVER_PORT": "1234", "GRPC_SERVER_PORT": "1234",
"GRPC_ROUTER_RUECKFRAGEN_PORT": "5678", "GRPC_ROUTER_PORT": "5678",
"GRPC_ROUTER_COMMANDS_PORT": "1357",
"GRPC_ROUTER_BINARYFILES_PORT": "2468",
"LOGGING_LEVEL": "ERROR", "LOGGING_LEVEL": "ERROR",
} }
...@@ -72,9 +68,7 @@ func TestLoadConfig(t *testing.T) { ...@@ -72,9 +68,7 @@ func TestLoadConfig(t *testing.T) {
expectedConfig.Grpc.Server.Mock = false expectedConfig.Grpc.Server.Mock = false
expectedConfig.Http.Server.Port = 9090 expectedConfig.Http.Server.Port = 9090
expectedConfig.Grpc.Server.Port = 1234 expectedConfig.Grpc.Server.Port = 1234
expectedConfig.Grpc.Router.Rueckfragen.Port = 5678 expectedConfig.Grpc.Router.Port = 5678
expectedConfig.Grpc.Router.Commands.Port = 1357
expectedConfig.Grpc.Router.Binaryfiles.Port = 2468
expectedConfig.Logging.Level = "ERROR" expectedConfig.Logging.Level = "ERROR"
assert.Equal(t, expectedConfig, config) assert.Equal(t, expectedConfig, config)
...@@ -84,7 +78,6 @@ func TestLoadConfig(t *testing.T) { ...@@ -84,7 +78,6 @@ func TestLoadConfig(t *testing.T) {
envVars := map[string]string{ envVars := map[string]string{
"HTTP_SERVER_PORT": "9090", "HTTP_SERVER_PORT": "9090",
"GRPC_SERVER_PORT": "1234", "GRPC_SERVER_PORT": "1234",
"GRPC_ROUTER_RUECKFRAGEN_PORT": "5678",
} }
for key, value := range envVars { for key, value := range envVars {
...@@ -101,9 +94,7 @@ func TestLoadConfig(t *testing.T) { ...@@ -101,9 +94,7 @@ func TestLoadConfig(t *testing.T) {
expectedConfig.Grpc.Server.Mock = false expectedConfig.Grpc.Server.Mock = false
expectedConfig.Http.Server.Port = 9090 expectedConfig.Http.Server.Port = 9090
expectedConfig.Grpc.Server.Port = 1234 expectedConfig.Grpc.Server.Port = 1234
expectedConfig.Grpc.Router.Rueckfragen.Port = 5678 expectedConfig.Grpc.Router.Port = 50051
expectedConfig.Grpc.Router.Commands.Port = 50052
expectedConfig.Grpc.Router.Binaryfiles.Port = 50053
expectedConfig.Logging.Level = "DEBUG" expectedConfig.Logging.Level = "DEBUG"
assert.Equal(t, expectedConfig, config) assert.Equal(t, expectedConfig, config)
......
...@@ -3,13 +3,8 @@ http: ...@@ -3,13 +3,8 @@ http:
port: 8082 port: 8082
grpc: grpc:
server: server:
port: 50054 port: 50052
router: router:
rueckfragen:
port: 50051 port: 50051
commands:
port: 50052
binaryfiles:
port: 50053
logging: logging:
level: "DEBUG" level: "DEBUG"
\ No newline at end of file
...@@ -3,13 +3,8 @@ http: ...@@ -3,13 +3,8 @@ http:
port: 8082 port: 8082
grpc: grpc:
server: server:
port: 50054 port: 50052
router: router:
rueckfragen:
port: 50051 port: 50051
commands:
port: 50052
binaryfiles:
port: 50053
logging: logging:
level: "INFO" level: "INFO"
\ No newline at end of file
...@@ -3,13 +3,8 @@ http: ...@@ -3,13 +3,8 @@ http:
port: 8082 port: 8082
grpc: grpc:
server: server:
port: 50054 port: 50052
router: router:
rueckfragen:
port: 50051 port: 50051
commands:
port: 50052
binaryfiles:
port: 50053
logging: logging:
level: "DEBUG" level: "DEBUG"
\ No newline at end of file
/*
* 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 (
pb "antragsraum-proxy/gen/go"
"antragsraum-proxy/internal/config"
"context"
"errors"
"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"
"io"
"net"
)
type binaryFileRouter struct {
pb.UnimplementedBinaryFileServiceServer
}
func (s *binaryFileRouter) GetBinaryFileContent(in *pb.GrpcGetBinaryFileDataRequest, stream pb.BinaryFileService_GetBinaryFileContentServer) error {
client, connCleanUp, err := s.getClientFromContext(stream.Context())
if err != nil {
return err
}
defer connCleanUp()
clientStream, err := client.GetBinaryFileContent(stream.Context(), in)
if err != nil {
return err
}
for {
resp, err := clientStream.Recv()
if err == io.EOF {
break
}
if err != nil {
return err
}
if err := stream.Send(resp); err != nil {
return err
}
}
return nil
}
func (s *binaryFileRouter) FindBinaryFilesMetaData(ctx context.Context, in *pb.GrpcBinaryFilesRequest) (*pb.GrpcFindFilesResponse, error) {
client, connCleanUp, err := s.getClientFromContext(ctx)
if err != nil {
return nil, err
}
defer connCleanUp()
return client.FindBinaryFilesMetaData(ctx, in)
}
func (s *binaryFileRouter) getClientFromContext(ctx context.Context) (pb.BinaryFileServiceClient, func() error, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, nil, status.Error(codes.InvalidArgument, "unable to retrieve metadata")
}
grpcAddress := md.Get(GrpcAddressMetadata)
if len(grpcAddress) == 0 {
return nil, nil, status.Error(codes.InvalidArgument, "grpc address is missing")
}
return createBinaryFileClient(grpcAddress[0])
}
func createBinaryFileClient(binaryFileServerAddress string) (pb.BinaryFileServiceClient, func() error, error) {
target := GetBinaryFileServerUrl(binaryFileServerAddress, conf)
conn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
logger.Error("binary file router failed to route: %v", err)
return nil, nil, errors.New("binary file router failed to route")
}
return pb.NewBinaryFileServiceClient(conn), conn.Close, nil
}
func GetBinaryFileServerUrl(binaryFileServerAddress string, c config.Config) string {
return fmt.Sprintf("%v:%d", binaryFileServerAddress, c.Grpc.Server.Port)
}
func StartBinaryFileRouter() *grpc.Server {
s := grpc.NewServer()
pb.RegisterBinaryFileServiceServer(s, &binaryFileRouter{})
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.Grpc.Router.Binaryfiles.Port))
if err != nil {
logger.Fatal("binary file router failed to listen: %v", err)
}
logger.Info("binary file router listening on port %d", conf.Grpc.Router.Binaryfiles.Port)
if err := s.Serve(lis); err != nil {
logger.Fatal("binary file router failed to serve: %v", err)
}
return s
}
/*
* 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 (
pb "antragsraum-proxy/gen/go"
"antragsraum-proxy/internal/config"
"context"
"errors"
"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"
)
type commandRouter struct {
pb.UnimplementedCommandServiceServer
}
func (s *commandRouter) GetCommand(ctx context.Context, in *pb.GrpcGetCommandRequest) (*pb.GrpcCommand, error) {
response, err := s.handleRequest(ctx, func(client pb.CommandServiceClient, ctx context.Context) (interface{}, error) {
return client.GetCommand(ctx, in)
})
return response.(*pb.GrpcCommand), err
}
func (s *commandRouter) handleRequest(ctx context.Context, handler func(pb.CommandServiceClient, context.Context) (interface{}, error)) (interface{}, error) {
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 := createCommandClient(grpcAddress[0])
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
defer connCleanUp()
return handler(client, ctx)
}
func createCommandClient(commandServerAddress string) (pb.CommandServiceClient, func() error, error) {
target := GetCommandServerUrl(commandServerAddress, conf)
conn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
logger.Error("command router failed to route: %v", err)
return nil, nil, errors.New("command router failed to route")
}
return pb.NewCommandServiceClient(conn), conn.Close, nil
}
func GetCommandServerUrl(commandServerAddress string, c config.Config) string {
return fmt.Sprintf("%v:%d", commandServerAddress, c.Grpc.Server.Port)
}
func StartCommandRouter() *grpc.Server {
s := grpc.NewServer()
pb.RegisterCommandServiceServer(s, &commandRouter{})
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.Grpc.Router.Commands.Port))
if err != nil {
logger.Fatal("command router failed to listen: %v", err)
}
logger.Info("command router listening on port %d", conf.Grpc.Router.Commands.Port)
if err := s.Serve(lis); err != nil {
logger.Fatal("command router failed to serve: %v", err)
}
return s
}
/* /*
* Copyright (C) 2023-2024 * Copyright (c) 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 * Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden - * diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz"); * Folgeversionen der EUPL ("Lizenz");
...@@ -68,53 +63,119 @@ func (s *rueckfrageRouter) SendRueckfrageAnswer(ctx context.Context, in *pb.Grpc ...@@ -68,53 +63,119 @@ func (s *rueckfrageRouter) SendRueckfrageAnswer(ctx context.Context, in *pb.Grpc
} }
func (s *rueckfrageRouter) handleRequest(ctx context.Context, handler func(pb.AntragraumServiceClient, context.Context) (interface{}, error)) (interface{}, error) { func (s *rueckfrageRouter) handleRequest(ctx context.Context, handler func(pb.AntragraumServiceClient, context.Context) (interface{}, error)) (interface{}, error) {
md, ok := metadata.FromIncomingContext(ctx) return handleRequest(ctx, createRueckfrageClient, handler)
if !ok {
return nil, status.Error(codes.InvalidArgument, "unable to retrieve metadata")
} }
grpcAddress := md.Get(GrpcAddressMetadata) func createRueckfrageClient(grpcAddress string) (pb.AntragraumServiceClient, func() error, error) {
if len(grpcAddress) == 0 { target := getGrpcServerUrl(grpcAddress, conf)
return nil, status.Error(codes.InvalidArgument, "grpc address is missing") conn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
logger.Error("rueckfrage router failed to route: %v", err)
return nil, nil, errors.New("rueckfrage router failed to route")
}
return pb.NewAntragraumServiceClient(conn), conn.Close, nil
} }
client, connCleanUp, err := createRueckfrageClient(grpcAddress[0]) type commandRouter struct {
pb.UnimplementedCommandServiceServer
}
func (s *commandRouter) GetCommand(ctx context.Context, in *pb.GrpcGetCommandRequest) (*pb.GrpcCommand, error) {
response, err := s.handleRequest(ctx, func(client pb.CommandServiceClient, ctx context.Context) (interface{}, error) {
return client.GetCommand(ctx, in)
})
return response.(*pb.GrpcCommand), err
}
func (s *commandRouter) handleRequest(ctx context.Context, handler func(pb.CommandServiceClient, context.Context) (interface{}, error)) (interface{}, error) {
return handleRequest(ctx, createCommandClient, handler)
}
func createCommandClient(grpcAddress string) (pb.CommandServiceClient, func() error, error) {
target := getGrpcServerUrl(grpcAddress, conf)
conn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) logger.Error("command router failed to route: %v", err)
return nil, nil, errors.New("command router failed to route")
} }
defer connCleanUp()
return handler(client, ctx) return pb.NewCommandServiceClient(conn), conn.Close, nil
} }
func createRueckfrageClient(rueckfrageServerAddress string) (pb.AntragraumServiceClient, func() error, error) { type binaryFileRouter struct {
target := GetRueckfrageServerUrl(rueckfrageServerAddress, conf) pb.UnimplementedBinaryFileServiceServer
}
func (s *binaryFileRouter) FindBinaryFilesMetaData(ctx context.Context, in *pb.GrpcBinaryFilesRequest) (*pb.GrpcFindFilesResponse, error) {
response, err := s.handleRequest(ctx, func(client pb.BinaryFileServiceClient, ctx context.Context) (interface{}, error) {
return client.FindBinaryFilesMetaData(ctx, in)
})
return response.(*pb.GrpcFindFilesResponse), err
}
func (s *binaryFileRouter) handleRequest(ctx context.Context, handler func(pb.BinaryFileServiceClient, context.Context) (interface{}, error)) (interface{}, error) {
return handleRequest(ctx, createBinaryFileClient, handler)
}
func createBinaryFileClient(grpcAddress string) (pb.BinaryFileServiceClient, func() error, error) {
target := getGrpcServerUrl(grpcAddress, conf)
conn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { if err != nil {
logger.Error("rueckfrage router failed to route: %v", err) logger.Error("binary file router failed to route: %v", err)
return nil, nil, errors.New("rueckfrage router failed to route") return nil, nil, errors.New("binary file router failed to route")
} }
return pb.NewAntragraumServiceClient(conn), conn.Close, nil return pb.NewBinaryFileServiceClient(conn), conn.Close, nil
}
func getGrpcServerUrl(grpcAddress string, c config.Config) string {
return fmt.Sprintf("%v:%d", grpcAddress, c.Grpc.Server.Port)
}
func handleRequest[T any](
ctx context.Context,
createClientFunc func(grpcAddress string) (T, func() error, error),
handler func(T, context.Context) (interface{}, error),
) (interface{}, error) {
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")
} }
func GetRueckfrageServerUrl(rueckfrageServerAddress string, c config.Config) string { client, connCleanUp, err := createClientFunc(grpcAddress[0])
return fmt.Sprintf("%v:%d", rueckfrageServerAddress, c.Grpc.Server.Port) if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
defer connCleanUp()
return handler(client, ctx)
} }
func StartRueckfrageRouter() *grpc.Server { func StartGrpcRouter() *grpc.Server {
s := grpc.NewServer() s := grpc.NewServer()
pb.RegisterAntragraumServiceServer(s, &rueckfrageRouter{}) pb.RegisterAntragraumServiceServer(s, &rueckfrageRouter{})
pb.RegisterCommandServiceServer(s, &commandRouter{})
pb.RegisterBinaryFileServiceServer(s, &binaryFileRouter{})
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.Grpc.Router.Rueckfragen.Port)) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.Grpc.Router.Port))
if err != nil { if err != nil {
logger.Fatal("rueckfrage router failed to listen: %v", err) logger.Fatal("gRPC router failed to listen: %v", err)
} }
logger.Info("rueckfrage router listening on port %d", conf.Grpc.Router.Rueckfragen.Port) logger.Info("gRPC router listening on port %d", conf.Grpc.Router.Port)
if err := s.Serve(lis); err != nil { if err := s.Serve(lis); err != nil {
logger.Fatal("rueckfrage router failed to serve: %v", err) logger.Fatal("gRPC router failed to serve: %v", err)
} }
return s return s
......
...@@ -27,6 +27,7 @@ package server ...@@ -27,6 +27,7 @@ package server
import ( import (
pb "antragsraum-proxy/gen/go" pb "antragsraum-proxy/gen/go"
"bytes"
"context" "context"
"fmt" "fmt"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
...@@ -35,6 +36,7 @@ import ( ...@@ -35,6 +36,7 @@ import (
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"io" "io"
"mime/multipart"
"net/http" "net/http"
) )
...@@ -67,7 +69,7 @@ func RegisterFileUploadEndpoint(mux *runtime.ServeMux) { ...@@ -67,7 +69,7 @@ func RegisterFileUploadEndpoint(mux *runtime.ServeMux) {
} }
defer file.Close() defer file.Close()
conn, err := grpc.NewClient(GetBinaryFileServerUrl(r.Header.Get(GrpcAddressHeader), conf), grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := grpc.NewClient(getGrpcServerUrl(r.Header.Get(GrpcAddressHeader), conf), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { if err != nil {
http.Error(w, "gRPC connection error", http.StatusInternalServerError) http.Error(w, "gRPC connection error", http.StatusInternalServerError)
return return
...@@ -126,6 +128,71 @@ func RegisterFileUploadEndpoint(mux *runtime.ServeMux) { ...@@ -126,6 +128,71 @@ func RegisterFileUploadEndpoint(mux *runtime.ServeMux) {
} }
} }
func RegisterGetFileEndpoint(mux *runtime.ServeMux) {
err := mux.HandlePath("POST", "/api/v1/file/content/{fileId}", func(w http.ResponseWriter, r *http.Request, vars map[string]string) {
var fileBuffer bytes.Buffer
conn, err := grpc.NewClient(getGrpcServerUrl(r.Header.Get(GrpcAddressHeader), conf), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
http.Error(w, "gRPC connection error", http.StatusInternalServerError)
return
}
defer conn.Close()
client := pb.NewBinaryFileServiceClient(conn)
req := &pb.GrpcGetBinaryFileDataRequest{FileId: vars["fileId"]}
clientStream, err := client.GetBinaryFileContent(r.Context(), req)
if err != nil {
http.Error(w, "stream creation error", http.StatusInternalServerError)
return
}
for {
resp, err := clientStream.Recv()
if err == io.EOF {
break
}
if err != nil {
http.Error(w, "Error receiving file chunks", http.StatusInternalServerError)
return
}
_, err = fileBuffer.Write(resp.FileContent)
if err != nil {
http.Error(w, "Error writing file data", http.StatusInternalServerError)
return
}
}
w.Header().Set("Content-Type", "multipart/form-data")
w.Header().Set("Content-Disposition", `attachment; filename="file"`)
w.WriteHeader(http.StatusOK)
mw := multipart.NewWriter(w)
part, err := mw.CreateFormFile("file", "file")
if err != nil {
http.Error(w, "Error creating multipart form file", http.StatusInternalServerError)
return
}
_, err = fileBuffer.WriteTo(part)
if err != nil {
http.Error(w, "Error writing file data to multipart", http.StatusInternalServerError)
return
}
err = mw.Close()
if err != nil {
http.Error(w, "Error closing multipart writer", http.StatusInternalServerError)
return
}
})
if err != nil {
logger.Fatal("Endpoint registration failed: %v", err)
}
}
func ErrorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) { func ErrorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) {
st, ok := status.FromError(err) st, ok := status.FromError(err)
if !ok { if !ok {
......
...@@ -55,19 +55,19 @@ func StartHttpGateway() *http.Server { ...@@ -55,19 +55,19 @@ func StartHttpGateway() *http.Server {
mux := runtime.NewServeMux(runtime.WithErrorHandler(ErrorHandler), runtime.WithIncomingHeaderMatcher(HeaderMatcher)) mux := runtime.NewServeMux(runtime.WithErrorHandler(ErrorHandler), runtime.WithIncomingHeaderMatcher(HeaderMatcher))
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
rueckfrageRouterUrl := fmt.Sprintf("localhost:%d", conf.Grpc.Router.Rueckfragen.Port) rueckfrageRouterUrl := fmt.Sprintf("localhost:%d", conf.Grpc.Router.Port)
err := pb.RegisterAntragraumServiceHandlerFromEndpoint(ctx, mux, rueckfrageRouterUrl, opts) err := pb.RegisterAntragraumServiceHandlerFromEndpoint(ctx, mux, rueckfrageRouterUrl, opts)
if err != nil { if err != nil {
logger.Fatal("failed to start HTTP gateway: %v", err) logger.Fatal("failed to start HTTP gateway: %v", err)
} }
commandRouterUrl := fmt.Sprintf("localhost:%d", conf.Grpc.Router.Commands.Port) commandRouterUrl := fmt.Sprintf("localhost:%d", conf.Grpc.Router.Port)
err = pb.RegisterCommandServiceHandlerFromEndpoint(ctx, mux, commandRouterUrl, opts) err = pb.RegisterCommandServiceHandlerFromEndpoint(ctx, mux, commandRouterUrl, opts)
if err != nil { if err != nil {
logger.Fatal("failed to start HTTP gateway: %v", err) logger.Fatal("failed to start HTTP gateway: %v", err)
} }
binaryFileRouterUrl := fmt.Sprintf("localhost:%d", conf.Grpc.Router.Binaryfiles.Port) binaryFileRouterUrl := fmt.Sprintf("localhost:%d", conf.Grpc.Router.Port)
err = pb.RegisterBinaryFileServiceHandlerFromEndpoint(ctx, mux, binaryFileRouterUrl, opts) err = pb.RegisterBinaryFileServiceHandlerFromEndpoint(ctx, mux, binaryFileRouterUrl, opts)
if err != nil { if err != nil {
logger.Fatal("failed to start HTTP gateway: %v", err) logger.Fatal("failed to start HTTP gateway: %v", err)
...@@ -75,6 +75,7 @@ func StartHttpGateway() *http.Server { ...@@ -75,6 +75,7 @@ func StartHttpGateway() *http.Server {
RegisterHomeEndpoint(mux) RegisterHomeEndpoint(mux)
RegisterFileUploadEndpoint(mux) RegisterFileUploadEndpoint(mux)
RegisterGetFileEndpoint(mux)
httpServer := &http.Server{ httpServer := &http.Server{
Addr: fmt.Sprintf(":%d", conf.Http.Server.Port), Addr: fmt.Sprintf(":%d", conf.Http.Server.Port),
......
...@@ -35,7 +35,7 @@ import ( ...@@ -35,7 +35,7 @@ import (
func TestStartHttpGateway(t *testing.T) { func TestStartHttpGateway(t *testing.T) {
SetUpHttpGateway() SetUpHttpGateway()
conn, err := net.DialTimeout("tcp", "localhost:8080", 2*time.Second) conn, err := net.DialTimeout("tcp", "localhost:8082", 2*time.Second)
assert.NoError(t, err) assert.NoError(t, err)
......
...@@ -74,7 +74,7 @@ func TestRequestLoggingMiddleware(t *testing.T) { ...@@ -74,7 +74,7 @@ func TestRequestLoggingMiddleware(t *testing.T) {
] ]
} }
}`) }`)
http.Post("http://localhost:8080/api/v1/rueckfrage", "application/json", bytes.NewBuffer(jsonReplyData)) http.Post("http://localhost:8082/api/v1/rueckfrage", "application/json", bytes.NewBuffer(jsonReplyData))
logOutput := buf.String() logOutput := buf.String()
assert.Contains(t, logOutput, "received request with body") assert.Contains(t, logOutput, "received request with body")
......
http: http:
server: server:
port: 8080 port: 8082
grpc: grpc:
server: server:
port: 50054 port: 50052
router: router:
rueckfragen:
port: 50051 port: 50051
commands:
port: 50052
binaryfiles:
port: 50053
logging: logging:
level: "DEBUG" level: "DEBUG"
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment