From bcf48252a2f4f3caeca60d4967d81b44c7157449 Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Wed, 25 Sep 2024 07:21:33 +0200 Subject: [PATCH] OZG-6751 Code cleanup --- api/proto/information.model.proto | 24 ++++++ api/proto/information.proto | 24 ++++++ buf.gen.yaml | 2 + info-manager-proxy/main.go | 19 ----- internal/config/config_test.go | 2 +- internal/config/testdata/test_config.yml | 2 +- internal/logging/logger_test.go | 21 +++-- internal/logging/testdata/test_config.yml | 2 +- internal/mock/globals.go | 25 ++++++ internal/mock/grpc_server.go | 53 +++++++++---- internal/mock/grpc_server_test.go | 97 ++++++++++++++++------- internal/mock/test_setup.go | 25 ++++++ internal/mock/testdata/test_config.yml | 2 +- internal/server/globals.go | 25 ++++++ internal/server/handler.go | 11 +++ internal/server/handler_test.go | 43 ++++++---- internal/server/http_gateway.go | 19 ++--- internal/server/http_gateway_test.go | 13 ++- internal/server/middleware.go | 12 +-- internal/server/middleware_test.go | 52 ++++++++---- internal/server/testdata/test_config.yml | 2 +- 21 files changed, 339 insertions(+), 136 deletions(-) delete mode 100644 info-manager-proxy/main.go diff --git a/api/proto/information.model.proto b/api/proto/information.model.proto index 80fc907..7ad0f5f 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 bd78bbc..b77d4c3 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 e18132f..21d5c63 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 14bf7dd..0000000 --- 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 38cd142..b423ad6 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 ea8925d..3138586 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 11eff2f..e760453 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 6021893..6f5d5d3 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 04a1d31..024c66e 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 e4d5e91..445dc42 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 5f1312b..25204b6 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 7ed07c6..24fe3fc 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 ea8925d..3138586 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 c07fe8a..eaa3959 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 3d22eb8..5b79e4c 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 0ae84cc..a4eb1aa 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 d7919b8..bcbbf99 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 68d875c..aff24e8 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 42aa86a..4171075 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 7755e84..0a304ad 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 6235966..ab046e2 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: -- GitLab