From 066c169845d48194761e8db9f3884d367eb64f15 Mon Sep 17 00:00:00 2001
From: Asim <asim@chuhnk.me>
Date: Wed, 9 Dec 2015 15:06:31 +0000
Subject: [PATCH] Add example dc filter

---
 examples/client/dc_filter/dc_filter.go | 84 ++++++++++++++++++++++++++
 examples/server/main.go                |  4 ++
 2 files changed, 88 insertions(+)
 create mode 100644 examples/client/dc_filter/dc_filter.go

diff --git a/examples/client/dc_filter/dc_filter.go b/examples/client/dc_filter/dc_filter.go
new file mode 100644
index 00000000..1795edc5
--- /dev/null
+++ b/examples/client/dc_filter/dc_filter.go
@@ -0,0 +1,84 @@
+package main
+
+import (
+	"fmt"
+	"math/rand"
+	"time"
+
+	"github.com/micro/go-micro/client"
+	"github.com/micro/go-micro/cmd"
+	c "github.com/micro/go-micro/context"
+	example "github.com/micro/go-micro/examples/server/proto/example"
+	"github.com/micro/go-micro/registry"
+	"golang.org/x/net/context"
+)
+
+func init() {
+	rand.Seed(time.Now().Unix())
+}
+
+// A Wrapper that creates a Datacenter Selector Option
+type dcWrapper struct {
+	client.Client
+}
+
+func (dc *dcWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
+	md, _ := c.GetMetadata(ctx)
+
+	filter := func(services []*registry.Service) []*registry.Service {
+		for _, service := range services {
+			var nodes []*registry.Node
+			for _, node := range service.Nodes {
+				if node.Metadata["datacenter"] == md["datacenter"] {
+					nodes = append(nodes, node)
+				}
+			}
+			service.Nodes = nodes
+		}
+		return services
+	}
+
+	callOptions := append(opts, client.WithSelectOption(registry.SelectFilter(filter)))
+
+	fmt.Printf("[DC Wrapper] filtering for datacenter %s\n", md["datacenter"])
+	return dc.Client.Call(ctx, req, rsp, callOptions...)
+}
+
+func NewDCWrapper(c client.Client) client.Client {
+	return &dcWrapper{c}
+}
+
+func call(i int) {
+	// Create new request to service go.micro.srv.example, method Example.Call
+	req := client.NewRequest("go.micro.srv.example", "Example.Call", &example.Request{
+		Name: "John",
+	})
+
+	// create context with metadata
+	ctx := c.WithMetadata(context.Background(), map[string]string{
+		"datacenter": "local",
+	})
+
+	rsp := &example.Response{}
+
+	// Call service
+	if err := client.Call(ctx, req, rsp); err != nil {
+		fmt.Println("call err: ", err, rsp)
+		return
+	}
+
+	fmt.Println("Call:", i, "rsp:", rsp.Msg)
+}
+
+func main() {
+	cmd.Init()
+
+	client.DefaultClient = client.NewClient(
+		client.Wrap(NewDCWrapper),
+	)
+
+	fmt.Println("\n--- Call example ---\n")
+	for i := 0; i < 10; i++ {
+		call(i)
+	}
+}
diff --git a/examples/server/main.go b/examples/server/main.go
index 0f5e8329..193fd499 100644
--- a/examples/server/main.go
+++ b/examples/server/main.go
@@ -31,9 +31,13 @@ func main() {
 	// optionally setup command line usage
 	cmd.Init()
 
+	md := server.Config().Metadata()
+	md["datacenter"] = "local"
+
 	server.DefaultServer = server.NewServer(
 		server.WrapHandler(logWrapper),
 		server.WrapSubscriber(logSubWrapper),
+		server.Metadata(md),
 	)
 
 	// Initialise Server