feat: support request_header key source (#4903)
* feat: support request_header key source in backend and settings UI * feat: support request_header channel affinity source
This commit is contained in:
@@ -176,6 +176,66 @@ func TestShouldSkipRetryAfterChannelAffinityFailure(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractChannelAffinityValue_RequestHeader(t *testing.T) {
|
||||
rec := httptest.NewRecorder()
|
||||
ctx, _ := gin.CreateTestContext(rec)
|
||||
ctx.Request = httptest.NewRequest(http.MethodPost, "/v1/responses", nil)
|
||||
ctx.Request.Header.Set("X-Affinity-Key", " tenant-123 ")
|
||||
|
||||
value := extractChannelAffinityValue(ctx, operation_setting.ChannelAffinityKeySource{
|
||||
Type: "request_header",
|
||||
Key: "X-Affinity-Key",
|
||||
})
|
||||
|
||||
require.Equal(t, "tenant-123", value)
|
||||
}
|
||||
|
||||
func TestGetPreferredChannelByAffinity_RequestHeaderKeySource(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
rule := operation_setting.ChannelAffinityRule{
|
||||
Name: "header-affinity",
|
||||
ModelRegex: []string{"^gpt-.*$"},
|
||||
PathRegex: []string{"/v1/responses"},
|
||||
KeySources: []operation_setting.ChannelAffinityKeySource{
|
||||
{Type: "request_header", Key: "X-Affinity-Key"},
|
||||
},
|
||||
IncludeRuleName: true,
|
||||
IncludeModelName: true,
|
||||
}
|
||||
|
||||
affinityValue := fmt.Sprintf("header-hit-%d", time.Now().UnixNano())
|
||||
cacheKeySuffix := buildChannelAffinityCacheKeySuffix(rule, "gpt-5", "default", affinityValue)
|
||||
|
||||
cache := getChannelAffinityCache()
|
||||
require.NoError(t, cache.SetWithTTL(cacheKeySuffix, 9528, time.Minute))
|
||||
t.Cleanup(func() {
|
||||
_, _ = cache.DeleteMany([]string{cacheKeySuffix})
|
||||
})
|
||||
|
||||
setting := operation_setting.GetChannelAffinitySetting()
|
||||
originalRules := setting.Rules
|
||||
setting.Rules = append([]operation_setting.ChannelAffinityRule{rule}, originalRules...)
|
||||
t.Cleanup(func() {
|
||||
setting.Rules = originalRules
|
||||
})
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
ctx, _ := gin.CreateTestContext(rec)
|
||||
ctx.Request = httptest.NewRequest(http.MethodPost, "/v1/responses", nil)
|
||||
ctx.Request.Header.Set("X-Affinity-Key", affinityValue)
|
||||
|
||||
channelID, found := GetPreferredChannelByAffinity(ctx, "gpt-5", "default")
|
||||
require.True(t, found)
|
||||
require.Equal(t, 9528, channelID)
|
||||
|
||||
meta, ok := getChannelAffinityMeta(ctx)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "request_header", meta.KeySourceType)
|
||||
require.Equal(t, "X-Affinity-Key", meta.KeySourceKey)
|
||||
require.Equal(t, buildChannelAffinityKeyHint(affinityValue), meta.KeyHint)
|
||||
}
|
||||
|
||||
func TestChannelAffinityHitCodexTemplatePassHeadersEffective(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user