From ab3f76bc85ae5708cd395b0d0e494457d1cbb3ac Mon Sep 17 00:00:00 2001
From: Philipp Borucki
Date: Fri, 3 Nov 2023 17:08:13 +0100
Subject: [PATCH 1/2] fix(lib): allow trailing slash in routes
---
lib/router/router.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/router/router.go b/lib/router/router.go
index 1e058524..ed82ff79 100644
--- a/lib/router/router.go
+++ b/lib/router/router.go
@@ -64,7 +64,7 @@ func (router *Router) addRoute(method string, pattern string, handler http.Handl
if substring == "*" {
return "(.*)"
} else {
- return "([^/]+)"
+ return "([^/]+)/?"
}
})
From 77d8e98482acbf9fadcd904aa8018f59d761868b Mon Sep 17 00:00:00 2001
From: Philipp Borucki
Date: Fri, 3 Nov 2023 17:11:15 +0100
Subject: [PATCH 2/2] refactor(http-proxy-service): add interface for proxy and
prepare for tests
---
.../config/proxyConfig.yaml | 4 +-
src/http-proxy-service/go.mod | 2 +-
src/http-proxy-service/main.go | 83 ++-----------------
.../proxy/default_manager.go | 80 ++++++++++++++++++
src/http-proxy-service/proxy/manager.go | 13 +++
.../ReadDefaultProxyManagerConfiguration.go | 28 +++++++
6 files changed, 129 insertions(+), 81 deletions(-)
create mode 100644 src/http-proxy-service/proxy/default_manager.go
create mode 100644 src/http-proxy-service/proxy/manager.go
create mode 100644 src/http-proxy-service/proxy/proxyutils/ReadDefaultProxyManagerConfiguration.go
diff --git a/src/http-proxy-service/config/proxyConfig.yaml b/src/http-proxy-service/config/proxyConfig.yaml
index 42115578..b4a10faf 100644
--- a/src/http-proxy-service/config/proxyConfig.yaml
+++ b/src/http-proxy-service/config/proxyConfig.yaml
@@ -5,7 +5,7 @@ proxy:
context: /api/v1/user
target: http://localhost:3001/api/v1/user
- name: Shoppinglist Service (Lists)
- context: /api/v1/shoppinglist (Lists)
+ context: /api/v1/shoppinglist
target: http://localhost:3002/api/v1/shoppinglist
- name: Shoppinglist Service (Entries)
context: /api/v1/shoppinglistentries
@@ -14,7 +14,7 @@ proxy:
context: /api/v1/product
target: http://localhost:3003/api/v1/product
- name: Data Processing Service
- context: /api/v1//processing
+ context: /api/v1/processing
target: http://localhost:3004/api/v1/processing
- name: Web Service
context:
diff --git a/src/http-proxy-service/go.mod b/src/http-proxy-service/go.mod
index 3afbee88..156228d1 100644
--- a/src/http-proxy-service/go.mod
+++ b/src/http-proxy-service/go.mod
@@ -1,6 +1,6 @@
module hsfl.de/group6/hsfl-master-ai-cloud-engineering/http-proxy-service
-go 1.21.2
+go 1.21
require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
diff --git a/src/http-proxy-service/main.go b/src/http-proxy-service/main.go
index 32901e11..5ae2866d 100644
--- a/src/http-proxy-service/main.go
+++ b/src/http-proxy-service/main.go
@@ -1,89 +1,16 @@
package main
import (
- "github.com/spf13/viper"
- "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib/router"
+ "hsfl.de/group6/hsfl-master-ai-cloud-engineering/http-proxy-service/proxy"
+ "hsfl.de/group6/hsfl-master-ai-cloud-engineering/http-proxy-service/proxy/proxyutils"
"log"
"net/http"
- "net/http/httputil"
- "net/url"
)
-type ProxyRoute struct {
- Name string `mapstructure:"name"`
- Context string `mapstructure:"context"`
- Target string `mapstructure:"target"`
-}
-
-type ProxyConfig struct {
- ListenAddress string `mapstructure:"listenAddress"`
- ProxyRoutes []ProxyRoute `mapstructure:"proxyRoutes"`
-}
-
func main() {
- // Load config
- proxyConfig := readProxyConfiguration()
-
- // Prepare routing
- routing := router.New()
-
- for _, route := range proxyConfig.ProxyRoutes {
- proxy, err := newProxy(route.Target)
- if err != nil {
- panic(err)
- }
-
- log.Printf("Mapping '%v' | %v ---> %v", route.Name, route.Context, route.Target)
-
- routing.ALL(route.Context+"/*", newHandler(proxy))
- }
+ proxyConfig := proxyutils.ReadDefaultProxyManagerConfiguration("./config", "proxyConfig")
+ proxyManager := proxy.NewDefaultManager(proxyConfig)
log.Printf("Listening on %v", proxyConfig.ListenAddress)
- log.Fatal(http.ListenAndServe(proxyConfig.ListenAddress, routing))
-}
-
-func readProxyConfiguration() *ProxyConfig {
- viper.AddConfigPath("./config")
- viper.SetConfigType("yaml")
- viper.SetConfigName("proxyConfig")
-
- err := viper.ReadInConfig()
- if err != nil {
- log.Fatalf("Error while loading proxy configuration: %v", err)
- }
- viper.AutomaticEnv()
-
- proxyConfig := &ProxyConfig{}
-
- err = viper.UnmarshalKey("proxy", proxyConfig)
- if err != nil {
- panic(err)
- }
-
- return proxyConfig
-}
-
-func newProxy(targetUrl string) (*httputil.ReverseProxy, error) {
- target, err := url.Parse(targetUrl)
- if err != nil {
- return nil, err
- }
- proxy := httputil.NewSingleHostReverseProxy(target)
- proxy.ModifyResponse = func(response *http.Response) error {
- dumpResponse, err := httputil.DumpResponse(response, false)
- if err != nil {
- return err
- }
- log.Println("Response: \r\n", string(dumpResponse))
- return nil
- }
- return proxy, nil
-}
-
-func newHandler(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- r.URL.Path = r.Context().Value("wildcard0").(string)
- log.Println("Request URL: ", r.URL.String())
- p.ServeHTTP(w, r)
- }
+ log.Fatal(http.ListenAndServe(proxyConfig.ListenAddress, proxyManager.GetProxyRouter()))
}
diff --git a/src/http-proxy-service/proxy/default_manager.go b/src/http-proxy-service/proxy/default_manager.go
new file mode 100644
index 00000000..31aa963c
--- /dev/null
+++ b/src/http-proxy-service/proxy/default_manager.go
@@ -0,0 +1,80 @@
+package proxy
+
+import (
+ "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib/router"
+ "log"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+)
+
+type Route struct {
+ Name string `mapstructure:"name"`
+ Context string `mapstructure:"context"`
+ Target string `mapstructure:"target"`
+}
+
+type Config struct {
+ ListenAddress string `mapstructure:"listenAddress"`
+ ProxyRoutes []Route `mapstructure:"proxyRoutes"`
+}
+
+type defaultManager struct {
+ proxies []*httputil.ReverseProxy
+ routing *router.Router
+}
+
+func NewDefaultManager(config *Config) *defaultManager {
+ proxyManager := defaultManager{}
+
+ // Prepare routing
+ proxyManager.routing = router.New()
+
+ for _, route := range config.ProxyRoutes {
+ proxy, err := proxyManager.newProxy(route.Target)
+ if err != nil {
+ panic(err)
+ }
+
+ proxyManager.newHandler(proxy)
+ proxyManager.proxies = append(proxyManager.proxies, proxy)
+
+ proxyManager.routing.ALL(route.Context+"/*", proxyManager.newHandler(proxy))
+
+ log.Printf("Mapping '%v' | %v ---> %v", route.Name, route.Context, route.Target)
+ }
+
+ return &proxyManager
+}
+
+func (dp defaultManager) GetProxyRouter() *router.Router {
+ return dp.routing
+}
+
+func (dp defaultManager) newProxy(targetUrl string) (*httputil.ReverseProxy, error) {
+ target, err := url.Parse(targetUrl)
+ if err != nil {
+ return nil, err
+ }
+ proxy := httputil.NewSingleHostReverseProxy(target)
+ proxy.ModifyResponse = func(response *http.Response) error {
+ dumpResponse, err := httputil.DumpResponse(response, false)
+ if err != nil {
+ return err
+ }
+ log.Println("Response: \r\n", string(dumpResponse))
+ return nil
+ }
+
+ dp.proxies = append(dp.proxies, proxy)
+
+ return proxy, nil
+}
+
+func (dp defaultManager) newHandler(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ r.URL.Path = r.Context().Value("wildcard0").(string)
+ log.Println("Request URL: ", r.URL.String())
+ p.ServeHTTP(w, r)
+ }
+}
diff --git a/src/http-proxy-service/proxy/manager.go b/src/http-proxy-service/proxy/manager.go
new file mode 100644
index 00000000..5c1e7074
--- /dev/null
+++ b/src/http-proxy-service/proxy/manager.go
@@ -0,0 +1,13 @@
+package proxy
+
+import (
+ "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib/router"
+ "net/http"
+ "net/http/httputil"
+)
+
+type Manager interface {
+ GetProxyRouter() *router.Router
+ newProxy(targetUrl string) (*httputil.ReverseProxy, error)
+ newHandler(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request)
+}
diff --git a/src/http-proxy-service/proxy/proxyutils/ReadDefaultProxyManagerConfiguration.go b/src/http-proxy-service/proxy/proxyutils/ReadDefaultProxyManagerConfiguration.go
new file mode 100644
index 00000000..0e2726bb
--- /dev/null
+++ b/src/http-proxy-service/proxy/proxyutils/ReadDefaultProxyManagerConfiguration.go
@@ -0,0 +1,28 @@
+package proxyutils
+
+import (
+ "github.com/spf13/viper"
+ "hsfl.de/group6/hsfl-master-ai-cloud-engineering/http-proxy-service/proxy"
+ "log"
+)
+
+func ReadDefaultProxyManagerConfiguration(path string, filename string) *proxy.Config {
+ viper.AddConfigPath(path)
+ viper.SetConfigType("yaml")
+ viper.SetConfigName(filename)
+
+ err := viper.ReadInConfig()
+ if err != nil {
+ log.Fatalf("Error while loading proxy configuration: %v", err)
+ }
+ viper.AutomaticEnv()
+
+ proxyConfig := &proxy.Config{}
+
+ err = viper.UnmarshalKey("proxy", proxyConfig)
+ if err != nil {
+ panic(err)
+ }
+
+ return proxyConfig
+}