feat: complete contract-driven business development and MySQL integration

This commit is contained in:
2026-09-24 21:56:04 +08:00
parent f9afb8f8dd
commit f5478cdc76
108 changed files with 6557 additions and 550 deletions

58
app/logIsolation_test.go Normal file
View File

@@ -0,0 +1,58 @@
package app_test
import (
"bytes"
"context"
"net/http/httptest"
"strings"
"testing"
omni "git.yuntuo.hk/k2safe/go-omni"
"git.yuntuo.hk/k2safe/go-omni/httpx"
"git.yuntuo.hk/k2safe/go-omni/logx"
)
func TestAppLogAndRequestMetadataIsolation(t *testing.T) {
var a, b bytes.Buffer
la, _ := logx.New(logx.Config{Writer: &a})
lb, _ := logx.New(logx.Config{Writer: &b})
apps := []*omni.App{
omni.New(omni.WithLogger(true), omni.WithLogInstance(la), omni.WithTrustedProxies("127.0.0.1/32")),
omni.New(omni.WithLogger(true), omni.WithLogInstance(lb)),
}
for i, app := range apps {
app.GET("/probe/:id", func(c *httpx.Context) error {
ctx := c.Context()
meta := httpx.Metadata(ctx)
expected := "127.0.0.1"
if i == 0 {
expected = "203.0.113.7"
}
if meta.ClientIP != expected || meta.Route != "/probe/:id" || meta.Method != "GET" {
t.Error(meta)
}
logx.InfoContext(ctx, "business", "app", i)
clone := c.Clone(context.WithValue(ctx, struct{}{}, true), httptest.NewRecorder())
if httpx.Metadata(clone.Context()) != meta {
t.Error("metadata lost")
}
return c.OK(nil)
})
}
for _, app := range apps {
r := httptest.NewRequest("GET", "/probe/42", nil)
r.RemoteAddr = "127.0.0.1:1234"
r.Header.Set("X-Forwarded-For", "203.0.113.7")
app.ServeHTTP(httptest.NewRecorder(), r)
}
for i, out := range []string{a.String(), b.String()} {
if !strings.Contains(out, "http.request") || !strings.Contains(out, "business") || strings.Contains(out, `"app":`+string(rune('0'+(1-i)))) {
t.Fatal(out)
}
}
_ = apps[0].Close()
lb.Info("still open")
if !strings.Contains(b.String(), "still open") {
t.Fatal("borrowed logger closed")
}
}

View File

@@ -3,7 +3,9 @@ package app
import (
"net/http"
"git.yuntuo.hk/k2safe/go-omni/contract"
"git.yuntuo.hk/k2safe/go-omni/httpx"
"git.yuntuo.hk/k2safe/go-omni/logx"
"git.yuntuo.hk/k2safe/go-omni/response"
)
@@ -26,10 +28,14 @@ func (a *App) adaptResponse(encoder response.Encoder, handler httpx.Handler, mid
}
}
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
request = request.WithContext(logx.WithLogger(contract.WithRequestPolicy(request.Context(), a.config.Request), a.config.LogInstance))
if len(a.config.TrustedProxies) > 0 {
request = request.WithContext(httpx.WithClientIPResolver(request.Context(), a.clientIPResolver))
}
requestContext := httpx.NewContext(request, writer, httpx.RouteParams(request.Context()))
requestContext.WithContext(httpx.WithRequestMetadata(request.Context(), httpx.RequestMetadata{
ClientIP: requestContext.ClientIP(), Method: request.Method, Route: httpx.RoutePattern(request.Context()),
}))
if provider, ok := a.responseEncoder.(response.ErrorRegistryProvider); ok {
requestContext.SetErrorRegistry(provider.ErrorRegistry())
}