diff --git a/api/proto/information.model.proto b/api/proto/information.model.proto index 80fc9079b7fe632de470a4b313e3f60e5035e5b1..7ad0f5fdd05ac472faeabf5832e642a6018a8ba0 100644 --- a/api/proto/information.model.proto +++ b/api/proto/information.model.proto @@ -1,3 +1,27 @@ +/* + * 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 + * 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. + */ + syntax = "proto3"; package de.ozgcloud.info; diff --git a/api/proto/information.proto b/api/proto/information.proto index bd78bbc5e15ec2ab6bb3c411d9e92ad5103d6f1d..b77d4c3e0d2808dd058f3e47634dd5670518b778 100644 --- a/api/proto/information.proto +++ b/api/proto/information.proto @@ -1,3 +1,27 @@ +/* + * 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 + * 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. + */ + syntax = "proto3"; package de.ozgcloud.info; diff --git a/buf.gen.yaml b/buf.gen.yaml index e18132f572789797723497bed5cd8d141848b99a..21d5c631f37d8df3cddb48450fd1a576b977b7cd 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -16,5 +16,7 @@ plugins: - plugin: openapiv2 out: gen/openapiv2 opt: + - allow_merge=true + - merge_file_name=openapiv2.json - grpc_api_configuration=api/gateway-config.yml - openapi_configuration=api/openapi-config.yml \ No newline at end of file diff --git a/info-manager-proxy/main.go b/info-manager-proxy/main.go deleted file mode 100644 index 14bf7dd754fdb0b114797fb03c78818e7bbf09ef..0000000000000000000000000000000000000000 --- a/info-manager-proxy/main.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "info-manager-proxy/internal/config" - "info-manager-proxy/internal/mock" - "info-manager-proxy/internal/server" -) - -var version = "v1.0.0-beta.1" - -func main() { - conf := config.LoadConfig() - - if conf.Grpc.Mock { - go mock.StartGrpcServer() - } - - server.StartHttpGateway(conf) -} diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 38cd14245895c0ba67c51af3f41cd7d3faf899f9..b423ad6b36d8343e001df094c668fac3bd42b16b 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -37,7 +37,7 @@ func TestLoadConfig(t *testing.T) { config := LoadConfig() expectedConfig := Config{} - expectedConfig.Server.Port = 8080 + expectedConfig.Server.Port = 8082 expectedConfig.Grpc.Url = "localhost:50051" expectedConfig.Grpc.Mock = false expectedConfig.Logging.Level = "DEBUG" diff --git a/internal/config/testdata/test_config.yml b/internal/config/testdata/test_config.yml index ea8925db9cb5af5c351a1af92d6fb7f878de4359..3138586b8c8b7858dda264c704619e6e712c3d23 100644 --- a/internal/config/testdata/test_config.yml +++ b/internal/config/testdata/test_config.yml @@ -1,5 +1,5 @@ server: - port: 8080 + port: 8082 grpc: url: "localhost:50051" logging: diff --git a/internal/logging/logger_test.go b/internal/logging/logger_test.go index 11eff2f85f749fc9bcd884ee9d57c7a9b13fe12d..e760453a43169d8578a1679e3537de0bb07f9918 100644 --- a/internal/logging/logger_test.go +++ b/internal/logging/logger_test.go @@ -28,21 +28,20 @@ package logging import ( "bytes" "github.com/stretchr/testify/assert" - "log" "testing" ) -func setUpLogger(t *testing.T, level string, msg string) *bytes.Buffer { +func logMessage(level string, msg string) *bytes.Buffer { logger := GetLogger() var buf bytes.Buffer logger.BaseLogger.SetOutput(&buf) - originalFlags := log.Flags() - t.Cleanup(func() { - log.SetOutput(nil) - log.SetFlags(originalFlags) - }) + originalFlags := logger.BaseLogger.Flags() + defer func() { + logger.BaseLogger.SetOutput(nil) + logger.BaseLogger.SetFlags(originalFlags) + }() if level == LogLevelError { logger.Error(msg) @@ -58,25 +57,25 @@ func setUpLogger(t *testing.T, level string, msg string) *bytes.Buffer { } func TestError(t *testing.T) { - buf := setUpLogger(t, LogLevelError, "test error") + buf := logMessage(LogLevelError, "test error") logOutput := buf.String() assert.Contains(t, logOutput, "ERROR: test error") } func TestWarning(t *testing.T) { - buf := setUpLogger(t, LogLevelWarning, "test warning") + buf := logMessage(LogLevelWarning, "test warning") logOutput := buf.String() assert.Contains(t, logOutput, "WARNING: test warning") } func TestInfo(t *testing.T) { - buf := setUpLogger(t, LogLevelInfo, "test info") + buf := logMessage(LogLevelInfo, "test info") logOutput := buf.String() assert.Contains(t, logOutput, "INFO: test info") } func TestDebug(t *testing.T) { - buf := setUpLogger(t, LogLevelDebug, "test debug") + buf := logMessage(LogLevelDebug, "test debug") logOutput := buf.String() assert.Empty(t, logOutput) } diff --git a/internal/logging/testdata/test_config.yml b/internal/logging/testdata/test_config.yml index 6021893b2e1982f4f8d4215707fa6300e2cd6e8e..6f5d5d32e43399a0dc52da8c6b66ee0128854cc4 100644 --- a/internal/logging/testdata/test_config.yml +++ b/internal/logging/testdata/test_config.yml @@ -1,5 +1,5 @@ server: - port: 8080 + port: 8082 grpc: url: "localhost:50051" logging: diff --git a/internal/mock/globals.go b/internal/mock/globals.go index 04a1d31ce771922c8e9270ea9eedcf0c68df7d34..024c66e9075e1c6f4df7922d5239f38447f16485 100644 --- a/internal/mock/globals.go +++ b/internal/mock/globals.go @@ -1,3 +1,28 @@ +/* + * 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 mock import "info-manager-proxy/internal/logging" diff --git a/internal/mock/grpc_server.go b/internal/mock/grpc_server.go index e4d5e9152b49e01fcfeae91ca511f4d42e1eb0cc..445dc425bd399173cc3af16787db157dd9053eb0 100644 --- a/internal/mock/grpc_server.go +++ b/internal/mock/grpc_server.go @@ -1,12 +1,37 @@ +/* + * 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 mock import ( "context" - pb "info-manager-proxy/gen/go" "fmt" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + pb "info-manager-proxy/gen/go" "net" ) @@ -16,21 +41,21 @@ type server struct { pb.UnimplementedInformationServiceServer } -func (s *server) GetInformation(ctx context.Context, in *pb.GrpcInformationRequest) (*pb.GrpcInformationResponse, error) { - if in.PostfachId == "" { - return nil, status.Error(codes.InvalidArgument, "PostfachId is missing") - } - - if in.PostfachId == "service_unavailable" { - return nil, status.Error(codes.Unavailable, "Unavailable") - } else if in.PostfachId == "internal_server_error" { - return nil, status.Error(codes.Internal, "Error") - } - - return &pb.GrpcInformationResponse{}, nil +func (s *server) GetInformation(_ context.Context, in *pb.GrpcInformationRequest) (*pb.GrpcInformationResponse, error) { + if in.PostfachId == "" { + return nil, status.Error(codes.InvalidArgument, "PostfachId is missing") } -func (s *server) GetInformationById(ctx context.Context, in *pb.GrpcInformationByIdRequest) (*pb.GrpcInformationByIdResponse, error) { + if in.PostfachId == "service_unavailable" { + return nil, status.Error(codes.Unavailable, "Unavailable") + } else if in.PostfachId == "internal_server_error" { + return nil, status.Error(codes.Internal, "Error") + } + + return &pb.GrpcInformationResponse{}, nil +} + +func (s *server) GetInformationById(_ context.Context, in *pb.GrpcInformationByIdRequest) (*pb.GrpcInformationByIdResponse, error) { if in.Id == "" { return nil, status.Error(codes.InvalidArgument, "Id is missing") } diff --git a/internal/mock/grpc_server_test.go b/internal/mock/grpc_server_test.go index 5f1312bcd00c025c12f670080606740088604759..25204b6f79bd1754ff8bed21a23437b926360393 100644 --- a/internal/mock/grpc_server_test.go +++ b/internal/mock/grpc_server_test.go @@ -1,16 +1,53 @@ +/* + * 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 mock import ( "context" - pb "info-manager-proxy/gen/go" "fmt" "github.com/stretchr/testify/assert" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + pb "info-manager-proxy/gen/go" + "net" "testing" + "time" ) func TestStartGrpcServer(t *testing.T) { + t.Run("should start gRPC server", func(t *testing.T) { + SetUpGrpcServer() + + conn, err := net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", GrpcMockPort), 2*time.Second) + + assert.NoError(t, err) + + conn.Close() + }) + setUpGrpcEnv := func() (pb.InformationServiceClient, func()) { SetUpGrpcServer() @@ -25,43 +62,47 @@ func TestStartGrpcServer(t *testing.T) { return client, cleanup } - t.Run("should have no error on get information with valid postfachId", func(t *testing.T) { - client, cleanUp := setUpGrpcEnv() - defer cleanUp() + t.Run("TestGetInformation", func(t *testing.T) { + t.Run("should have no error on get information with valid postfachId", func(t *testing.T) { + client, cleanUp := setUpGrpcEnv() + defer cleanUp() - resp, err := client.GetInformation(context.Background(), &pb.GrpcInformationRequest{PostfachId: "testPostfachId"}) + resp, err := client.GetInformation(context.Background(), &pb.GrpcInformationRequest{PostfachId: "testPostfachId"}) - assert.NoError(t, err) - assert.NotNil(t, resp) - }) + assert.NoError(t, err) + assert.NotNil(t, resp) + }) - t.Run("should have error on get information with empty postfachId", func(t *testing.T) { - client, cleanUp := setUpGrpcEnv() - defer cleanUp() + t.Run("should have error on get information with empty postfachId", func(t *testing.T) { + client, cleanUp := setUpGrpcEnv() + defer cleanUp() - resp, err := client.GetInformation(context.Background(), &pb.GrpcInformationRequest{PostfachId: ""}) + resp, err := client.GetInformation(context.Background(), &pb.GrpcInformationRequest{PostfachId: ""}) - assert.Error(t, err) - assert.Nil(t, resp) + assert.Error(t, err) + assert.Nil(t, resp) + }) }) - t.Run("should have no error on get information by id", func(t *testing.T) { - client, cleanUp := setUpGrpcEnv() - defer cleanUp() + t.Run("TestGetInformationById", func(t *testing.T) { + t.Run("should have no error on get information by id", func(t *testing.T) { + client, cleanUp := setUpGrpcEnv() + defer cleanUp() - resp, err := client.GetInformationById(context.Background(), &pb.GrpcInformationByIdRequest{Id: "testId"}) + resp, err := client.GetInformationById(context.Background(), &pb.GrpcInformationByIdRequest{Id: "testId"}) - assert.NoError(t, err) - assert.NotNil(t, resp) - }) + assert.NoError(t, err) + assert.NotNil(t, resp) + }) - t.Run("should have error on get information by id with empty id", func(t *testing.T) { - client, cleanUp := setUpGrpcEnv() - defer cleanUp() + t.Run("should have error on get information by id with empty id", func(t *testing.T) { + client, cleanUp := setUpGrpcEnv() + defer cleanUp() - resp, err := client.GetInformationById(context.Background(), &pb.GrpcInformationByIdRequest{Id: ""}) + resp, err := client.GetInformationById(context.Background(), &pb.GrpcInformationByIdRequest{Id: ""}) - assert.Error(t, err) - assert.Nil(t, resp) + assert.Error(t, err) + assert.Nil(t, resp) + }) }) -} \ No newline at end of file +} diff --git a/internal/mock/test_setup.go b/internal/mock/test_setup.go index 7ed07c6aabc3068f6cbb0710357b1bcde89e3985..24fe3fc1cd864e14338fb9ca00f60aa24dc73492 100644 --- a/internal/mock/test_setup.go +++ b/internal/mock/test_setup.go @@ -1,3 +1,28 @@ +/* + * 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 mock import ( diff --git a/internal/mock/testdata/test_config.yml b/internal/mock/testdata/test_config.yml index ea8925db9cb5af5c351a1af92d6fb7f878de4359..3138586b8c8b7858dda264c704619e6e712c3d23 100644 --- a/internal/mock/testdata/test_config.yml +++ b/internal/mock/testdata/test_config.yml @@ -1,5 +1,5 @@ server: - port: 8080 + port: 8082 grpc: url: "localhost:50051" logging: diff --git a/internal/server/globals.go b/internal/server/globals.go index c07fe8addab19f2d50f8c66e9d1f440475424d8f..eaa39597f85aae40529aa400ae55d7618f580e43 100644 --- a/internal/server/globals.go +++ b/internal/server/globals.go @@ -1,3 +1,28 @@ +/* + * 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 "info-manager-proxy/internal/logging" diff --git a/internal/server/handler.go b/internal/server/handler.go index 3d22eb8fc72bcd32d2e28f676fb07f87aeafdd13..5b79e4cf4f0954eda755ec6c515dc626179d0644 100644 --- a/internal/server/handler.go +++ b/internal/server/handler.go @@ -29,8 +29,11 @@ import ( "context" "fmt" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" + pb "info-manager-proxy/gen/go" "net/http" ) @@ -49,6 +52,14 @@ func RegisterHomeEndpoint(mux *runtime.ServeMux) { } } +func RegisterInformationEndpoints(ctx context.Context, mux *runtime.ServeMux, grpcUrl string) { + opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} + err := pb.RegisterInformationServiceHandlerFromEndpoint(ctx, mux, grpcUrl, opts) + if err != nil { + logger.Fatal("failed to register information endpoints: %v", err) + } +} + func ErrorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) { st, ok := status.FromError(err) if !ok { diff --git a/internal/server/handler_test.go b/internal/server/handler_test.go index 0ae84cce5bb076b3bc40dde058dada58e12389aa..a4eb1aad47ee74040ec024505a45709f3e1d49d4 100644 --- a/internal/server/handler_test.go +++ b/internal/server/handler_test.go @@ -26,10 +26,9 @@ package server import ( - "bytes" - "info-manager-proxy/internal/mock" "fmt" "github.com/stretchr/testify/assert" + "info-manager-proxy/internal/mock" "net/http" "testing" ) @@ -37,38 +36,54 @@ import ( func TestRegisterHomeEndpoint(t *testing.T) { SetUpHttpGateway() - resp, err := http.Get("http://localhost:8080/") + resp, err := http.Get("http://localhost:8082/") assert.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) } +func TestRegisterInformationEndpoints(t *testing.T) { + t.Run("should get information", func(t *testing.T) { + mock.SetUpGrpcServer() + SetUpHttpGateway() + + resp, err := http.Get("http://localhost:8082/api/v1/informations/testPostfachId") + + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + }) + + t.Run("should get information by id", func(t *testing.T) { + mock.SetUpGrpcServer() + SetUpHttpGateway() + + resp, err := http.Get("http://localhost:8082/api/v1/information/testId") + + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + }) +} + func TestErrorHandler(t *testing.T) { - assertErroneousRequest := func(jsonData []byte, expectedStatusCode int) { + assertErroneousRequest := func(postfachId string, expectedStatusCode int) { mock.SetUpGrpcServer() SetUpHttpGateway() - resp, err := http.Post(fmt.Sprintf("http://localhost:8080%v", RegisterInformationUrlPath), "application/json", bytes.NewBuffer(jsonData)) + resp, err := http.Get(fmt.Sprintf("http://localhost:8082/api/v1/informations/%v", postfachId)) assert.NoError(t, err) assert.Equal(t, expectedStatusCode, resp.StatusCode) } t.Run("should have bad request error", func(t *testing.T) { - jsonData := []byte(`{}`) - - assertErroneousRequest(jsonData, http.StatusBadRequest) + assertErroneousRequest("", http.StatusBadRequest) }) t.Run("should have unavailable error", func(t *testing.T) { - jsonData := []byte(`{"postfachId": "service_unavailable"}`) - - assertErroneousRequest(jsonData, http.StatusServiceUnavailable) + assertErroneousRequest("service_unavailable", http.StatusServiceUnavailable) }) t.Run("should have internal server error", func(t *testing.T) { - jsonData := []byte(`{"postfachId": "internal_server_error"}`) - - assertErroneousRequest(jsonData, http.StatusInternalServerError) + assertErroneousRequest("internal_server_error", http.StatusInternalServerError) }) } diff --git a/internal/server/http_gateway.go b/internal/server/http_gateway.go index d7919b83ece76829f4bcc47a6adb5c80a940c2cb..bcbbf998025a7b88da00f85f5442359bc6ea6f6c 100644 --- a/internal/server/http_gateway.go +++ b/internal/server/http_gateway.go @@ -27,16 +27,12 @@ package server import ( "context" + "fmt" "info-manager-proxy/internal/config" "info-manager-proxy/internal/mock" - "fmt" - "google.golang.org/grpc/credentials/insecure" "net/http" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - "google.golang.org/grpc" - - pb "info-manager-proxy/gen/go" ) func StartHttpGateway(conf config.Config) *http.Server { @@ -44,19 +40,14 @@ func StartHttpGateway(conf config.Config) *http.Server { ctx, cancel := context.WithCancel(ctx) defer cancel() - grpcEndpoint := conf.Grpc.Url - if conf.Grpc.Mock { - grpcEndpoint = fmt.Sprintf("localhost:%d", mock.GrpcMockPort) - } - mux := runtime.NewServeMux(runtime.WithErrorHandler(ErrorHandler)) - opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} - err := pb.RegisterInformationServiceHandlerFromEndpoint(ctx, mux, grpcEndpoint, opts) - if err != nil { - logger.Fatal("failed to start HTTP gateway: %v", err) + grpcUrl := conf.Grpc.Url + if conf.Grpc.Mock { + grpcUrl = fmt.Sprintf("localhost:%d", mock.GrpcMockPort) } RegisterHomeEndpoint(mux) + RegisterInformationEndpoints(ctx, mux, grpcUrl) httpServer := &http.Server{ Addr: fmt.Sprintf(":%d", conf.Server.Port), diff --git a/internal/server/http_gateway_test.go b/internal/server/http_gateway_test.go index 68d875c04d4554e09d83eba7145506d069fcf68e..aff24e8a0ef64ae3da6c3bfb051d9364ffd74f21 100644 --- a/internal/server/http_gateway_test.go +++ b/internal/server/http_gateway_test.go @@ -26,21 +26,18 @@ package server import ( - "bytes" - "info-manager-proxy/internal/mock" - "fmt" "github.com/stretchr/testify/assert" - "net/http" + "net" "testing" + "time" ) func TestStartHttpGateway(t *testing.T) { - mock.SetUpGrpcServer() SetUpHttpGateway() - jsonData := []byte(`{"postfachId": "testPostfachId"}}`) - resp, err := http.Post(fmt.Sprintf("http://localhost:8080%v", RegisterInformationUrlPath), "application/json", bytes.NewBuffer(jsonData)) + conn, err := net.DialTimeout("tcp", "localhost:8082", 2*time.Second) assert.NoError(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) + + conn.Close() } diff --git a/internal/server/middleware.go b/internal/server/middleware.go index 42aa86a1e203e1a929126b866c0f5f893e3b9a55..41710750de6006fed161507fd8ba65846ef1601b 100644 --- a/internal/server/middleware.go +++ b/internal/server/middleware.go @@ -32,7 +32,7 @@ import ( "net/http" ) -const RegisterInformationUrlPath = "/api/information" +const HomeUrlPath = "/" type logResponseWriter struct { http.ResponseWriter @@ -46,28 +46,28 @@ func (rsp *logResponseWriter) WriteHeader(statusCode int) { func RequestLoggingMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path != RegisterInformationUrlPath { + if r.URL.Path == HomeUrlPath { h.ServeHTTP(w, r) return } body, err := io.ReadAll(r.Body) if err != nil { - logger.Error("failed to read request body: %v", err) + logger.Error("failed to read %v request body for %v: %v", r.Method, r.URL.Path, err) http.Error(w, fmt.Sprintf("failed to read request body: %v", err), http.StatusBadRequest) return } r.Body = io.NopCloser(bytes.NewReader(body)) - logger.Debug("received request with body: %v", string(body)) + logger.Debug("received %v request for %v with body: %v", r.Method, r.URL.Path, string(body)) lw := &logResponseWriter{w, http.StatusOK} h.ServeHTTP(lw, r) if lw.statusCode == http.StatusOK { - logger.Debug("successfully handled request with body: %v", string(body)) + logger.Debug("successfully handled %v request for %v with body: %v", r.Method, r.URL.Path, string(body)) } else { - logger.Error("failed handling request with body: %v, status code: %d", string(body), lw.statusCode) + logger.Error("failed handling %v request for %v with body: %v, status code: %d", r.Method, r.URL.Path, string(body), lw.statusCode) } }) } diff --git a/internal/server/middleware_test.go b/internal/server/middleware_test.go index 7755e84fe80d3f0ec5bfa07b97a84e0b64d821f6..0a304adc5bce634cccef8490507a353e9c3603e2 100644 --- a/internal/server/middleware_test.go +++ b/internal/server/middleware_test.go @@ -27,31 +27,49 @@ package server import ( "bytes" - "info-manager-proxy/internal/mock" - "fmt" "github.com/stretchr/testify/assert" - "log" + "info-manager-proxy/internal/mock" "net/http" "testing" ) func TestRequestLoggingMiddleware(t *testing.T) { - mock.SetUpGrpcServer() - SetUpHttpGateway() + t.Run("should log request", func(t *testing.T) { + mock.SetUpGrpcServer() + SetUpHttpGateway() + + var buf bytes.Buffer + logger.BaseLogger.SetOutput(&buf) + + originalFlags := logger.BaseLogger.Flags() + defer func() { + logger.BaseLogger.SetOutput(nil) + logger.BaseLogger.SetFlags(originalFlags) + }() + + http.Get("http://localhost:8082/api/v1/information/testId") + + logOutput := buf.String() + assert.Contains(t, logOutput, "received GET request for /api/v1/information/testId with body") + assert.Contains(t, logOutput, "successfully handled GET request for /api/v1/information/testId with body") + }) + + t.Run("should not log request", func(t *testing.T) { + mock.SetUpGrpcServer() + SetUpHttpGateway() - var buf bytes.Buffer - logger.BaseLogger.SetOutput(&buf) + var buf bytes.Buffer + logger.BaseLogger.SetOutput(&buf) - originalFlags := log.Flags() - defer func() { - log.SetOutput(nil) - log.SetFlags(originalFlags) - }() + originalFlags := logger.BaseLogger.Flags() + defer func() { + logger.BaseLogger.SetOutput(nil) + logger.BaseLogger.SetFlags(originalFlags) + }() - jsonData := []byte(`{"postfachId": "testPostfachId"}`) - http.Post(fmt.Sprintf("http://localhost:8080%v", RegisterInformationUrlPath), "application/json", bytes.NewBuffer(jsonData)) + http.Get("http://localhost:8082/") - logOutput := buf.String() - assert.Contains(t, logOutput, "received request with body: {\"postfachId\": \"testPostfachId\"}") - assert.Contains(t, logOutput, "successfully handled request with body: {\"postfachId\": \"testPostfachId\"}") + logOutput := buf.String() + assert.Empty(t, logOutput) + }) } diff --git a/internal/server/testdata/test_config.yml b/internal/server/testdata/test_config.yml index 6235966c8828f67d39820aeb96b70781ca9300f7..ab046e21279584ca07ff098edcf604f39c0b51a4 100644 --- a/internal/server/testdata/test_config.yml +++ b/internal/server/testdata/test_config.yml @@ -1,5 +1,5 @@ server: - port: 8080 + port: 8082 grpc: mock: true logging: