Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/grpc #143

Merged
merged 29 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7b0a9f7
refactor(http-stress-test): reorganize and new ui lib
Onyxmoon Dec 8, 2023
cf41c67
fix(http-stress-test): fix bug in ramp up calc
Onyxmoon Dec 8, 2023
5785785
feat(product-service): add grpc skeleton and server
Onyxmoon Dec 13, 2023
fe3d74f
feat(product-service): add listener for multi protocol serving (http …
Onyxmoon Dec 14, 2023
da2945f
Merge branch 'feature/update-http-stress-test' into feature/grpc-product
Onyxmoon Dec 14, 2023
09f2857
feat(product-service): add coalescing server for http requests
Onyxmoon Dec 14, 2023
d77617b
feat(product-service): add coalescing controller and remove old approach
Onyxmoon Dec 14, 2023
eeef55d
chore(product-service): extract example demo repository functions for…
Onyxmoon Jan 1, 2024
c9f98b8
fix(product-service): adapt tests for product coalescing controller
Onyxmoon Jan 1, 2024
29f66b2
Merge c9f98b8e34cf5bf4beb1fb4ea3d4368909492991 into fcb13fc927dfa68f8…
Onyxmoon Jan 1, 2024
ec5d3ba
chore: Updated coverage badge.
actions-user Jan 1, 2024
a030637
test(product-service): refactor testing and fix self reference
Onyxmoon Jan 1, 2024
b8f56e6
feat(lib): add grpc service for prices in product service server prot…
Onyxmoon Jan 1, 2024
6e997d6
feat(product-service): add procedures for price grpc service
Onyxmoon Jan 1, 2024
d232968
feat(product-service): add coalescing controller variant for prices
Onyxmoon Jan 1, 2024
7f337b2
test(product-service): add test skeleton for grpc server
Onyxmoon Jan 1, 2024
654e349
Merge 7f337b26784342bb553edd01bab28b6db8f183c7 into fcb13fc927dfa68f8…
Onyxmoon Jan 1, 2024
1c75aed
chore: Updated coverage badge.
actions-user Jan 1, 2024
4d641d3
feat(lib): add protobuff specification for shopping list service
Onyxmoon Jan 1, 2024
eb537d6
build(shoppinglist-service): add generation for protoc
Onyxmoon Jan 1, 2024
da94daa
feat(user-service): add jwt verification for tokens
Onyxmoon Jan 2, 2024
9e6f2fa
feat(user-service): add grpc server for jwt token validation
Onyxmoon Jan 2, 2024
4cabea3
chore(product-service): delete comments
Onyxmoon Jan 2, 2024
9166354
chore(user-service): fix typo
Onyxmoon Jan 2, 2024
6b7d251
feat(user-service): add possibility to specify private key as string …
Onyxmoon Jan 2, 2024
62437f1
test(user-service): add random key generation for tests
Onyxmoon Jan 2, 2024
7ce3b3e
test(user-service): add random private key to router test
Onyxmoon Jan 2, 2024
805f10f
feat(lib): add possibility to use middlewares while routing
Onyxmoon Jan 3, 2024
688db03
Merge branch 'develop' into feature/grpc
Onyxmoon Jan 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Price Whisper
![Coverage](https://img.shields.io/badge/Coverage-82.6%25-brightgreen)
![Coverage](https://img.shields.io/badge/Coverage-77.2%25-brightgreen)
![GitHub release (by tag)](https://img.shields.io/github/v/tag/onyxmoon/hsfl-master-ai-cloud-engineering.svg?sort=semver&label=Version&color=4ccc93d)
[![Run tests (http proxy service)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-http-proxy-service.yml/badge.svg)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-http-proxy-service.yml)
[![Run tests (product-service)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-product-service.yml/badge.svg)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-product-service.yml)
Expand Down
1 change: 1 addition & 0 deletions docker-compose.dev.native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ services:
dockerfile: ./src/product-service/Dockerfile
ports:
- 3003:3003
- 50051:50051

users:
build:
Expand Down
17 changes: 1 addition & 16 deletions docker-compose.native.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
services:
proxy:
build:
context: ./
dockerfile: ./src/http-proxy-service/Dockerfile
image: onyxmoon/pw-http-proxy-service:latest
environment:
- PROXY_CONFIG_PATH=./config/proxyConfig.docker.native.yaml
ports:
- 80:8080
- 8080:8080
- 443:8443
depends_on:
- web
Expand All @@ -16,9 +13,6 @@ services:
- internal

web:
build:
context: ./
dockerfile: ./src/web-service/Dockerfile
image: onyxmoon/pw-web-service:latest
ports:
- 3000:3000
Expand All @@ -30,29 +24,20 @@ services:
- internal

products:
build:
context: ./
dockerfile: ./src/product-service/Dockerfile
image: onyxmoon/pw-product-service:latest
ports:
- 3003:3003
networks:
- internal

users:
build:
context: ./
dockerfile: ./src/user-service/Dockerfile
image: onyxmoon/pw-user-service:latest
ports:
- 3001:3001
networks:
- internal

shoppinglists:
build:
context: ./
dockerfile: ./src/shoppinglist-service/Dockerfile
image: onyxmoon/pw-shoppinglist-service:latest
ports:
- 3002:3002
Expand Down
3 changes: 1 addition & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ services:
environment:
- PROXY_CONFIG_PATH=./config/proxyConfig.docker.yaml
ports:
- 80:8080
- 443:8443
- 8080:8080
depends_on:
- load-balancer-web
networks:
Expand Down
70 changes: 44 additions & 26 deletions go.work.sum

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions lib/router/middleware/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package middleware

import (
router "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib"
"net/http"
)

func CreateAuthMiddleware() router.Middleware {
return func(w http.ResponseWriter, r *http.Request) *http.Request {
return r
}
}
79 changes: 47 additions & 32 deletions lib/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"regexp"
)

type Middleware = func(w http.ResponseWriter, r *http.Request) *http.Request

type route struct {
method string
pattern *regexp.Regexp
Expand All @@ -15,7 +17,8 @@ type route struct {
}

type Router struct {
routes []route
routes []route
middlewares []Middleware
}

func New() *Router {
Expand All @@ -32,6 +35,9 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {

if len(matches) > 0 {
r = createRequestContext(r, route.params, matches[1:])
for _, middleware := range router.middlewares {
r = middleware(w, r)
}
route.handler(w, r)
return
}
Expand All @@ -53,7 +59,7 @@ func createRequestContext(r *http.Request, paramKeys []string, paramValues []str
return r.WithContext(ctx)
}

func (router *Router) addRoute(method string, pattern string, handler http.HandlerFunc) {
func (router *Router) addRoute(method string, pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
paramMatcher := regexp.MustCompile(":([a-zA-Z]+)|\\*")
paramMatches := paramMatcher.FindAllStringSubmatch(pattern, -1)

Expand Down Expand Up @@ -83,55 +89,64 @@ func (router *Router) addRoute(method string, pattern string, handler http.Handl
router.routes = append(router.routes, route{
method: method,
pattern: regexp.MustCompile("^" + pattern + "$"),
handler: handler,
params: params,
handler: func(w http.ResponseWriter, r *http.Request) {
for _, middleware := range middlewares {
r = middleware(w, r)
}
handler(w, r)
},
params: params,
})
}

func (router *Router) GET(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodGet, pattern, handler)
func (router *Router) GET(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodGet, pattern, handler, middlewares...)
}

func (router *Router) POST(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodPost, pattern, handler, middlewares...)
}

func (router *Router) POST(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodPost, pattern, handler)
func (router *Router) PUT(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodPut, pattern, handler, middlewares...)
}

func (router *Router) PUT(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodPut, pattern, handler)
func (router *Router) DELETE(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodDelete, pattern, handler, middlewares...)
}

func (router *Router) DELETE(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodDelete, pattern, handler)
func (router *Router) PATCH(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodPatch, pattern, handler, middlewares...)
}

func (router *Router) PATCH(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodPatch, pattern, handler)
func (router *Router) CONNECT(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodConnect, pattern, handler, middlewares...)
}

func (router *Router) CONNECT(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodConnect, pattern, handler)
func (router *Router) HEAD(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodHead, pattern, handler, middlewares...)
}

func (router *Router) HEAD(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodHead, pattern, handler)
func (router *Router) OPTIONS(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodOptions, pattern, handler, middlewares...)
}

