/
standaloneApi.go
107 lines (92 loc) · 2.83 KB
/
standaloneApi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package restAPI
import (
"bytes"
"fmt"
"net/http"
"time"
"github.com/Nightapes/go-rest/pkg/openapi"
"github.com/exasol/extension-manager/pkg/apiErrors"
"github.com/exasol/extension-manager/pkg/extensionController"
httpswagger "github.com/swaggo/http-swagger"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
log "github.com/sirupsen/logrus"
)
/* [impl -> dsn~rest-interface~1]. */
func setupStandaloneAPI(controller extensionController.TransactionController, addCauseToInternalServerError bool) (http.Handler, *openapi.API, error) {
api, err := CreateOpenApi()
if err != nil {
return nil, nil, err
}
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(loggerMiddleware())
r.Use(middleware.Recoverer)
err = addPublicEndpointsWithController(api, addCauseToInternalServerError, controller)
if err != nil {
return nil, nil, err
}
openApiHandler, err := api.OpenAPIHandlerFunc()
if err != nil {
return nil, nil, err
}
r.Group(func(r chi.Router) {
r.MethodFunc(http.MethodGet, "/openapi.json", openApiHandler)
r.Method(http.MethodGet, "/openapi/*", httpswagger.Handler(
httpswagger.URL("/openapi.json"),
))
})
r.Group(func(r chi.Router) {
for _, handleConfig := range api.GetHandleFunc() {
log.Tracef("Add func %s %s", handleConfig.Method, handleConfig.Path)
r.With(middleware.Timeout(60*time.Second)).Method(handleConfig.Method, handleConfig.Path, handleConfig.HandlerFunc)
}
})
return r, api, nil
}
func CreateOpenApi() (*openapi.API, error) {
api := openapi.NewOpenAPI()
api.Title = "Exasol Extension Manager REST-API"
api.Description = "Managed extensions and instances of extensions"
api.Version = "dev"
if err := api.WithBasicAuth(BasicAuth); err != nil {
return nil, err
}
if err := api.WithBearerAuth(BearerAuth, "bearer", "JWT"); err != nil {
return nil, err
}
api.DefaultResponse(&openapi.MethodResponse{
Description: "Default error",
Value: &apiErrors.APIError{
Status: 500,
Message: "Something went wrong.",
RequestID: "Rn3x8gcEInnHt205B4c7QZ",
OriginalError: nil,
},
})
return api, nil
}
func loggerMiddleware() func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
buf := &bytes.Buffer{}
logger := GetLogger(r.Context())
t1 := time.Now()
defer func() {
scheme := "http"
if r.TLS != nil {
scheme = "https"
}
fmt.Fprintf(buf, "\"%s %s://%s%s %s\" ", r.Method, scheme, r.Host, r.RequestURI, r.Proto)
buf.WriteString("from ")
buf.WriteString(r.RemoteAddr)
buf.WriteString(" - ")
fmt.Fprintf(buf, "%d %dB in %s", ww.Status(), ww.BytesWritten(), time.Since(t1))
logger.Infof(buf.String())
}()
next.ServeHTTP(ww, r)
}
return http.HandlerFunc(fn)
}
}