Spaces:
Sleeping
Sleeping
feat: add security features
Browse files- .dockerignore +18 -6
- .env +8 -0
- .gitignore +2 -0
- Makefile +6 -0
- docs/docs.go +27 -6
- docs/swagger.json +27 -6
- docs/swagger.yaml +18 -0
- go.mod +7 -0
- go.sum +14 -0
- main.go +39 -9
- proxy/crypto/list_service.go +2 -2
- proxy/crypto/prediction_handler.go +13 -0
- proxy/crypto/prediction_service.go +3 -2
- proxy/crypto/structs.go +2 -2
- proxy/{utils.go → helpers/get_service.go} +2 -2
- proxy/helpers/validator.go +9 -0
- proxy/middlewares/logging.go +26 -0
- proxy/{middlewares.go → middlewares/rate_limiter.go} +2 -18
- proxy/national_currency/list_service.go +3 -2
- proxy/national_currency/prediction_handler.go +13 -0
- proxy/national_currency/prediction_service.go +3 -2
- proxy/national_currency/structs.go +2 -2
- proxy/stock/list_service.go +2 -2
- proxy/stock/prediction_handler.go +13 -0
- proxy/stock/prediction_service.go +2 -2
- proxy/stock/structs.go +2 -2
- runner.conf +54 -0
- tests/utils_test.go +2 -2
- tmp/.gitkeep +0 -0
.dockerignore
CHANGED
@@ -1,20 +1,32 @@
|
|
1 |
-
#
|
2 |
/.github
|
3 |
README.md
|
4 |
|
5 |
-
#
|
6 |
/.vscode
|
7 |
|
8 |
-
#
|
9 |
/nginx
|
10 |
/traefik
|
11 |
/haproxy
|
12 |
|
13 |
-
#
|
14 |
docker-compose.yaml
|
15 |
|
16 |
-
#
|
17 |
Makefile
|
18 |
|
19 |
-
#
|
20 |
/postman
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Git and Github
|
2 |
/.github
|
3 |
README.md
|
4 |
|
5 |
+
# VScode
|
6 |
/.vscode
|
7 |
|
8 |
+
# Proxies
|
9 |
/nginx
|
10 |
/traefik
|
11 |
/haproxy
|
12 |
|
13 |
+
# Compose
|
14 |
docker-compose.yaml
|
15 |
|
16 |
+
# Make
|
17 |
Makefile
|
18 |
|
19 |
+
# Postman
|
20 |
/postman
|
21 |
+
|
22 |
+
# Fresh
|
23 |
+
runner.conf
|
24 |
+
|
25 |
+
# Testing
|
26 |
+
/tests
|
27 |
+
/postman
|
28 |
+
coverage.out
|
29 |
+
endpoints_test.sh
|
30 |
+
|
31 |
+
# Temporary
|
32 |
+
/tmp
|
.env
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# TebakAja Proxy
|
2 |
+
TEBAKAJA_PROXY_HOST=0.0.0.0
|
3 |
+
TEBAKAJA_PROXY_PORT=7860
|
4 |
+
|
5 |
+
# TebakAja CORS
|
6 |
+
TEBAKAJA_CORS_ALLOW_ORIGINS=https://huggingface.co,https://qywok-tebakaja-proxy-space-0.hf.space,https://qywok-tebakaja-proxy-space-1.hf.space,https://qywok-tebakaja-proxy-space-2.hf.space
|
7 |
+
TEBAKAJA_CORS_ALLOW_HEADERS=*
|
8 |
+
TEBAKAJA_CORS_ALLOW_METHODS=GET,POST
|
.gitignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
# temporary file
|
2 |
+
/tmp/tebakaja_proxy.exe
|
Makefile
CHANGED
@@ -8,6 +8,9 @@ svc:
|
|
8 |
swag init
|
9 |
go run main.go
|
10 |
|
|
|
|
|
|
|
11 |
swag:
|
12 |
swag init
|
13 |
|
@@ -27,6 +30,9 @@ traefik-test:
|
|
27 |
--api.dashboard=true \
|
28 |
--api.insecure=false
|
29 |
|
|
|
|
|
|
|
30 |
endpoints_check:
|
31 |
bash -c 'chmod +x endpoints_test.sh && ./endpoints_test.sh'
|
32 |
|
|
|
8 |
swag init
|
9 |
go run main.go
|
10 |
|
11 |
+
unittest:
|
12 |
+
go test -v ./tests -coverprofile=coverage.out
|
13 |
+
|
14 |
swag:
|
15 |
swag init
|
16 |
|
|
|
30 |
--api.dashboard=true \
|
31 |
--api.insecure=false
|
32 |
|
33 |
+
hot-reload:
|
34 |
+
freeze -c runner.conf
|
35 |
+
|
36 |
endpoints_check:
|
37 |
bash -c 'chmod +x endpoints_test.sh && ./endpoints_test.sh'
|
38 |
|
docs/docs.go
CHANGED
@@ -203,12 +203,19 @@ const docTemplate = `{
|
|
203 |
},
|
204 |
"crypto.PredictionRequest": {
|
205 |
"type": "object",
|
|
|
|
|
|
|
206 |
"properties": {
|
207 |
"currency": {
|
208 |
-
"type": "string"
|
|
|
|
|
209 |
},
|
210 |
"days": {
|
211 |
-
"type": "integer"
|
|
|
|
|
212 |
}
|
213 |
}
|
214 |
},
|
@@ -278,12 +285,19 @@ const docTemplate = `{
|
|
278 |
},
|
279 |
"national_currency.PredictionRequest": {
|
280 |
"type": "object",
|
|
|
|
|
|
|
281 |
"properties": {
|
282 |
"currency": {
|
283 |
-
"type": "string"
|
|
|
|
|
284 |
},
|
285 |
"days": {
|
286 |
-
"type": "integer"
|
|
|
|
|
287 |
}
|
288 |
}
|
289 |
},
|
@@ -353,12 +367,19 @@ const docTemplate = `{
|
|
353 |
},
|
354 |
"stock.PredictionRequest": {
|
355 |
"type": "object",
|
|
|
|
|
|
|
356 |
"properties": {
|
357 |
"currency": {
|
358 |
-
"type": "string"
|
|
|
|
|
359 |
},
|
360 |
"days": {
|
361 |
-
"type": "integer"
|
|
|
|
|
362 |
}
|
363 |
}
|
364 |
},
|
|
|
203 |
},
|
204 |
"crypto.PredictionRequest": {
|
205 |
"type": "object",
|
206 |
+
"required": [
|
207 |
+
"currency"
|
208 |
+
],
|
209 |
"properties": {
|
210 |
"currency": {
|
211 |
+
"type": "string",
|
212 |
+
"maxLength": 16,
|
213 |
+
"minLength": 4
|
214 |
},
|
215 |
"days": {
|
216 |
+
"type": "integer",
|
217 |
+
"maximum": 31,
|
218 |
+
"minimum": 1
|
219 |
}
|
220 |
}
|
221 |
},
|
|
|
285 |
},
|
286 |
"national_currency.PredictionRequest": {
|
287 |
"type": "object",
|
288 |
+
"required": [
|
289 |
+
"currency"
|
290 |
+
],
|
291 |
"properties": {
|
292 |
"currency": {
|
293 |
+
"type": "string",
|
294 |
+
"maxLength": 16,
|
295 |
+
"minLength": 4
|
296 |
},
|
297 |
"days": {
|
298 |
+
"type": "integer",
|
299 |
+
"maximum": 31,
|
300 |
+
"minimum": 1
|
301 |
}
|
302 |
}
|
303 |
},
|
|
|
367 |
},
|
368 |
"stock.PredictionRequest": {
|
369 |
"type": "object",
|
370 |
+
"required": [
|
371 |
+
"currency"
|
372 |
+
],
|
373 |
"properties": {
|
374 |
"currency": {
|
375 |
+
"type": "string",
|
376 |
+
"maxLength": 16,
|
377 |
+
"minLength": 4
|
378 |
},
|
379 |
"days": {
|
380 |
+
"type": "integer",
|
381 |
+
"maximum": 31,
|
382 |
+
"minimum": 1
|
383 |
}
|
384 |
}
|
385 |
},
|
docs/swagger.json
CHANGED
@@ -195,12 +195,19 @@
|
|
195 |
},
|
196 |
"crypto.PredictionRequest": {
|
197 |
"type": "object",
|
|
|
|
|
|
|
198 |
"properties": {
|
199 |
"currency": {
|
200 |
-
"type": "string"
|
|
|
|
|
201 |
},
|
202 |
"days": {
|
203 |
-
"type": "integer"
|
|
|
|
|
204 |
}
|
205 |
}
|
206 |
},
|
@@ -270,12 +277,19 @@
|
|
270 |
},
|
271 |
"national_currency.PredictionRequest": {
|
272 |
"type": "object",
|
|
|
|
|
|
|
273 |
"properties": {
|
274 |
"currency": {
|
275 |
-
"type": "string"
|
|
|
|
|
276 |
},
|
277 |
"days": {
|
278 |
-
"type": "integer"
|
|
|
|
|
279 |
}
|
280 |
}
|
281 |
},
|
@@ -345,12 +359,19 @@
|
|
345 |
},
|
346 |
"stock.PredictionRequest": {
|
347 |
"type": "object",
|
|
|
|
|
|
|
348 |
"properties": {
|
349 |
"currency": {
|
350 |
-
"type": "string"
|
|
|
|
|
351 |
},
|
352 |
"days": {
|
353 |
-
"type": "integer"
|
|
|
|
|
354 |
}
|
355 |
}
|
356 |
},
|
|
|
195 |
},
|
196 |
"crypto.PredictionRequest": {
|
197 |
"type": "object",
|
198 |
+
"required": [
|
199 |
+
"currency"
|
200 |
+
],
|
201 |
"properties": {
|
202 |
"currency": {
|
203 |
+
"type": "string",
|
204 |
+
"maxLength": 16,
|
205 |
+
"minLength": 4
|
206 |
},
|
207 |
"days": {
|
208 |
+
"type": "integer",
|
209 |
+
"maximum": 31,
|
210 |
+
"minimum": 1
|
211 |
}
|
212 |
}
|
213 |
},
|
|
|
277 |
},
|
278 |
"national_currency.PredictionRequest": {
|
279 |
"type": "object",
|
280 |
+
"required": [
|
281 |
+
"currency"
|
282 |
+
],
|
283 |
"properties": {
|
284 |
"currency": {
|
285 |
+
"type": "string",
|
286 |
+
"maxLength": 16,
|
287 |
+
"minLength": 4
|
288 |
},
|
289 |
"days": {
|
290 |
+
"type": "integer",
|
291 |
+
"maximum": 31,
|
292 |
+
"minimum": 1
|
293 |
}
|
294 |
}
|
295 |
},
|
|
|
359 |
},
|
360 |
"stock.PredictionRequest": {
|
361 |
"type": "object",
|
362 |
+
"required": [
|
363 |
+
"currency"
|
364 |
+
],
|
365 |
"properties": {
|
366 |
"currency": {
|
367 |
+
"type": "string",
|
368 |
+
"maxLength": 16,
|
369 |
+
"minLength": 4
|
370 |
},
|
371 |
"days": {
|
372 |
+
"type": "integer",
|
373 |
+
"maximum": 31,
|
374 |
+
"minimum": 1
|
375 |
}
|
376 |
}
|
377 |
},
|
docs/swagger.yaml
CHANGED
@@ -10,9 +10,15 @@ definitions:
|
|
10 |
crypto.PredictionRequest:
|
11 |
properties:
|
12 |
currency:
|
|
|
|
|
13 |
type: string
|
14 |
days:
|
|
|
|
|
15 |
type: integer
|
|
|
|
|
16 |
type: object
|
17 |
crypto.PredictionResponse:
|
18 |
properties:
|
@@ -58,9 +64,15 @@ definitions:
|
|
58 |
national_currency.PredictionRequest:
|
59 |
properties:
|
60 |
currency:
|
|
|
|
|
61 |
type: string
|
62 |
days:
|
|
|
|
|
63 |
type: integer
|
|
|
|
|
64 |
type: object
|
65 |
national_currency.PredictionResponse:
|
66 |
properties:
|
@@ -106,9 +118,15 @@ definitions:
|
|
106 |
stock.PredictionRequest:
|
107 |
properties:
|
108 |
currency:
|
|
|
|
|
109 |
type: string
|
110 |
days:
|
|
|
|
|
111 |
type: integer
|
|
|
|
|
112 |
type: object
|
113 |
stock.PredictionResponse:
|
114 |
properties:
|
|
|
10 |
crypto.PredictionRequest:
|
11 |
properties:
|
12 |
currency:
|
13 |
+
maxLength: 16
|
14 |
+
minLength: 4
|
15 |
type: string
|
16 |
days:
|
17 |
+
maximum: 31
|
18 |
+
minimum: 1
|
19 |
type: integer
|
20 |
+
required:
|
21 |
+
- currency
|
22 |
type: object
|
23 |
crypto.PredictionResponse:
|
24 |
properties:
|
|
|
64 |
national_currency.PredictionRequest:
|
65 |
properties:
|
66 |
currency:
|
67 |
+
maxLength: 16
|
68 |
+
minLength: 4
|
69 |
type: string
|
70 |
days:
|
71 |
+
maximum: 31
|
72 |
+
minimum: 1
|
73 |
type: integer
|
74 |
+
required:
|
75 |
+
- currency
|
76 |
type: object
|
77 |
national_currency.PredictionResponse:
|
78 |
properties:
|
|
|
118 |
stock.PredictionRequest:
|
119 |
properties:
|
120 |
currency:
|
121 |
+
maxLength: 16
|
122 |
+
minLength: 4
|
123 |
type: string
|
124 |
days:
|
125 |
+
maximum: 31
|
126 |
+
minimum: 1
|
127 |
type: integer
|
128 |
+
required:
|
129 |
+
- currency
|
130 |
type: object
|
131 |
stock.PredictionResponse:
|
132 |
properties:
|
go.mod
CHANGED
@@ -8,14 +8,20 @@ require (
|
|
8 |
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
9 |
github.com/andybalholm/brotli v1.1.0 // indirect
|
10 |
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
|
|
11 |
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
12 |
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
13 |
github.com/go-openapi/spec v0.21.0 // indirect
|
14 |
github.com/go-openapi/swag v0.23.0 // indirect
|
|
|
|
|
|
|
15 |
github.com/gofiber/fiber/v2 v2.52.5 // indirect
|
16 |
github.com/google/uuid v1.6.0 // indirect
|
|
|
17 |
github.com/josharian/intern v1.0.0 // indirect
|
18 |
github.com/klauspost/compress v1.17.9 // indirect
|
|
|
19 |
github.com/mailru/easyjson v0.7.7 // indirect
|
20 |
github.com/mattn/go-colorable v0.1.13 // indirect
|
21 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
@@ -32,6 +38,7 @@ require (
|
|
32 |
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
33 |
github.com/valyala/fasthttp v1.55.0 // indirect
|
34 |
github.com/valyala/tcplisten v1.0.0 // indirect
|
|
|
35 |
golang.org/x/net v0.27.0 // indirect
|
36 |
golang.org/x/sys v0.22.0 // indirect
|
37 |
golang.org/x/text v0.16.0 // indirect
|
|
|
8 |
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
9 |
github.com/andybalholm/brotli v1.1.0 // indirect
|
10 |
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
11 |
+
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
12 |
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
13 |
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
14 |
github.com/go-openapi/spec v0.21.0 // indirect
|
15 |
github.com/go-openapi/swag v0.23.0 // indirect
|
16 |
+
github.com/go-playground/locales v0.14.1 // indirect
|
17 |
+
github.com/go-playground/universal-translator v0.18.1 // indirect
|
18 |
+
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
19 |
github.com/gofiber/fiber/v2 v2.52.5 // indirect
|
20 |
github.com/google/uuid v1.6.0 // indirect
|
21 |
+
github.com/joho/godotenv v1.5.1 // indirect
|
22 |
github.com/josharian/intern v1.0.0 // indirect
|
23 |
github.com/klauspost/compress v1.17.9 // indirect
|
24 |
+
github.com/leodido/go-urn v1.4.0 // indirect
|
25 |
github.com/mailru/easyjson v0.7.7 // indirect
|
26 |
github.com/mattn/go-colorable v0.1.13 // indirect
|
27 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
|
38 |
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
39 |
github.com/valyala/fasthttp v1.55.0 // indirect
|
40 |
github.com/valyala/tcplisten v1.0.0 // indirect
|
41 |
+
golang.org/x/crypto v0.25.0 // indirect
|
42 |
golang.org/x/net v0.27.0 // indirect
|
43 |
golang.org/x/sys v0.22.0 // indirect
|
44 |
golang.org/x/text v0.16.0 // indirect
|
go.sum
CHANGED
@@ -16,6 +16,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
|
16 |
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
17 |
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
18 |
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
|
|
|
19 |
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
20 |
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
21 |
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
@@ -35,12 +37,20 @@ github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyr
|
|
35 |
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
36 |
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
37 |
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
github.com/gofiber/fiber/v2 v2.32.0/go.mod h1:CMy5ZLiXkn6qwthrl03YMyW1NLfj0rhxz2LKl4t7ZTY=
|
39 |
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
40 |
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
41 |
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
42 |
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
43 |
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
|
|
|
|
44 |
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
45 |
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
46 |
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
@@ -51,6 +61,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
|
51 |
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
52 |
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
53 |
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|
|
|
|
54 |
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
55 |
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
56 |
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
@@ -112,6 +124,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|
112 |
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
113 |
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
114 |
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
|
|
|
115 |
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
116 |
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
117 |
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
|
16 |
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
17 |
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
18 |
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
19 |
+
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
20 |
+
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
21 |
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
22 |
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
23 |
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
|
|
37 |
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
38 |
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
39 |
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
40 |
+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
41 |
+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
42 |
+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
43 |
+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
44 |
+
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
45 |
+
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
46 |
github.com/gofiber/fiber/v2 v2.32.0/go.mod h1:CMy5ZLiXkn6qwthrl03YMyW1NLfj0rhxz2LKl4t7ZTY=
|
47 |
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
48 |
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
49 |
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
50 |
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
51 |
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
52 |
+
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
53 |
+
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
54 |
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
55 |
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
56 |
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
|
|
61 |
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
62 |
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
63 |
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
64 |
+
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
65 |
+
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
66 |
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
67 |
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
68 |
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
|
|
124 |
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
125 |
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
126 |
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
127 |
+
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
128 |
+
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
129 |
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
130 |
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
131 |
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
main.go
CHANGED
@@ -1,18 +1,24 @@
|
|
1 |
package main
|
2 |
|
3 |
import (
|
|
|
4 |
"fmt"
|
5 |
"log"
|
6 |
|
7 |
-
"github.com/
|
8 |
|
9 |
-
|
|
|
|
|
|
|
10 |
|
11 |
// Main Features
|
12 |
-
stock_proxy
|
13 |
-
crypto_proxy
|
14 |
national_currency_proxy "tebakaja_lb_proxy/proxy/national_currency"
|
15 |
|
|
|
|
|
16 |
// Swagger
|
17 |
_ "tebakaja_lb_proxy/docs"
|
18 |
swagger "github.com/swaggo/fiber-swagger"
|
@@ -22,6 +28,7 @@ import (
|
|
22 |
)
|
23 |
|
24 |
|
|
|
25 |
// @title TebakAja
|
26 |
// @version 1.0
|
27 |
// @description TebakAja REST API Service
|
@@ -36,9 +43,32 @@ import (
|
|
36 |
|
37 |
// @host 192.168.137.1:7860
|
38 |
func main() {
|
|
|
|
|
|
|
|
|
|
|
39 |
proxyService := fiber.New()
|
40 |
-
proxyService.Use(
|
41 |
-
proxyService.Use(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
stockGroup := proxyService.Group("/stock")
|
44 |
stockGroup.Get("/lists",
|
@@ -69,7 +99,7 @@ func main() {
|
|
69 |
return c.Redirect("/swagger/index.html", fiber.StatusMovedPermanently)
|
70 |
})
|
71 |
|
72 |
-
|
73 |
-
|
74 |
-
log.Fatal(proxyService.Listen(fmt.Sprintf("%s:%
|
75 |
}
|
|
|
1 |
package main
|
2 |
|
3 |
import (
|
4 |
+
"os"
|
5 |
"fmt"
|
6 |
"log"
|
7 |
|
8 |
+
"github.com/joho/godotenv"
|
9 |
|
10 |
+
// Fiber
|
11 |
+
"github.com/gofiber/fiber/v2"
|
12 |
+
"github.com/gofiber/fiber/v2/middleware/cors"
|
13 |
+
"github.com/gofiber/fiber/v2/middleware/helmet"
|
14 |
|
15 |
// Main Features
|
16 |
+
stock_proxy "tebakaja_lb_proxy/proxy/stock"
|
17 |
+
crypto_proxy "tebakaja_lb_proxy/proxy/crypto"
|
18 |
national_currency_proxy "tebakaja_lb_proxy/proxy/national_currency"
|
19 |
|
20 |
+
middlewares "tebakaja_lb_proxy/proxy/middlewares"
|
21 |
+
|
22 |
// Swagger
|
23 |
_ "tebakaja_lb_proxy/docs"
|
24 |
swagger "github.com/swaggo/fiber-swagger"
|
|
|
28 |
)
|
29 |
|
30 |
|
31 |
+
|
32 |
// @title TebakAja
|
33 |
// @version 1.0
|
34 |
// @description TebakAja REST API Service
|
|
|
43 |
|
44 |
// @host 192.168.137.1:7860
|
45 |
func main() {
|
46 |
+
err := godotenv.Load()
|
47 |
+
if err != nil {
|
48 |
+
log.Fatalf("Error loading .env file")
|
49 |
+
}
|
50 |
+
|
51 |
proxyService := fiber.New()
|
52 |
+
proxyService.Use(helmet.New())
|
53 |
+
proxyService.Use(middlewares.LoggingMiddleware)
|
54 |
+
proxyService.Use(middlewares.RateLimiterMiddleware())
|
55 |
+
|
56 |
+
proxyService.Use(cors.New(cors.Config{
|
57 |
+
AllowOrigins: os.Getenv("TEBAKAJA_CORS_ALLOW_ORIGINS"),
|
58 |
+
AllowHeaders: os.Getenv("TEBAKAJA_CORS_ALLOW_HEADERS"),
|
59 |
+
AllowMethods: os.Getenv("TEBAKAJA_CORS_ALLOW_METHODS"),
|
60 |
+
AllowCredentials: true,
|
61 |
+
}))
|
62 |
+
|
63 |
+
proxyService.Use(func(c *fiber.Ctx) error {
|
64 |
+
c.Set("Content-Security-Policy", fmt.Sprintf("frame-ancestors 'self' %s %s %s %s",
|
65 |
+
"https://huggingface.co",
|
66 |
+
"https://qywok-tebakaja-proxy-space-0.hf.space",
|
67 |
+
"https://qywok-tebakaja-proxy-space-1.hf.space",
|
68 |
+
"https://qywok-tebakaja-proxy-space-2.hf.space",
|
69 |
+
))
|
70 |
+
return c.Next()
|
71 |
+
})
|
72 |
|
73 |
stockGroup := proxyService.Group("/stock")
|
74 |
stockGroup.Get("/lists",
|
|
|
99 |
return c.Redirect("/swagger/index.html", fiber.StatusMovedPermanently)
|
100 |
})
|
101 |
|
102 |
+
HOST := os.Getenv("TEBAKAJA_PROXY_HOST")
|
103 |
+
PORT := os.Getenv("TEBAKAJA_PROXY_PORT")
|
104 |
+
log.Fatal(proxyService.Listen(fmt.Sprintf("%s:%s", HOST, PORT)))
|
105 |
}
|
proxy/crypto/list_service.go
CHANGED
@@ -6,7 +6,7 @@ import (
|
|
6 |
"net/http"
|
7 |
"encoding/json"
|
8 |
|
9 |
-
|
10 |
)
|
11 |
|
12 |
|
@@ -14,7 +14,7 @@ import (
|
|
14 |
* --- Cryptocurrency Prediction Model Lists Service ---
|
15 |
*/
|
16 |
func (s *CryptoServiceImpl) CryptoListsService(ctx context.Context) (ApiResponse, error) {
|
17 |
-
endpoint := fmt.Sprintf("%s/lists",
|
18 |
req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
19 |
if err != nil {
|
20 |
return ApiResponse{
|
|
|
6 |
"net/http"
|
7 |
"encoding/json"
|
8 |
|
9 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
10 |
)
|
11 |
|
12 |
|
|
|
14 |
* --- Cryptocurrency Prediction Model Lists Service ---
|
15 |
*/
|
16 |
func (s *CryptoServiceImpl) CryptoListsService(ctx context.Context) (ApiResponse, error) {
|
17 |
+
endpoint := fmt.Sprintf("%s/lists", helpers.GetEndpointService("crypto"))
|
18 |
req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
19 |
if err != nil {
|
20 |
return ApiResponse{
|
proxy/crypto/prediction_handler.go
CHANGED
@@ -9,6 +9,9 @@ import (
|
|
9 |
"net/http"
|
10 |
|
11 |
"github.com/gofiber/fiber/v2"
|
|
|
|
|
|
|
12 |
)
|
13 |
|
14 |
|
@@ -46,6 +49,16 @@ func CryptoPredictionHandler(service CryptoService) fiber.Handler {
|
|
46 |
return
|
47 |
}
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
apiResponse, err := service.CryptoPredictionService(ctx, predictionReq)
|
50 |
if err != nil {
|
51 |
log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err)
|
|
|
9 |
"net/http"
|
10 |
|
11 |
"github.com/gofiber/fiber/v2"
|
12 |
+
"github.com/go-playground/validator/v10"
|
13 |
+
|
14 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
15 |
)
|
16 |
|
17 |
|
|
|
49 |
return
|
50 |
}
|
51 |
|
52 |
+
if err := helpers.ValidateStruct(predictionReq); err != nil {
|
53 |
+
errors := err.(validator.ValidationErrors)
|
54 |
+
|
55 |
+
ch <- ApiResponse{
|
56 |
+
Message: fmt.Sprintf("%v", errors),
|
57 |
+
StatusCode: http.StatusBadRequest,
|
58 |
+
}
|
59 |
+
return
|
60 |
+
}
|
61 |
+
|
62 |
apiResponse, err := service.CryptoPredictionService(ctx, predictionReq)
|
63 |
if err != nil {
|
64 |
log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err)
|
proxy/crypto/prediction_service.go
CHANGED
@@ -6,7 +6,8 @@ import (
|
|
6 |
"context"
|
7 |
"net/http"
|
8 |
"encoding/json"
|
9 |
-
|
|
|
10 |
)
|
11 |
|
12 |
|
@@ -22,7 +23,7 @@ func (s *CryptoServiceImpl) CryptoPredictionService(ctx context.Context, req Pre
|
|
22 |
}, err
|
23 |
}
|
24 |
|
25 |
-
endpoint := fmt.Sprintf("%s/prediction",
|
26 |
httpReq, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewBuffer(reqBody))
|
27 |
if err != nil {
|
28 |
return ApiResponse{
|
|
|
6 |
"context"
|
7 |
"net/http"
|
8 |
"encoding/json"
|
9 |
+
|
10 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
11 |
)
|
12 |
|
13 |
|
|
|
23 |
}, err
|
24 |
}
|
25 |
|
26 |
+
endpoint := fmt.Sprintf("%s/prediction", helpers.GetEndpointService("crypto"))
|
27 |
httpReq, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewBuffer(reqBody))
|
28 |
if err != nil {
|
29 |
return ApiResponse{
|
proxy/crypto/structs.go
CHANGED
@@ -8,8 +8,8 @@ type ApiResponse struct {
|
|
8 |
|
9 |
|
10 |
type PredictionRequest struct {
|
11 |
-
Days int `json:"days"`
|
12 |
-
Currency string `json:"currency"`
|
13 |
}
|
14 |
|
15 |
|
|
|
8 |
|
9 |
|
10 |
type PredictionRequest struct {
|
11 |
+
Days int `json:"days" validate:"gte=1,lte=31"`
|
12 |
+
Currency string `json:"currency" validate:"required,min=4,max=16"`
|
13 |
}
|
14 |
|
15 |
|
proxy/{utils.go → helpers/get_service.go}
RENAMED
@@ -1,4 +1,4 @@
|
|
1 |
-
package
|
2 |
|
3 |
import "math/rand"
|
4 |
|
@@ -26,7 +26,7 @@ var serviceUrls = map[string][]string{
|
|
26 |
},
|
27 |
}
|
28 |
|
29 |
-
func
|
30 |
var selectedUrls []string
|
31 |
switch svc_name {
|
32 |
case "crypto":
|
|
|
1 |
+
package helpers
|
2 |
|
3 |
import "math/rand"
|
4 |
|
|
|
26 |
},
|
27 |
}
|
28 |
|
29 |
+
func GetEndpointService(svc_name string) string {
|
30 |
var selectedUrls []string
|
31 |
switch svc_name {
|
32 |
case "crypto":
|
proxy/helpers/validator.go
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package helpers
|
2 |
+
|
3 |
+
import "github.com/go-playground/validator/v10"
|
4 |
+
|
5 |
+
var validate *validator.Validate
|
6 |
+
|
7 |
+
func init() { validate = validator.New() }
|
8 |
+
|
9 |
+
func ValidateStruct(data interface{}) error { return validate.Struct(data) }
|
proxy/middlewares/logging.go
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package middlewares
|
2 |
+
|
3 |
+
import (
|
4 |
+
"log"
|
5 |
+
"time"
|
6 |
+
"net/http"
|
7 |
+
|
8 |
+
"github.com/gofiber/fiber/v2"
|
9 |
+
)
|
10 |
+
|
11 |
+
|
12 |
+
/*
|
13 |
+
* --- Logging Middleware ---
|
14 |
+
*/
|
15 |
+
func LoggingMiddleware(c *fiber.Ctx) error {
|
16 |
+
start_time := time.Now()
|
17 |
+
|
18 |
+
log.Printf("[%s] %s %s - %d %s in %v",
|
19 |
+
time.Now().Format("2006-01-02 15:04:05"),
|
20 |
+
c.Method(), c.Path(), c.Response().StatusCode(),
|
21 |
+
http.StatusText(c.Response().StatusCode()), time.Since(start_time))
|
22 |
+
|
23 |
+
|
24 |
+
return c.Next()
|
25 |
+
}
|
26 |
+
|
proxy/{middlewares.go → middlewares/rate_limiter.go}
RENAMED
@@ -1,30 +1,14 @@
|
|
1 |
-
package
|
2 |
|
3 |
import (
|
4 |
-
"log"
|
5 |
-
"net/http"
|
6 |
"time"
|
|
|
7 |
|
8 |
"github.com/gofiber/fiber/v2"
|
9 |
"github.com/gofiber/fiber/v2/middleware/limiter"
|
10 |
)
|
11 |
|
12 |
|
13 |
-
/*
|
14 |
-
* --- Logging Middleware ---
|
15 |
-
*/
|
16 |
-
func LoggingMiddleware(c *fiber.Ctx) error {
|
17 |
-
start := time.Now()
|
18 |
-
err := c.Next()
|
19 |
-
|
20 |
-
log.Printf("[%s] %s %s - %d %s in %v", time.Now().Format("2006-01-02 15:04:05"),
|
21 |
-
c.Method(), c.Path(), c.Response().StatusCode(),
|
22 |
-
http.StatusText(c.Response().StatusCode()), time.Since(start))
|
23 |
-
|
24 |
-
return err
|
25 |
-
}
|
26 |
-
|
27 |
-
|
28 |
/*
|
29 |
* --- Rate Limiter Middleware ---
|
30 |
*/
|
|
|
1 |
+
package middlewares
|
2 |
|
3 |
import (
|
|
|
|
|
4 |
"time"
|
5 |
+
"net/http"
|
6 |
|
7 |
"github.com/gofiber/fiber/v2"
|
8 |
"github.com/gofiber/fiber/v2/middleware/limiter"
|
9 |
)
|
10 |
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/*
|
13 |
* --- Rate Limiter Middleware ---
|
14 |
*/
|
proxy/national_currency/list_service.go
CHANGED
@@ -5,7 +5,8 @@ import (
|
|
5 |
"context"
|
6 |
"net/http"
|
7 |
"encoding/json"
|
8 |
-
|
|
|
9 |
)
|
10 |
|
11 |
|
@@ -13,7 +14,7 @@ import (
|
|
13 |
* --- National Currency Prediction Model Lists Service ---
|
14 |
*/
|
15 |
func (s *NationalCurrencyServiceImpl) NationalCurrencyListsService(ctx context.Context) (ApiResponse, error) {
|
16 |
-
endpoint := fmt.Sprintf("%s/lists",
|
17 |
req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
18 |
if err != nil {
|
19 |
return ApiResponse{
|
|
|
5 |
"context"
|
6 |
"net/http"
|
7 |
"encoding/json"
|
8 |
+
|
9 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
10 |
)
|
11 |
|
12 |
|
|
|
14 |
* --- National Currency Prediction Model Lists Service ---
|
15 |
*/
|
16 |
func (s *NationalCurrencyServiceImpl) NationalCurrencyListsService(ctx context.Context) (ApiResponse, error) {
|
17 |
+
endpoint := fmt.Sprintf("%s/lists", helpers.GetEndpointService("national"))
|
18 |
req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
19 |
if err != nil {
|
20 |
return ApiResponse{
|
proxy/national_currency/prediction_handler.go
CHANGED
@@ -9,6 +9,9 @@ import (
|
|
9 |
"net/http"
|
10 |
|
11 |
"github.com/gofiber/fiber/v2"
|
|
|
|
|
|
|
12 |
)
|
13 |
|
14 |
|
@@ -46,6 +49,16 @@ func NationalCurrencyPredictionHandler(service NationalCurrencyService) fiber.Ha
|
|
46 |
return
|
47 |
}
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
apiResponse, err := service.NationalCurrencyPredictionService(ctx, predictionReq)
|
50 |
if err != nil {
|
51 |
log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err)
|
|
|
9 |
"net/http"
|
10 |
|
11 |
"github.com/gofiber/fiber/v2"
|
12 |
+
"github.com/go-playground/validator/v10"
|
13 |
+
|
14 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
15 |
)
|
16 |
|
17 |
|
|
|
49 |
return
|
50 |
}
|
51 |
|
52 |
+
if err := helpers.ValidateStruct(predictionReq); err != nil {
|
53 |
+
errors := err.(validator.ValidationErrors)
|
54 |
+
|
55 |
+
ch <- ApiResponse{
|
56 |
+
Message: fmt.Sprintf("%v", errors),
|
57 |
+
StatusCode: http.StatusBadRequest,
|
58 |
+
}
|
59 |
+
return
|
60 |
+
}
|
61 |
+
|
62 |
apiResponse, err := service.NationalCurrencyPredictionService(ctx, predictionReq)
|
63 |
if err != nil {
|
64 |
log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err)
|
proxy/national_currency/prediction_service.go
CHANGED
@@ -6,7 +6,8 @@ import (
|
|
6 |
"context"
|
7 |
"net/http"
|
8 |
"encoding/json"
|
9 |
-
|
|
|
10 |
)
|
11 |
|
12 |
|
@@ -22,7 +23,7 @@ func (s *NationalCurrencyServiceImpl) NationalCurrencyPredictionService(ctx cont
|
|
22 |
}, err
|
23 |
}
|
24 |
|
25 |
-
endpoint := fmt.Sprintf("%s/prediction",
|
26 |
httpReq, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewBuffer(reqBody))
|
27 |
if err != nil {
|
28 |
return ApiResponse{
|
|
|
6 |
"context"
|
7 |
"net/http"
|
8 |
"encoding/json"
|
9 |
+
|
10 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
11 |
)
|
12 |
|
13 |
|
|
|
23 |
}, err
|
24 |
}
|
25 |
|
26 |
+
endpoint := fmt.Sprintf("%s/prediction", helpers.GetEndpointService("national"))
|
27 |
httpReq, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewBuffer(reqBody))
|
28 |
if err != nil {
|
29 |
return ApiResponse{
|
proxy/national_currency/structs.go
CHANGED
@@ -7,8 +7,8 @@ type ApiResponse struct {
|
|
7 |
}
|
8 |
|
9 |
type PredictionRequest struct {
|
10 |
-
Days int `json:"days"`
|
11 |
-
Currency string `json:"currency"`
|
12 |
}
|
13 |
|
14 |
type PredictionResponse struct {
|
|
|
7 |
}
|
8 |
|
9 |
type PredictionRequest struct {
|
10 |
+
Days int `json:"days" validate:"gte=1,lte=31"`
|
11 |
+
Currency string `json:"currency" validate:"required,min=4,max=16"`
|
12 |
}
|
13 |
|
14 |
type PredictionResponse struct {
|
proxy/stock/list_service.go
CHANGED
@@ -6,7 +6,7 @@ import (
|
|
6 |
"net/http"
|
7 |
"encoding/json"
|
8 |
|
9 |
-
|
10 |
)
|
11 |
|
12 |
|
@@ -14,7 +14,7 @@ import (
|
|
14 |
* --- Stock Prediction Model Lists Service ---
|
15 |
*/
|
16 |
func (s *StockServiceImpl) StockListsService(ctx context.Context) (ApiResponse, error) {
|
17 |
-
endpoint := fmt.Sprintf("%s/lists",
|
18 |
req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
19 |
if err != nil {
|
20 |
return ApiResponse{
|
|
|
6 |
"net/http"
|
7 |
"encoding/json"
|
8 |
|
9 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
10 |
)
|
11 |
|
12 |
|
|
|
14 |
* --- Stock Prediction Model Lists Service ---
|
15 |
*/
|
16 |
func (s *StockServiceImpl) StockListsService(ctx context.Context) (ApiResponse, error) {
|
17 |
+
endpoint := fmt.Sprintf("%s/lists", helpers.GetEndpointService("stock"))
|
18 |
req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
19 |
if err != nil {
|
20 |
return ApiResponse{
|
proxy/stock/prediction_handler.go
CHANGED
@@ -9,6 +9,9 @@ import (
|
|
9 |
"net/http"
|
10 |
|
11 |
"github.com/gofiber/fiber/v2"
|
|
|
|
|
|
|
12 |
)
|
13 |
|
14 |
|
@@ -46,6 +49,16 @@ func StockPredictionHandler(service StockService) fiber.Handler {
|
|
46 |
return
|
47 |
}
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
apiResponse, err := service.StockPredictionService(ctx, predictionReq)
|
50 |
if err != nil {
|
51 |
log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err)
|
|
|
9 |
"net/http"
|
10 |
|
11 |
"github.com/gofiber/fiber/v2"
|
12 |
+
"github.com/go-playground/validator/v10"
|
13 |
+
|
14 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
15 |
)
|
16 |
|
17 |
|
|
|
49 |
return
|
50 |
}
|
51 |
|
52 |
+
if err := helpers.ValidateStruct(predictionReq); err != nil {
|
53 |
+
errors := err.(validator.ValidationErrors)
|
54 |
+
|
55 |
+
ch <- ApiResponse{
|
56 |
+
Message: fmt.Sprintf("%v", errors),
|
57 |
+
StatusCode: http.StatusBadRequest,
|
58 |
+
}
|
59 |
+
return
|
60 |
+
}
|
61 |
+
|
62 |
apiResponse, err := service.StockPredictionService(ctx, predictionReq)
|
63 |
if err != nil {
|
64 |
log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err)
|
proxy/stock/prediction_service.go
CHANGED
@@ -7,7 +7,7 @@ import (
|
|
7 |
"net/http"
|
8 |
"encoding/json"
|
9 |
|
10 |
-
|
11 |
)
|
12 |
|
13 |
|
@@ -23,7 +23,7 @@ func (s *StockServiceImpl) StockPredictionService(ctx context.Context, req Predi
|
|
23 |
}, err
|
24 |
}
|
25 |
|
26 |
-
endpoint := fmt.Sprintf("%s/prediction",
|
27 |
httpReq, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewBuffer(reqBody))
|
28 |
if err != nil {
|
29 |
return ApiResponse{
|
|
|
7 |
"net/http"
|
8 |
"encoding/json"
|
9 |
|
10 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
11 |
)
|
12 |
|
13 |
|
|
|
23 |
}, err
|
24 |
}
|
25 |
|
26 |
+
endpoint := fmt.Sprintf("%s/prediction", helpers.GetEndpointService("stock"))
|
27 |
httpReq, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewBuffer(reqBody))
|
28 |
if err != nil {
|
29 |
return ApiResponse{
|
proxy/stock/structs.go
CHANGED
@@ -7,8 +7,8 @@ type ApiResponse struct {
|
|
7 |
}
|
8 |
|
9 |
type PredictionRequest struct {
|
10 |
-
Days int `json:"days"`
|
11 |
-
Currency string `json:"currency"`
|
12 |
}
|
13 |
|
14 |
type PredictionResponse struct {
|
|
|
7 |
}
|
8 |
|
9 |
type PredictionRequest struct {
|
10 |
+
Days int `json:"days" validate:"gte=1,lte=31"`
|
11 |
+
Currency string `json:"currency" validate:"required,min=4,max=16"`
|
12 |
}
|
13 |
|
14 |
type PredictionResponse struct {
|
runner.conf
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# root directory for your project
|
2 |
+
root: .
|
3 |
+
|
4 |
+
# temporary path where Fresh will store built binaries
|
5 |
+
tmp_path: ./tmp
|
6 |
+
|
7 |
+
# name of the build file
|
8 |
+
build_name: tebakaja_proxy
|
9 |
+
|
10 |
+
# directories to watch for changes (can include multiple directories)
|
11 |
+
watch_dirs: ["."]
|
12 |
+
# watch_dirs: ["./src", "./views"]
|
13 |
+
|
14 |
+
# file extensions to watch and trigger a rebuild
|
15 |
+
valid_ext: [".go", ".tpl", ".tmpl", ".html", ".css", ".js"]
|
16 |
+
|
17 |
+
# file extensions that should not trigger a rebuild (but reloads)
|
18 |
+
no_rebuild_ext: [".tpl", ".tmpl", ".html", ".css", ".js"]
|
19 |
+
|
20 |
+
# directories and files to ignore when watching for changes
|
21 |
+
ignore: ["assets", "tmp", "vendor", ".git", "node_modules"]
|
22 |
+
|
23 |
+
# log path for build output
|
24 |
+
build_log: ./tmp/build.log
|
25 |
+
|
26 |
+
# command to run after the build is complete
|
27 |
+
build_cmd: go build -o ./tmp/tebakaja_proxy .
|
28 |
+
|
29 |
+
# command to run when starting the server
|
30 |
+
run_cmd: ./tmp/tebakaja_proxy
|
31 |
+
|
32 |
+
# environment variables to set when running the server
|
33 |
+
envs: [
|
34 |
+
"HOST=0.0.0.0",
|
35 |
+
"ENV=development"
|
36 |
+
]
|
37 |
+
|
38 |
+
# delay before restarting the server after a change (milliseconds)
|
39 |
+
restart_delay: 200
|
40 |
+
|
41 |
+
# enables or disables color in the terminal output
|
42 |
+
colors: true
|
43 |
+
|
44 |
+
# specify custom commands to run on file change
|
45 |
+
commands: {
|
46 |
+
"go": {
|
47 |
+
"run": "go run .",
|
48 |
+
"build": "go build -o ./tmp/tebakaja_proxy ."
|
49 |
+
},
|
50 |
+
# "html": {
|
51 |
+
# "run": "echo HTML file changed",
|
52 |
+
# "build": ""
|
53 |
+
# }
|
54 |
+
}
|
tests/utils_test.go
CHANGED
@@ -4,7 +4,7 @@ import (
|
|
4 |
"reflect"
|
5 |
"testing"
|
6 |
|
7 |
-
|
8 |
)
|
9 |
|
10 |
func IsStringReflect(x interface{}) bool {
|
@@ -28,7 +28,7 @@ func TestGetEndpointByRestService(t *testing.T) {
|
|
28 |
|
29 |
for _, tt := range tests {
|
30 |
t.Run(tt.service, func(t *testing.T) {
|
31 |
-
endpoint :=
|
32 |
|
33 |
if got := IsStringReflect(endpoint); got != tt.want {
|
34 |
t.Errorf("IsStringReflect(%v) = %v, want %v", endpoint, got, tt.want)
|
|
|
4 |
"reflect"
|
5 |
"testing"
|
6 |
|
7 |
+
helpers "tebakaja_lb_proxy/proxy/helpers"
|
8 |
)
|
9 |
|
10 |
func IsStringReflect(x interface{}) bool {
|
|
|
28 |
|
29 |
for _, tt := range tests {
|
30 |
t.Run(tt.service, func(t *testing.T) {
|
31 |
+
endpoint := helpers.GetEndpointService(tt.service)
|
32 |
|
33 |
if got := IsStringReflect(endpoint); got != tt.want {
|
34 |
t.Errorf("IsStringReflect(%v) = %v, want %v", endpoint, got, tt.want)
|
tmp/.gitkeep
ADDED
File without changes
|