From eca6672746ae4bb108d28e31c7cff9e1572bdf77 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Mon, 18 Sep 2023 22:04:54 -0400 Subject: [PATCH 1/5] Update golang et alpine --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 23820d5..67e6af6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.20.2 as build +FROM golang:1.21.1 as build LABEL author="vlbeaudoin" @@ -17,7 +17,7 @@ RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o bottin . # Alpine -FROM alpine:latest +FROM alpine:3.18 WORKDIR /app From 025f9d74cecd5b54ee136503e8fc567a37685686 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Mon, 18 Sep 2023 22:05:30 -0400 Subject: [PATCH 2/5] =?UTF-8?q?Migrer=20responses=20=C3=A0=20voki/response?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- responses/health.go | 4 +++- responses/post.go | 6 ++++-- responses/root.go | 15 --------------- 3 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 responses/root.go diff --git a/responses/health.go b/responses/health.go index 854279d..1edf34a 100644 --- a/responses/health.go +++ b/responses/health.go @@ -1,5 +1,7 @@ package responses +import "codeberg.org/vlbeaudoin/voki/response" + type GetHealthResponse struct { - Response + response.ResponseWithError } diff --git a/responses/post.go b/responses/post.go index 91eef96..cfb03af 100644 --- a/responses/post.go +++ b/responses/post.go @@ -1,14 +1,16 @@ package responses +import "codeberg.org/vlbeaudoin/voki/response" + type PostMembresResponse struct { - Response + response.ResponseWithError Data struct { MembresInserted int64 } } type PostProgrammesResponse struct { - Response + response.ResponseWithError Data struct { ProgrammesInserted int64 } diff --git a/responses/root.go b/responses/root.go deleted file mode 100644 index 0f0bcce..0000000 --- a/responses/root.go +++ /dev/null @@ -1,15 +0,0 @@ -package responses - -type Response struct { - StatusCode int - Message string - Error string -} - -type Responder interface { - Respond() Responder -} - -func (r Response) Respond() Responder { - return r -} From 6dff76d871347506da897aaa7ad100768871a051 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Mon, 18 Sep 2023 22:06:26 -0400 Subject: [PATCH 3/5] Move APIClient to voki --- data/apiclient.go | 84 +++++------------------------------------------ 1 file changed, 8 insertions(+), 76 deletions(-) diff --git a/data/apiclient.go b/data/apiclient.go index 3319d72..973326a 100644 --- a/data/apiclient.go +++ b/data/apiclient.go @@ -1,100 +1,43 @@ package data import ( - "encoding/json" "errors" "fmt" - "io" - "io/ioutil" "net/http" + "codeberg.org/vlbeaudoin/voki" "git.agecem.com/agecem/bottin/v5/models" "git.agecem.com/agecem/bottin/v5/responses" "github.com/spf13/viper" ) type ApiClient struct { - Key string - Host string - Port int - Protocol string + Voki *voki.Voki } -func NewApiClientFromViper() *ApiClient { +func NewApiClientFromViper(client *http.Client) *ApiClient { apiClientKey := viper.GetString("web.api.key") apiClientHost := viper.GetString("web.api.host") apiClientProtocol := viper.GetString("web.api.protocol") apiClientPort := viper.GetInt("web.api.port") - return NewApiClient(apiClientKey, apiClientHost, apiClientProtocol, apiClientPort) + return NewApiClient(client, apiClientKey, apiClientHost, apiClientProtocol, apiClientPort) } -func NewApiClient(key, host, protocol string, port int) *ApiClient { +func NewApiClient(client *http.Client, key, host, protocol string, port int) *ApiClient { return &ApiClient{ - Key: key, - Host: host, - Port: port, - Protocol: protocol, + Voki: voki.New(client, host, key, port, protocol), } } -func (a *ApiClient) Call(method, route string, requestBody io.Reader, useKey bool) (*http.Response, error) { - var response *http.Response - - endpoint := fmt.Sprintf("%s://%s:%d%s", - a.Protocol, a.Host, a.Port, route, - ) - - // Create client - client := &http.Client{} - - // Create request - request, err := http.NewRequest(method, endpoint, requestBody) - if err != nil { - return response, err - } - - if useKey { - if a.Key == "" { - return response, fmt.Errorf("Call to API required a key but none was provided. See --help for instructions on providing an API key.") - } - - request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Key)) - } - - if requestBody != nil { - request.Header.Add("Content-Type", "application/json") - } - - // Fetch Request - response, err = client.Do(request) - if err != nil { - return response, err - } - - return response, nil -} - // GetHealth allows checking for API server health func (a *ApiClient) GetHealth() (string, error) { var getHealthResponse responses.GetHealthResponse - - response, err := a.Call(http.MethodGet, "/v5/health", nil, true) + err := a.Voki.Unmarshal(http.MethodGet, "/v5/health", nil, true, &getHealthResponse) if err != nil { return getHealthResponse.Message, err } - defer response.Body.Close() - - body, err := ioutil.ReadAll(response.Body) - if err != nil { - return getHealthResponse.Message, err - } - - if err := json.Unmarshal(body, &getHealthResponse); err != nil { - return getHealthResponse.Message, err - } - if getHealthResponse.Message == "" { return getHealthResponse.Message, errors.New("Could not confirm that API server is up, no response message") } @@ -114,22 +57,11 @@ func (a *ApiClient) GetMembre(membreID string) (models.Membre, error) { return getMembreResponse.Data.Membre, errors.New("Veuillez fournir un numéro étudiant à rechercher") } - response, err := a.Call(http.MethodGet, fmt.Sprintf("/v5/membres/%s", membreID), nil, true) + err := a.Voki.Unmarshal(http.MethodGet, fmt.Sprintf("/v5/membres/%s", membreID), nil, true, getMembreResponse) if err != nil { return getMembreResponse.Data.Membre, err } - defer response.Body.Close() - - body, err := ioutil.ReadAll(response.Body) - if err != nil { - return getMembreResponse.Data.Membre, err - } - - if err := json.Unmarshal(body, &getMembreResponse); err != nil { - return getMembreResponse.Data.Membre, err - } - if getMembreResponse.Data.Membre == *new(models.Membre) { return getMembreResponse.Data.Membre, fmt.Errorf("Ce numéro étudiant ne correspond à aucunE membre") } From ad83bc081a596e029110e91a445d5a5ae310d238 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Mon, 18 Sep 2023 22:07:02 -0400 Subject: [PATCH 4/5] Migrate webclient to voki and add webhandlers.Handler --- cmd/web.go | 12 +++++++++--- web/webhandlers/handlers.go | 11 +++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cmd/web.go b/cmd/web.go index d09477c..a944d30 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -7,6 +7,7 @@ import ( "html/template" "io" "log" + "net/http" "git.agecem.com/agecem/bottin/v5/data" "git.agecem.com/agecem/bottin/v5/web" @@ -53,7 +54,10 @@ var webCmd = &cobra.Command{ // Ping API server - apiClient := data.NewApiClient(webApiKey, webApiHost, webApiProtocol, webApiPort) + client := http.DefaultClient + defer client.CloseIdleConnections() + + apiClient := data.NewApiClient(client, webApiKey, webApiHost, webApiProtocol, webApiPort) pingResult, err := apiClient.GetHealth() if err != nil { @@ -84,8 +88,10 @@ var webCmd = &cobra.Command{ // Routes - e.GET("/", webhandlers.GetIndex) - e.GET("/membre/", webhandlers.GetMembre) + handler := webhandlers.Handler{APIClient: apiClient} + + e.GET("/", handler.GetIndex) + e.GET("/membre/", handler.GetMembre) // Execution diff --git a/web/webhandlers/handlers.go b/web/webhandlers/handlers.go index dce8399..96fba50 100644 --- a/web/webhandlers/handlers.go +++ b/web/webhandlers/handlers.go @@ -8,16 +8,19 @@ import ( "github.com/labstack/echo/v4" ) -func GetIndex(c echo.Context) error { +type Handler struct { + APIClient *data.ApiClient +} + +func (h *Handler) GetIndex(c echo.Context) error { return c.Render(http.StatusOK, "index-html", nil) } -func GetMembre(c echo.Context) error { - apiClient := data.NewApiClientFromViper() +func (h *Handler) GetMembre(c echo.Context) error { membreID := c.QueryParam("membre_id") - membre, err := apiClient.GetMembre(membreID) + membre, err := h.APIClient.GetMembre(membreID) if err != nil { return c.Render(http.StatusBadRequest, "index-html", struct { Result string From b36d36d669a799ed8542289274362e050d005d8d Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Mon, 18 Sep 2023 22:07:41 -0400 Subject: [PATCH 5/5] Update go.mod and go.sum --- go.mod | 5 ++++- go.sum | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5bd54b0..bb11ea5 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,11 @@ module git.agecem.com/agecem/bottin/v5 -go 1.20 +go 1.21.0 + +toolchain go1.21.1 require ( + codeberg.org/vlbeaudoin/voki v1.3.1 github.com/gocarina/gocsv v0.0.0-20230616125104-99d496ca653d github.com/jackc/pgx v3.6.2+incompatible github.com/jmoiron/sqlx v1.3.5 diff --git a/go.sum b/go.sum index 7fa5e1c..153feae 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +codeberg.org/vlbeaudoin/voki v1.3.1 h1:TxJj3qmOys0Pbq1dPKnOEXMXKqQLQqrBYd4QqiWWXcw= +codeberg.org/vlbeaudoin/voki v1.3.1/go.mod h1:5XTLx/KiW/OfiupF3o7PAAAU/UhsPdKSrVMmtHbmkPI= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -59,6 +61,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -109,6 +112,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -147,9 +151,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= @@ -179,6 +185,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=