This is an automated email from the ASF dual-hosted git repository.

xuetaoli pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git


The following commit(s) were added to refs/heads/main by this push:
     new 29a15654 feat: add router static config sample (#1059)
29a15654 is described below

commit 29a1565416a7c6be9259ac55c453d0e4695875e1
Author: Aether <[email protected]>
AuthorDate: Mon Apr 13 12:03:46 2026 +0800

    feat: add router static config sample (#1059)
    
    * add router static config sample
    
    * fix(router): exit non-zero when static config consumer invoke fails
    
    * refactor(router): align static router samples with integration layout
    
    * chore(router): add static router samples to integration docs and CI list
    
    * fix: add more attemps to reduce test flakiness
    
    * fix(router): align static tag router key with provider application
    
    ---------
    
    Co-authored-by: Aetherance <[email protected]>
---
 README.md                                          |   2 +
 README_CN.md                                       |   2 +
 router/static_config/README.md                     |  27 ++++++
 router/static_config/README_CN.md                  |  27 ++++++
 router/static_config/condition/README.md           |  59 ++++++++++++
 router/static_config/condition/README_CN.md        |  59 ++++++++++++
 .../condition/go-client/cmd/client.go              |  94 ++++++++++++++++++
 .../condition/go-node2-server/cmd/server_node2.go  |  76 +++++++++++++++
 .../condition/go-server/cmd/server.go              |  76 +++++++++++++++
 router/static_config/tag/README.md                 |  78 +++++++++++++++
 router/static_config/tag/README_CN.md              |  78 +++++++++++++++
 router/static_config/tag/go-client/cmd/client.go   | 105 +++++++++++++++++++++
 router/static_config/tag/go-server/cmd/server.go   |  76 +++++++++++++++
 .../tag/go-tag-server/cmd/server_tag.go            |  77 +++++++++++++++
 start_integrate_test.sh                            |   2 +
 15 files changed, 838 insertions(+)

diff --git a/README.md b/README.md
index c7313344..4a30dc51 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,8 @@ Please refer to [HOWTO.md](HOWTO.md) for detailed 
instructions on running the sa
   * `router/condition`: Dubbo-go condition router examples.
   * `router/script`: Dubbo-go script router examples.
   * `router/polaris`: Quickly experience Polaris' service routing capabilities 
in Dubbo-go.
+  * `router/static_config/tag`: Dubbo-go static tag router example.
+  * `router/static_config/condition`: Dubbo-go static condition router example.
 * `rpc`: Various RPC protocol examples with Dubbo-go.
   * `rpc/dubbo`: Dubbo protocol example, including Java–Go interop.
   * `rpc/grpc`: gRPC protocol example.
diff --git a/README_CN.md b/README_CN.md
index 943a0dcc..f5f4bebd 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -57,6 +57,8 @@
   * `router/condition`: Dubbo-go 的 condition router 使用示例。
   * `router/script`: Dubbo-go 的 script router 使用示例。
   * `router/polaris`:在 Dubbo-go 中快速体验北极星的服务路由能力。
+  * `router/static_config/tag`: 静态配置的 tag router 示例。
+  * `router/static_config/condition`: 静态配置的 condition router 示例。
 * `rpc`:Dubbo-go 支持的多种 RPC 协议示例。
   * `rpc/dubbo`:Dubbo 协议示例,包含 Java–Go 互操作。
   * `rpc/grpc`:基于 gRPC 协议的示例。
diff --git a/router/static_config/README.md b/router/static_config/README.md
new file mode 100644
index 00000000..56b52b02
--- /dev/null
+++ b/router/static_config/README.md
@@ -0,0 +1,27 @@
+# Static router configuration
+
+This directory contains static router samples configured directly in code.
+Here, `static_config` means the router rules are injected statically on the 
consumer side, instead of being delivered dynamically from a config center.
+
+English | [中文](README_CN.md)
+
+## Prerequisites
+
+- Go 1.25+.
+
+## Sub-samples
+
+- `condition`: service-scope static condition router sample with direct URLs
+- `tag`: application-scope static tag router sample with direct URLs
+
+## How to use
+
+Choose one sub-sample and follow its own README:
+
+- `condition/README.md`
+- `tag/README.md`
+
+The `condition` sample uses direct URLs only.
+The `tag` sample uses direct URLs only.
+Neither sample requires a config center.
+Each sub-sample can be run locally after following its own prerequisites and 
setup steps.
diff --git a/router/static_config/README_CN.md 
b/router/static_config/README_CN.md
new file mode 100644
index 00000000..f6a9707b
--- /dev/null
+++ b/router/static_config/README_CN.md
@@ -0,0 +1,27 @@
+# 静态路由配置
+
+这个目录用于展示如何在代码中直接配置 Dubbo-Go 的静态路由。
+这里的 `static_config` 指的是:在 consumer 侧通过代码静态注入路由规则,而不是从配置中心动态下发。
+
+[English](README.md) | 中文
+
+## 前置准备
+
+- Go 1.25+。
+
+## 子示例
+
+- `condition`:基于直连地址的服务级静态条件路由示例
+- `tag`:基于直连地址的应用级静态标签路由示例
+
+## 如何使用
+
+进入对应子目录,按各自 README 运行:
+
+- `condition/README_CN.md`
+- `tag/README_CN.md`
+
+`condition` 示例只使用直连 URL。
+`tag` 示例只使用直连 URL。
+两个示例都不需要配置中心。
+每个子示例都需要先完成各自 README 中的前置准备和启动步骤。
diff --git a/router/static_config/condition/README.md 
b/router/static_config/condition/README.md
new file mode 100644
index 00000000..3aebac2e
--- /dev/null
+++ b/router/static_config/condition/README.md
@@ -0,0 +1,59 @@
+# Static condition router
+
+This example shows how to configure Dubbo-Go's condition router statically in 
code with direct provider URLs.
+
+English | [中文](README_CN.md)
+
+## Prerequisites
+
+- Go 1.25+.
+
+## What this sample demonstrates
+
+- Two providers listening directly on ports `20000` and `20001`
+- A service-scope static condition router configured by `dubbo.WithRouter(...)`
+- A `force=true` rule that routes `Greet` requests to port `20000`
+
+## How to run
+
+### Run providers
+
+Start two providers in separate terminals:
+
+```shell
+$ go run ./go-server/cmd/server.go
+$ go run ./go-node2-server/cmd/server_node2.go
+```
+
+- `go-server` listens on `:20000`
+- `go-node2-server` listens on `:20001`
+
+### Run consumer
+
+If you want to change the provider addresses, update `directURL` in 
`go-client/cmd/client.go`.
+
+```shell
+$ go run ./go-client/cmd/client.go
+```
+
+The client connects to both providers by direct URLs.
+No registry or config center is required.
+
+## Expected result
+
+- The client logs `invoke successfully: receive: static condition router, 
response from: server-node-20000`
+
+## Key router config
+
+The consumer injects this service-scope static condition router:
+
+```go
+dubbo.WithRouter(
+    router.WithScope("service"),
+    router.WithKey(greet.GreetServiceName),
+    router.WithForce(true),
+    router.WithConditions([]string{
+        "method = Greet => port = 20000",
+    }),
+)
+```
diff --git a/router/static_config/condition/README_CN.md 
b/router/static_config/condition/README_CN.md
new file mode 100644
index 00000000..3a5794d7
--- /dev/null
+++ b/router/static_config/condition/README_CN.md
@@ -0,0 +1,59 @@
+# 静态条件路由
+
+这个示例展示了如何在代码中直接配置 Dubbo-Go 的静态条件路由,并通过直连地址访问服务实例。
+
+[English](README.md) | 中文
+
+## 前置准备
+
+- Go 1.25+。
+
+## 这个示例演示了什么
+
+- 两个通过直连地址访问的 provider,分别监听 `20000` 和 `20001`
+- 使用 `dubbo.WithRouter(...)` 配置服务级静态 condition router
+- 通过 `force=true` 规则把 `Greet` 请求固定路由到 `20000`
+
+## 如何运行
+
+### 启动 Provider
+
+在两个终端中分别启动下面两个 provider:
+
+```shell
+$ go run ./go-server/cmd/server.go
+$ go run ./go-node2-server/cmd/server_node2.go
+```
+
+- `go-server` 监听 `:20000`
+- `go-node2-server` 监听 `:20001`
+
+### 启动 Consumer
+
+如果你需要修改 provider 地址,请同步修改 `go-client/cmd/client.go` 中的 `directURL`。
+
+```shell
+$ go run ./go-client/cmd/client.go
+```
+
+客户端会通过直连 URL 连接两个 provider。
+这个示例不需要注册中心和配置中心。
+
+## 预期结果
+
+- 客户端会打印 `invoke successfully: receive: static condition router, response 
from: server-node-20000`
+
+## 关键路由配置
+
+consumer 注入的是一个服务级静态 condition router:
+
+```go
+dubbo.WithRouter(
+    router.WithScope("service"),
+    router.WithKey(greet.GreetServiceName),
+    router.WithForce(true),
+    router.WithConditions([]string{
+        "method = Greet => port = 20000",
+    }),
+)
+```
diff --git a/router/static_config/condition/go-client/cmd/client.go 
b/router/static_config/condition/go-client/cmd/client.go
new file mode 100644
index 00000000..f0936b8f
--- /dev/null
+++ b/router/static_config/condition/go-client/cmd/client.go
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+       "fmt"
+       "os"
+       "strings"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+       "dubbo.apache.org/dubbo-go/v3/client"
+       "dubbo.apache.org/dubbo-go/v3/cluster/router"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/direct/proto"
+)
+
+const (
+       clientApplication = "static-condition-client"
+       directURL         = "tri://127.0.0.1:20000;tri://127.0.0.1:20001"
+       expectedServer    = "server-node-20000"
+       attemptCount      = 5
+)
+
+func main() {
+       ins, err := dubbo.NewInstance(
+               dubbo.WithName(clientApplication),
+               dubbo.WithRouter(
+                       router.WithScope("service"),
+                       router.WithKey(greet.GreetServiceName),
+                       router.WithPriority(100),
+                       router.WithForce(true),
+                       router.WithConditions([]string{
+                               "method = Greet => port = 20000",
+                       }),
+               ),
+       )
+       if err != nil {
+               logger.Errorf("new instance failed: %v", err)
+               panic(err)
+       }
+
+       cli, err := ins.NewClient(client.WithClientURL(directURL))
+       if err != nil {
+               logger.Errorf("new client failed: %v", err)
+               panic(err)
+       }
+
+       svc, err := greet.NewGreetService(cli)
+       if err != nil {
+               logger.Errorf("new service failed: %v", err)
+               panic(err)
+       }
+
+       for i := 1; i <= attemptCount; i++ {
+               resp, err := svc.Greet(context.Background(), 
&greet.GreetRequest{
+                       Name: fmt.Sprintf("static condition router attempt %d", 
i),
+               })
+               if err != nil {
+                       logger.Errorf("invoke failed on attempt %d/%d: %v", i, 
attemptCount, err)
+                       os.Exit(1)
+               }
+
+               if !strings.Contains(resp.Greeting, expectedServer) {
+                       logger.Errorf("routed to unexpected server on attempt 
%d/%d, want %s, got %q",
+                               i, attemptCount, expectedServer, resp.Greeting)
+                       os.Exit(1)
+               }
+
+               logger.Infof("invoke successfully on attempt %d/%d: %v", i, 
attemptCount, resp.Greeting)
+       }
+}
diff --git a/router/static_config/condition/go-node2-server/cmd/server_node2.go 
b/router/static_config/condition/go-node2-server/cmd/server_node2.go
new file mode 100644
index 00000000..c723d78e
--- /dev/null
+++ b/router/static_config/condition/go-node2-server/cmd/server_node2.go
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       "dubbo.apache.org/dubbo-go/v3/protocol"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/direct/proto"
+)
+
+const (
+       providerApplication = "static-condition-provider"
+       triPort             = 20001
+       serverName          = "server-node-20001"
+)
+
+type GreetServer struct{}
+
+func (s *GreetServer) Greet(_ context.Context, req *greet.GreetRequest) 
(*greet.GreetResponse, error) {
+       logger.Infof("%s received request: %s", serverName, req.Name)
+       return &greet.GreetResponse{
+               Greeting: "receive: " + req.Name + ", response from: " + 
serverName,
+       }, nil
+}
+
+func main() {
+       ins, err := dubbo.NewInstance(
+               dubbo.WithName(providerApplication),
+               dubbo.WithProtocol(
+                       protocol.WithTriple(),
+                       protocol.WithPort(triPort),
+               ),
+       )
+       if err != nil {
+               panic(err)
+       }
+
+       srv, err := ins.NewServer()
+       if err != nil {
+               panic(err)
+       }
+
+       if err := greet.RegisterGreetServiceHandler(srv, &GreetServer{}); err 
!= nil {
+               panic(err)
+       }
+
+       logger.Infof("%s started on :%d", serverName, triPort)
+       if err := srv.Serve(); err != nil {
+               logger.Errorf("%s stopped: %v", serverName, err)
+       }
+}
diff --git a/router/static_config/condition/go-server/cmd/server.go 
b/router/static_config/condition/go-server/cmd/server.go
new file mode 100644
index 00000000..18582ac0
--- /dev/null
+++ b/router/static_config/condition/go-server/cmd/server.go
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       "dubbo.apache.org/dubbo-go/v3/protocol"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/direct/proto"
+)
+
+const (
+       providerApplication = "static-condition-provider"
+       triPort             = 20000
+       serverName          = "server-node-20000"
+)
+
+type GreetServer struct{}
+
+func (s *GreetServer) Greet(_ context.Context, req *greet.GreetRequest) 
(*greet.GreetResponse, error) {
+       logger.Infof("%s received request: %s", serverName, req.Name)
+       return &greet.GreetResponse{
+               Greeting: "receive: " + req.Name + ", response from: " + 
serverName,
+       }, nil
+}
+
+func main() {
+       ins, err := dubbo.NewInstance(
+               dubbo.WithName(providerApplication),
+               dubbo.WithProtocol(
+                       protocol.WithTriple(),
+                       protocol.WithPort(triPort),
+               ),
+       )
+       if err != nil {
+               panic(err)
+       }
+
+       srv, err := ins.NewServer()
+       if err != nil {
+               panic(err)
+       }
+
+       if err := greet.RegisterGreetServiceHandler(srv, &GreetServer{}); err 
!= nil {
+               panic(err)
+       }
+
+       logger.Infof("%s started on :%d", serverName, triPort)
+       if err := srv.Serve(); err != nil {
+               logger.Errorf("%s stopped: %v", serverName, err)
+       }
+}
diff --git a/router/static_config/tag/README.md 
b/router/static_config/tag/README.md
new file mode 100644
index 00000000..10eb9f04
--- /dev/null
+++ b/router/static_config/tag/README.md
@@ -0,0 +1,78 @@
+# Static tag router
+
+This example shows how to configure Dubbo-Go's tag router statically in code, 
without a registry or config center.
+
+English | [中文](README_CN.md)
+
+## Prerequisites
+
+- Go 1.25+.
+
+## What this sample demonstrates
+
+- One untagged provider on port `20000`
+- One `gray` tagged provider on port `20002`
+- An application-scope static tag router configured by `dubbo.WithRouter(...)`
+
+## How to run
+
+### Run providers
+
+Start two providers in separate terminals:
+
+```shell
+$ go run ./go-server/cmd/server.go
+$ go run ./go-tag-server/cmd/server_tag.go
+```
+
+- `go-server` listens on `:20000` without a tag
+- `go-tag-server` listens on `:20002` and exports the service with tag `gray`
+
+### Run consumer
+
+```shell
+$ go run ./go-client/cmd/client.go
+```
+
+The client uses direct URLs only:
+
+```text
+tri://127.0.0.1:20000;tri://127.0.0.1:20002?dubbo.tag=gray
+```
+
+No registry or config center is required.
+
+## Expected result
+
+The client runs a single scenario and routes to `server-with-gray-tag`.
+You should see logs similar to:
+
+```text
+INFO ... invoke successfully: receive: static tag router, response from: 
server-with-gray-tag
+```
+
+## Key router config
+
+Static tag router:
+
+```go
+dubbo.WithRouter(
+    router.WithScope("application"),
+    router.WithKey("static-tag-provider"),
+    router.WithForce(false),
+    router.WithTags([]global.Tag{
+        {
+            Name:      "gray",
+            Addresses: []string{"127.0.0.1:20002"},
+        },
+    }),
+)
+```
+
+Request with tag attachment:
+
+```go
+ctx := context.WithValue(context.Background(), constant.AttachmentKey, 
map[string]string{
+    constant.Tagkey: "gray",
+})
+```
diff --git a/router/static_config/tag/README_CN.md 
b/router/static_config/tag/README_CN.md
new file mode 100644
index 00000000..ca357f7f
--- /dev/null
+++ b/router/static_config/tag/README_CN.md
@@ -0,0 +1,78 @@
+# 静态标签路由
+
+这个示例展示了如何在代码中直接配置 Dubbo-Go 的静态标签路由,不依赖注册中心和配置中心。
+
+[English](README.md) | 中文
+
+## 前置准备
+
+- Go 1.25+。
+
+## 这个示例演示了什么
+
+- 一个不带 tag 的 provider,监听 `20000`
+- 一个带 `gray` tag 的 provider,监听 `20002`
+- 使用 `dubbo.WithRouter(...)` 配置应用级静态 tag router
+
+## 如何运行
+
+### 启动 Provider
+
+在两个终端中分别启动下面两个 provider:
+
+```shell
+$ go run ./go-server/cmd/server.go
+$ go run ./go-tag-server/cmd/server_tag.go
+```
+
+- `go-server` 监听 `:20000`,不带 tag
+- `go-tag-server` 监听 `:20002`,并以 `gray` 标签导出服务
+
+### 启动 Consumer
+
+```shell
+$ go run ./go-client/cmd/client.go
+```
+
+客户端只使用直连 URL:
+
+```text
+tri://127.0.0.1:20000;tri://127.0.0.1:20002?dubbo.tag=gray
+```
+
+这个示例不需要注册中心,也不需要配置中心。
+
+## 预期结果
+
+客户端会运行一个场景,并路由到 `server-with-gray-tag`。
+你会看到类似下面的日志:
+
+```text
+INFO ... invoke successfully: receive: static tag router, response from: 
server-with-gray-tag
+```
+
+## 关键路由配置
+
+静态 tag router:
+
+```go
+dubbo.WithRouter(
+    router.WithScope("application"),
+    router.WithKey("static-tag-provider"),
+    router.WithForce(false),
+    router.WithTags([]global.Tag{
+        {
+            Name:      "gray",
+            Addresses: []string{"127.0.0.1:20002"},
+        },
+    }),
+)
+```
+
+携带请求 tag:
+
+```go
+ctx := context.WithValue(context.Background(), constant.AttachmentKey, 
map[string]string{
+    constant.Tagkey: "gray",
+})
+```
diff --git a/router/static_config/tag/go-client/cmd/client.go 
b/router/static_config/tag/go-client/cmd/client.go
new file mode 100644
index 00000000..931b706e
--- /dev/null
+++ b/router/static_config/tag/go-client/cmd/client.go
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+       "fmt"
+       "os"
+       "strings"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+       "dubbo.apache.org/dubbo-go/v3/client"
+       "dubbo.apache.org/dubbo-go/v3/cluster/router"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/global"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/direct/proto"
+)
+
+const (
+       clientApplication = "static-tag-client"
+       tagName           = "gray"
+       grayAddress       = "127.0.0.1:20002"
+       directURL         = 
"tri://127.0.0.1:20000;tri://127.0.0.1:20002?dubbo.tag=gray"
+       expectedServer    = "server-with-gray-tag"
+       attemptCount      = 5
+)
+
+func main() {
+       ins, err := dubbo.NewInstance(
+               dubbo.WithName(clientApplication),
+               dubbo.WithRouter(
+                       router.WithScope("application"),
+                       router.WithKey("static-tag-provider"),
+                       router.WithPriority(100),
+                       router.WithForce(false),
+                       router.WithTags([]global.Tag{
+                               {
+                                       Name:      tagName,
+                                       Addresses: []string{grayAddress},
+                               },
+                       }),
+               ),
+       )
+       if err != nil {
+               logger.Errorf("new instance failed: %v", err)
+               panic(err)
+       }
+
+       cli, err := ins.NewClient(client.WithClientURL(directURL))
+       if err != nil {
+               logger.Errorf("new client failed: %v", err)
+               panic(err)
+       }
+
+       svc, err := greet.NewGreetService(cli)
+       if err != nil {
+               logger.Errorf("new service failed: %v", err)
+               panic(err)
+       }
+
+       ctx := context.WithValue(context.Background(), constant.AttachmentKey, 
map[string]string{
+               constant.Tagkey: tagName,
+       })
+
+       for i := 1; i <= attemptCount; i++ {
+               resp, err := svc.Greet(ctx, &greet.GreetRequest{
+                       Name: fmt.Sprintf("static tag router attempt %d", i),
+               })
+               if err != nil {
+                       logger.Errorf("invoke failed on attempt %d/%d: %v", i, 
attemptCount, err)
+                       os.Exit(1)
+               }
+
+               if !strings.Contains(resp.Greeting, expectedServer) {
+                       logger.Errorf("routed to unexpected server on attempt 
%d/%d, want %s, got %q",
+                               i, attemptCount, expectedServer, resp.Greeting)
+                       os.Exit(1)
+               }
+
+               logger.Infof("invoke successfully on attempt %d/%d: %v", i, 
attemptCount, resp.Greeting)
+       }
+}
diff --git a/router/static_config/tag/go-server/cmd/server.go 
b/router/static_config/tag/go-server/cmd/server.go
new file mode 100644
index 00000000..12fa2f33
--- /dev/null
+++ b/router/static_config/tag/go-server/cmd/server.go
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       "dubbo.apache.org/dubbo-go/v3/protocol"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/direct/proto"
+)
+
+const (
+       providerApplication = "static-tag-provider"
+       triPort             = 20000
+       serverName          = "server-without-tag"
+)
+
+type GreetServer struct{}
+
+func (s *GreetServer) Greet(_ context.Context, req *greet.GreetRequest) 
(*greet.GreetResponse, error) {
+       logger.Infof("%s received request: %s", serverName, req.Name)
+       return &greet.GreetResponse{
+               Greeting: "receive: " + req.Name + ", response from: " + 
serverName,
+       }, nil
+}
+
+func main() {
+       ins, err := dubbo.NewInstance(
+               dubbo.WithName(providerApplication),
+               dubbo.WithProtocol(
+                       protocol.WithTriple(),
+                       protocol.WithPort(triPort),
+               ),
+       )
+       if err != nil {
+               panic(err)
+       }
+
+       srv, err := ins.NewServer()
+       if err != nil {
+               panic(err)
+       }
+
+       if err := greet.RegisterGreetServiceHandler(srv, &GreetServer{}); err 
!= nil {
+               panic(err)
+       }
+
+       logger.Infof("%s started on :%d", serverName, triPort)
+       if err := srv.Serve(); err != nil {
+               logger.Errorf("%s stopped: %v", serverName, err)
+       }
+}
diff --git a/router/static_config/tag/go-tag-server/cmd/server_tag.go 
b/router/static_config/tag/go-tag-server/cmd/server_tag.go
new file mode 100644
index 00000000..e7a0faf6
--- /dev/null
+++ b/router/static_config/tag/go-tag-server/cmd/server_tag.go
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       "dubbo.apache.org/dubbo-go/v3/protocol"
+       "dubbo.apache.org/dubbo-go/v3/server"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/direct/proto"
+)
+
+const (
+       providerApplication = "static-tag-provider"
+       triPort             = 20002
+       serverName          = "server-with-gray-tag"
+)
+
+type GreetServer struct{}
+
+func (s *GreetServer) Greet(_ context.Context, req *greet.GreetRequest) 
(*greet.GreetResponse, error) {
+       logger.Infof("%s received request: %s", serverName, req.Name)
+       return &greet.GreetResponse{
+               Greeting: "receive: " + req.Name + ", response from: " + 
serverName,
+       }, nil
+}
+
+func main() {
+       ins, err := dubbo.NewInstance(
+               dubbo.WithName(providerApplication),
+               dubbo.WithProtocol(
+                       protocol.WithTriple(),
+                       protocol.WithPort(triPort),
+               ),
+       )
+       if err != nil {
+               panic(err)
+       }
+
+       srv, err := ins.NewServer()
+       if err != nil {
+               panic(err)
+       }
+
+       if err := greet.RegisterGreetServiceHandler(srv, &GreetServer{}, 
server.WithTag("gray")); err != nil {
+               panic(err)
+       }
+
+       logger.Infof("%s started on :%d with tag gray", serverName, triPort)
+       if err := srv.Serve(); err != nil {
+               logger.Errorf("%s stopped: %v", serverName, err)
+       }
+}
diff --git a/start_integrate_test.sh b/start_integrate_test.sh
index 7706ea76..91200bc9 100755
--- a/start_integrate_test.sh
+++ b/start_integrate_test.sh
@@ -97,6 +97,8 @@ array+=("java_interop/service_discovery/service")
 
 # router
 array+=("router/tag")
+array+=("router/static_config/tag")
+array+=("router/static_config/condition")
 
 DOCKER_DIR="$(pwd)"
 DOCKER_COMPOSE_CMD="docker-compose"

Reply via email to