-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.go
384 lines (349 loc) · 11.3 KB
/
functions.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
package api
import (
"context"
"crypto/md5"
"fmt"
"log"
"net/http"
"net/http/httptest"
"reflect"
"time"
"github.com/jgolang/api/core"
"go.opentelemetry.io/otel/trace"
)
// PrintError wrapper function.
var PrintError func(...interface{}) = log.Print
// Print wrapper function.
var Print func(string, ...interface{}) = log.Printf
// Fatal wrapper function.
var Fatal func(...interface{}) = log.Fatal
// GetHeaderValueString gets header value as string.
func GetHeaderValueString(key string, r *http.Request) (string, Response) {
value, err := api.GetHeaderValueString(key, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting header value!",
Message: fmt.Sprintf("The %v key header has not been obtained", key),
}
}
return value, nil
}
// GetHeaderValueInt gets header value as integer.
func GetHeaderValueInt(key string, r *http.Request) (int, Response) {
value, err := api.GetHeaderValueInt(key, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting header value type Int!",
Message: fmt.Sprintf("The %v key header has not been obtained", key),
}
}
return value, nil
}
// GetHeaderValueInt64 gets header value as integer 64.
func GetHeaderValueInt64(key string, r *http.Request) (int64, Response) {
value, err := api.GetHeaderValueInt64(key, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting header value type Int64!",
Message: fmt.Sprintf("The %v key header has not been obtained", key),
}
}
return value, nil
}
// GetHeaderValueFloat64 gets header value as float 64.
func GetHeaderValueFloat64(key string, r *http.Request) (float64, Response) {
value, err := api.GetHeaderValueFloat64(key, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting header value type Float64!",
Message: fmt.Sprintf("The %v key header has not been obtained", key),
}
}
return value, nil
}
// GetHeaderValueBool gets header values as bool.
func GetHeaderValueBool(key string, r *http.Request) (bool, Response) {
value, err := api.GetHeaderValueBool(key, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting header value type Bool!",
Message: fmt.Sprintf("The %v key header has not been obtained", key),
}
}
return value, nil
}
// GetRouteVarValueString gets route variable value as string.
func GetRouteVarValueString(urlVarName string, r *http.Request) (string, Response) {
value, err := api.GetRouteVarValueString(urlVarName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting route var!",
Message: fmt.Sprintf("The route var %v has not been obtained", urlVarName),
}
}
return value, nil
}
// GetRouteVarValueInt gets route variable value as integer.
func GetRouteVarValueInt(urlVarName string, r *http.Request) (int, Response) {
value, err := api.GetRouteVarValueInt(urlVarName, r)
if err != nil {
PrintError(err)
return 0, Error{
Title: "Error getting route var type Int",
Message: fmt.Sprintf("The route var %v has not been obtained", urlVarName),
}
}
return value, nil
}
// GetRouteVarValueInt64 gets route variable value as integer 64.
func GetRouteVarValueInt64(urlVarName string, r *http.Request) (int64, Response) {
value, err := api.GetRouteVarValueInt64(urlVarName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting route var type Int64",
Message: fmt.Sprintf("The route var %v has not been obtained", urlVarName),
}
}
return value, nil
}
// GetRouteVarValueFloat64 gets route variable value as float 64.
func GetRouteVarValueFloat64(urlVarName string, r *http.Request) (float64, Response) {
value, err := api.GetRouteVarValueFloat64(urlVarName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting route var type Float64",
Message: fmt.Sprintf("The route var %v has not been obtained", urlVarName),
}
}
return value, nil
}
// GetRouteVarValueBool gets route variable value as bool.
func GetRouteVarValueBool(urlVarName string, r *http.Request) (bool, Response) {
value, err := api.GetRouteVarValueBool(urlVarName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting route var type Bool",
Message: fmt.Sprintf("The route var %v has not been obtained", urlVarName),
}
}
return value, nil
}
// GetQueryParamValueString gets query param value as string.
func GetQueryParamValueString(queryParamName string, r *http.Request) (string, Response) {
value, err := api.GetQueryParamValueString(queryParamName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting query param!",
Message: fmt.Sprintf("The query parameter %v has not been obtained", queryParamName),
}
}
return value, nil
}
// GetQueryParamValueInt gets query param value as integer.
func GetQueryParamValueInt(queryParamName string, r *http.Request) (int, Response) {
value, err := api.GetQueryParamValueInt(queryParamName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting query param type Int!",
Message: fmt.Sprintf("The query parameter %v has not been obtained", queryParamName),
}
}
return value, nil
}
// GetQueryParamValueInt64 gets query param value as integer 64.
func GetQueryParamValueInt64(queryParamName string, r *http.Request) (int64, Response) {
value, err := api.GetQueryParamValueInt64(queryParamName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting query param type Int64!",
Message: fmt.Sprintf("The query parameter %v has not been obtained", queryParamName),
}
}
return value, nil
}
// GetQueryParamValueFloat64 gets query param value as float 64.
func GetQueryParamValueFloat64(queryParamName string, r *http.Request) (float64, Response) {
value, err := api.GetQueryParamValueFloat64(queryParamName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting query param type Float64!",
Message: fmt.Sprintf("The query parameter %v has not been obtained", queryParamName),
}
}
return value, nil
}
// GetQueryParamValueBool gets param value as bool.
func GetQueryParamValueBool(queryParamName string, r *http.Request) (bool, Response) {
value, err := api.GetQueryParamValueBool(queryParamName, r)
if err != nil {
PrintError(err)
return value, Error{
Title: "Error getting query param type Bool!",
Message: fmt.Sprintf("The query parameter %v has not been obtained", queryParamName),
}
}
return value, nil
}
// UnmarshalBody parses and validates request body to a struct
func UnmarshalBody(v interface{}, r *http.Request) Response {
err := api.UnmarshalBody(v, r)
if err != nil {
PrintError(err)
return Error{
Title: "Not unmarshal JSON struct!",
Message: "Error when unmarshal JSON structure",
}
}
if errMsg, err := api.ValidateParams(v); err != nil {
return Error{
Message: errMsg,
ResponseCode: ResponseCodes.InvalidParams,
}
}
return nil
}
// GetContextValue gets requesst context value from context key.
func GetContextValue(key interface{}, r *http.Request) interface{} {
return r.Context().Value(key)
}
// SetContextValue sets requesst context value from context key.
func SetContextValue(key, value interface{}, r *http.Request) *http.Request {
ctx := context.WithValue(
r.Context(),
key,
value,
)
return r.WithContext(ctx)
}
// GetRequestContext gets request data from http request context.
// This useful when you set Request type of core.RequestDataContext in http request context
// in a middleware implementation.
// Returns a core.RequestDataContext struct from api.RequestDataContextContextKey key.
func GetRequestContext(r *http.Request) (*RequestContext, error) {
value := r.Context().Value(RequestDataContextContextKey)
requestData, valid := value.(*RequestContext)
if valid {
return requestData, nil
}
return nil, fmt.Errorf("context requestData not found")
}
// UpdateRequestContext update request context.
func UpdateRequestContext(requestData *RequestContext, r *http.Request) *http.Request {
return SetContextValue(
RequestDataContextContextKey,
requestData,
r,
)
}
// RContext gets request data from http request context.
// This useful when you set Request type of core.RequestDataContext in http request context
// in a middleware implementation.
// Returns a core.RequestDataContext struct from api.RequestDataContextContextKey key.
func RContext(ctx context.Context) (*RequestContext, error) {
value := ctx.Value(RequestDataContextContextKey)
requestData, valid := value.(*RequestContext)
if valid {
return requestData, nil
}
return nil, fmt.Errorf("context requestData not found")
}
func Context(ctx context.Context) *RequestContext {
switch v := ctx.(type) {
case nil:
return &RequestContext{
RequestDataContext: &core.RequestDataContext{
Context: context.Background(),
},
}
case *RequestContext:
return ctx.(*RequestContext)
case RequestContext:
rctx := ctx.(RequestContext)
return &rctx
case context.Context:
ctxType := reflect.TypeOf(ctx)
ctxValue := reflect.ValueOf(ctx)
if ctxType.Kind() == reflect.Ptr {
elem := ctxValue.Elem()
for i := 0; i < elem.NumField(); i++ {
field := elem.Field(i)
rctx, ok := field.Interface().(*RequestContext)
if ok {
return rctx
}
}
}
return &RequestContext{
RequestDataContext: &core.RequestDataContext{
Context: v,
},
}
default:
return &RequestContext{
RequestDataContext: &core.RequestDataContext{
Context: v,
},
}
}
}
// PrintFullEvent set true value for allow print full event request
var PrintFullEvent bool = false
// LogRequest prints API request in log.
func LogRequest(method, uri, eventID, form string, headers http.Header, rawBody []byte) {
var requestBody string
if rawBody != nil && len(rawBody) != 0 {
if len(rawBody) > 2000 && !PrintFullEvent {
requestBody = fmt.Sprintf("REQUEST_BODY: %v%v%v", string(rawBody[:1000]), " ***** SKIPPED ***** ", string(rawBody[len(rawBody)-1000:]))
} else {
requestBody = fmt.Sprintf("REQUEST_BODY: %v", string(rawBody))
}
}
Print("REQUEST_EVENT_ID: %v \nREQUEST_URI: [%v] %v \n%v", eventID, method, uri, requestBody)
}
// LogResponse prints API response in log.
func LogResponse(eventID string, res *httptest.ResponseRecorder) {
var responseBody string
rawBody := res.Body.Bytes()
if rawBody != nil && len(rawBody) != 0 {
if len(rawBody) > 2000 && !PrintFullEvent {
responseBody = fmt.Sprintf("RESPONSE_BODY: %v%v%v", string(rawBody[:1000]), " ***** SKIPPED ***** ", string(rawBody[len(rawBody)-1000:]))
} else {
responseBody = fmt.Sprintf("RESPONSE_BODY: %v", string(rawBody))
}
}
Print("RESPONSE_EVENT_ID: %v \nSTATUS_CODE: %v %v \n%v", eventID, res.Code, http.StatusText(res.Code), responseBody)
}
func generateEventID(ctx context.Context, prefix, uri string) string {
if traceID := getOtelTraceID(ctx); traceID != "" {
return traceID
}
eventIDPayload := fmt.Sprintf("%v:%v:%v", prefix, time.Now().UnixNano(), uri)
buf := []byte(eventIDPayload)
return fmt.Sprintf("%x", md5.Sum(buf))
}
// getTraceID retrieves the trace ID from the provided context
func getOtelTraceID(ctx context.Context) string {
span := trace.SpanFromContext(ctx)
if span == nil {
return ""
}
traceID := span.SpanContext().TraceID().String()
return traceID
}
func ParamValidatorV0(v any) (string, error) {
// not validate any param by default
return "", nil
}