func (router *Router) OPTIONS(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodOptions, pattern, handler)
func (router *Router) TRACE(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.addRoute(http.MethodTrace, pattern, handler, middlewares...)
}

func (router *Router) TRACE(pattern string, handler http.HandlerFunc) {
router.addRoute(http.MethodTrace, pattern, handler)
func (router *Router) ALL(pattern string, handler http.HandlerFunc, middlewares ...Middleware) {
router.GET(pattern, handler, middlewares...)
router.POST(pattern, handler, middlewares...)
router.PUT(pattern, handler, middlewares...)
router.DELETE(pattern, handler, middlewares...)
router.PATCH(pattern, handler, middlewares...)
router.CONNECT(pattern, handler, middlewares...)
router.HEAD(pattern, handler, middlewares...)
router.OPTIONS(pattern, handler, middlewares...)
router.TRACE(pattern, handler, middlewares...)
}

func (router *Router) ALL(pattern string, handler http.HandlerFunc) {
router.GET(pattern, handler)
router.POST(pattern, handler)
router.PUT(pattern, handler)
router.DELETE(pattern, handler)
router.PATCH(pattern, handler)
router.CONNECT(pattern, handler)
router.HEAD(pattern, handler)
router.OPTIONS(pattern, handler)
router.TRACE(pattern, handler)
func (router *Router) RegisterMiddleware(middleware Middleware) {
router.middlewares = append(router.middlewares, middleware)
}
48 changes: 48 additions & 0 deletions lib/router/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,52 @@ func TestRouter(t *testing.T) {
assert.Equal(t, "route", ctx.Value("route"))
assert.Equal(t, "params", ctx.Value("params"))
})

t.Run("should handle simple handler response", func(t *testing.T) {
// given
router := New()
handlerResponse := "Test response"
router.GET("/test/handler", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(handlerResponse))
})

w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/test/handler", nil)

// when
router.ServeHTTP(w, r)

// then
assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, handlerResponse, w.Body.String())
})

t.Run("should handle handler response with middleware", func(t *testing.T) {
// given
router := New()
handlerResponse := "Test response"
contextKey := "testKey"
expectedValue := "testValue"
var ctx context.Context
router.GET("/test/context",
func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(handlerResponse))
w.WriteHeader(http.StatusOK)
ctx = r.Context()
},
func(w http.ResponseWriter, r *http.Request) *http.Request {
return r.WithContext(context.WithValue(r.Context(), contextKey, expectedValue))
})

w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/test/context", nil)

// when
router.ServeHTTP(w, r)

// then
assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, expectedValue, ctx.Value(contextKey).(string))
assert.Equal(t, handlerResponse, w.Body.String())
})
}
Loading
Loading