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

ztelur pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go-pixiu.git


The following commit(s) were added to refs/heads/develop by this push:
     new 7946f64  add http2 listener for grpc proxy (#315)
7946f64 is described below

commit 7946f64f3773c91a09d12b70cf5f75e196747f62
Author: randy <[email protected]>
AuthorDate: Mon Jan 3 15:58:53 2022 +0800

    add http2 listener for grpc proxy (#315)
    
    * split listener service interface
    
    * split listener service interface
    
    * update
    
    * update
    
    * update
    
    * update
    
    * add integration test
    
    * add integration test
    
    * update
    
    * fix golangci-lint
    
    * update
    
    * fix reviewdog
    
    * fix reviewdog
    
    * fix reviewdog
    
    * update for comment
    
    * rename to NetworkFilterChain
    
    * update
    
    Co-authored-by: Mark4z <[email protected]>
    Co-authored-by: Xin.Zh <[email protected]>
---
 docs/sample/dubbo/dubbo-registry.md                |   6 +-
 docs/sample/http/http-grpc.md                      |   6 +-
 docs/sample/http/http-http.md                      |   6 +-
 docs/user/config.md                                |   6 +-
 go.mod                                             |   4 +-
 go.sum                                             |   1 +
 pkg/common/constant/key.go                         |   1 +
 pkg/common/extension/filter/filter.go              |   5 +-
 .../listener.go => common/grpc/RoundTripper.go}    |  21 +-
 pkg/common/grpc/manager.go                         | 143 +++++++++
 pkg/common/http/manager.go                         |  40 ++-
 pkg/common/router/router.go                        |  13 +-
 pkg/common/router/router_test.go                   |   2 +-
 pkg/config/conf_test.yaml                          |   6 +-
 pkg/config/config_load.go                          |   6 +-
 pkg/config/config_load_test.go                     |  26 +-
 pkg/context/http/context.go                        |   1 -
 .../network/grpcconnectionmanager/plugin.go}       |  44 +--
 pkg/filterchain/network_filter_chain.go            |  84 ++++++
 .../listener.go => listener/http/http_listener.go} | 136 +++------
 pkg/listener/http2/http2_listener.go               | 121 ++++++++
 pkg/listener/listener.go                           |  57 ++++
 pkg/{server => listener}/listener_test.go          |  19 +-
 pkg/model/base.go                                  |  46 +--
 pkg/model/filter.go                                |   7 +-
 pkg/model/http.go                                  |   5 +
 pkg/model/listener.go                              |  57 +++-
 pkg/model/router.go                                |  10 +-
 pkg/pluginregistry/registry.go                     |   3 +
 pkg/server/listener_manager.go                     |  35 +--
 samples/dubbogo/http/pixiu/conf.yaml               |   6 +-
 samples/dubbogo/multi/config/conf.yaml             |   6 +-
 samples/dubbogo/simple/body/pixiu/conf.yaml        |   2 +-
 samples/dubbogo/simple/csrf/pixiu/conf.yaml        |   5 -
 samples/dubbogo/simple/jaeger/pixiu/conf.yaml      |   2 +-
 samples/dubbogo/simple/mix/pixiu/conf.yaml         |   6 +-
 samples/dubbogo/simple/proxy/pixiu/conf.yaml       |   6 +-
 samples/dubbogo/simple/query/pixiu/conf.yaml       |   6 +-
 .../darwin_amd64/pixiuconf}/conf.yaml              |   5 +-
 .../dist/darwin_amd64/server/log.yml}              |  56 ++--
 .../dist/darwin_amd64/server/server.yml}           |  52 ++--
 samples/dubbogo/simple/registry/pixiu/conf.yaml    |   6 +-
 samples/dubbogo/simple/triple/pixiu/conf.yaml      |   3 +-
 samples/dubbogo/simple/uri/conf.yaml               |   2 +-
 samples/dubbogo/simple/uri/pixiu/conf.yaml         |   6 +-
 samples/{http => }/grpc/pixiu/conf.yaml            |  17 +-
 samples/grpc/proto/hello_grpc.pb.go                | 320 +++++++++++++++++++++
 samples/grpc/proto/hello_grpc.proto                |  40 +++
 samples/grpc/proto/hello_grpc_grpc.pb.go           | 116 ++++++++
 samples/grpc/server/app/server.go                  |  85 ++++++
 .../grpc/test/pixiu_test.go                        |  55 ++--
 samples/http/grpc/pixiu/conf.yaml                  |   6 +-
 samples/http/simple/pixiu/conf.yaml                |   6 +-
 samples/https/pixiu/conf.yaml                      |   6 +-
 samples/seata/gateway/conf.yaml                    |  18 +-
 samples/seata/sidecar/server_a/conf.yaml           |   6 +-
 samples/seata/sidecar/server_b/conf.yaml           |   6 +-
 samples/seata/sidecar/server_c/conf.yaml           |   6 +-
 samples/springcloud/pixiu/conf.yaml                |   6 +-
 start_integrate_test.sh                            |   2 +
 60 files changed, 1315 insertions(+), 466 deletions(-)

diff --git a/docs/sample/dubbo/dubbo-registry.md 
b/docs/sample/dubbo/dubbo-registry.md
index 28202c8..8564e88 100644
--- a/docs/sample/dubbo/dubbo-registry.md
+++ b/docs/sample/dubbo/dubbo-registry.md
@@ -8,16 +8,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/docs/sample/http/http-grpc.md b/docs/sample/http/http-grpc.md
index 24b8eb8..3dfaaf7 100644
--- a/docs/sample/http/http-grpc.md
+++ b/docs/sample/http/http-grpc.md
@@ -8,16 +8,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/docs/sample/http/http-http.md b/docs/sample/http/http-http.md
index c854e4b..19c2e3e 100644
--- a/docs/sample/http/http-http.md
+++ b/docs/sample/http/http-http.md
@@ -9,16 +9,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/docs/user/config.md b/docs/user/config.md
index 9cb00ab..9c1c082 100644
--- a/docs/user/config.md
+++ b/docs/user/config.md
@@ -16,16 +16,12 @@ This document mainly describes the pixiu config 
abstraction, there is a example
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/go.mod b/go.mod
index 60a1611..4db1fbc 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
        github.com/dubbogo/dubbo-go-pixiu-filter v0.1.4
        github.com/dubbogo/go-zookeeper v1.0.3
        github.com/dubbogo/gost v1.11.19
-       github.com/emirpasic/gods v1.12.0
+       github.com/emirpasic/gods v1.12.0 // indirect
        github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
        github.com/gin-gonic/gin v1.7.4
        github.com/go-playground/assert/v2 v2.0.1
@@ -22,6 +22,7 @@ require (
        github.com/goinggo/mapstructure v0.0.0-20140717182941-194205d9b4a9
        github.com/golang-jwt/jwt/v4 v4.1.0
        github.com/golang/protobuf v1.5.2
+       github.com/gorilla/mux v1.7.3 // indirect
        github.com/jhump/protoreflect v1.9.0
        github.com/mercari/grpc-http-proxy v0.1.2
        github.com/mitchellh/mapstructure v1.4.2
@@ -45,6 +46,7 @@ require (
        go.opentelemetry.io/otel/trace v1.0.0-RC2
        go.uber.org/zap v1.19.1
        golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
+       golang.org/x/net v0.0.0-20211105192438-b53810dc28af
        google.golang.org/grpc v1.42.0
        google.golang.org/protobuf v1.27.1
        gopkg.in/yaml.v2 v2.4.0
diff --git a/go.sum b/go.sum
index ebd28f4..61e837d 100644
--- a/go.sum
+++ b/go.sum
@@ -439,6 +439,7 @@ github.com/gopherjs/gopherjs 
v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORR
 github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod 
h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
 github.com/gorilla/context v1.1.1/go.mod 
h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/mux v1.6.2/go.mod 
h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
 github.com/gorilla/mux v1.7.3/go.mod 
h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod 
h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.0/go.mod 
h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
diff --git a/pkg/common/constant/key.go b/pkg/common/constant/key.go
index 884ee89..1fc0395 100644
--- a/pkg/common/constant/key.go
+++ b/pkg/common/constant/key.go
@@ -19,6 +19,7 @@ package constant
 
 const (
        HTTPConnectManagerFilter = "dgp.filter.httpconnectionmanager"
+       GRPCConnectManagerFilter = "dgp.filter.grpcconnectionmanager"
 
        HTTPAuthorityFilter    = "dgp.filter.http.authority"
        HTTPProxyFilter        = "dgp.filter.http.httpproxy"
diff --git a/pkg/common/extension/filter/filter.go 
b/pkg/common/extension/filter/filter.go
index 5c203c1..d3030e7 100644
--- a/pkg/common/extension/filter/filter.go
+++ b/pkg/common/extension/filter/filter.go
@@ -19,6 +19,7 @@ package filter
 
 import (
        "fmt"
+       stdHttp "net/http"
 )
 
 import (
@@ -83,8 +84,8 @@ type (
 
        // NetworkFilter describe network filter
        NetworkFilter interface {
-               // OnData handle the http context from worker
-               OnData(hc *http.HttpContext) error
+               // ServeHTTP handle request and response
+               ServeHTTP(w stdHttp.ResponseWriter, r *stdHttp.Request)
        }
 )
 
diff --git a/pkg/model/listener.go b/pkg/common/grpc/RoundTripper.go
similarity index 67%
copy from pkg/model/listener.go
copy to pkg/common/grpc/RoundTripper.go
index 730f00d..6e44e44 100644
--- a/pkg/model/listener.go
+++ b/pkg/common/grpc/RoundTripper.go
@@ -15,13 +15,20 @@
  * limitations under the License.
  */
 
-package model
+package grpc
 
-// Listener is a server, listener a port
-type Listener struct {
-       Name    string  `yaml:"name" json:"name" mapstructure:"name"`
-       Address Address `yaml:"address" json:"address" mapstructure:"address"`
+import (
+       "net/http"
+)
 
-       FilterChains []FilterChain `yaml:"filter_chains" json:"filter_chains" 
mapstructure:"filter_chains"`
-       Config       interface{}   `yaml:"config" json:"config" 
mapstructure:"config"`
+import (
+       "golang.org/x/net/http2"
+)
+
+type HttpForwarder struct {
+       transport *http2.Transport
+}
+
+func (hf *HttpForwarder) Forward(r *http.Request) (*http.Response, error) {
+       return hf.transport.RoundTrip(r)
 }
diff --git a/pkg/common/grpc/manager.go b/pkg/common/grpc/manager.go
new file mode 100644
index 0000000..cf88cc4
--- /dev/null
+++ b/pkg/common/grpc/manager.go
@@ -0,0 +1,143 @@
+/*
+ * 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 grpc
+
+import (
+       "context"
+       "crypto/tls"
+       "encoding/json"
+       "io/ioutil"
+       "net"
+       stdHttp "net/http"
+)
+
+import (
+       "golang.org/x/net/http2"
+)
+
+import (
+       "github.com/apache/dubbo-go-pixiu/pkg/common/constant"
+       router2 "github.com/apache/dubbo-go-pixiu/pkg/common/router"
+       "github.com/apache/dubbo-go-pixiu/pkg/context/http"
+       pch "github.com/apache/dubbo-go-pixiu/pkg/context/http"
+       "github.com/apache/dubbo-go-pixiu/pkg/logger"
+       "github.com/apache/dubbo-go-pixiu/pkg/model"
+       "github.com/apache/dubbo-go-pixiu/pkg/server"
+)
+
+// GrpcConnectionManager network filter for grpc
+type GrpcConnectionManager struct {
+       config            *model.GRPCConnectionManagerConfig
+       routerCoordinator *router2.RouterCoordinator
+}
+
+// CreateGrpcConnectionManager create grpc connection manager
+func CreateGrpcConnectionManager(hcmc *model.GRPCConnectionManagerConfig, bs 
*model.Bootstrap) *GrpcConnectionManager {
+       hcm := &GrpcConnectionManager{config: hcmc}
+       hcm.routerCoordinator = 
router2.CreateRouterCoordinator(&hcmc.RouteConfig)
+       return hcm
+}
+
+// OnData receive data from listener
+func (gcm *GrpcConnectionManager) OnData(hc *pch.HttpContext) error {
+       panic("grpc connection manager OnData function shouldn't be called")
+}
+
+// ServeHTTP handle request and response
+func (gcm *GrpcConnectionManager) ServeHTTP(w stdHttp.ResponseWriter, r 
*stdHttp.Request) {
+
+       ra, err := gcm.routerCoordinator.RouteByPathAndName(r.RequestURI, 
r.Method)
+       if err != nil {
+               logger.Info("GrpcConnectionManager can't find route %v", err)
+               w.WriteHeader(stdHttp.StatusNotFound)
+               if _, err := w.Write(constant.Default404Body); err != nil {
+                       logger.Warnf("WriteWithStatus error %v", err)
+               }
+       }
+
+       logger.Debugf("[dubbo-go-pixiu] client choose endpoint from cluster 
:%v", ra.Cluster)
+
+       clusterName := ra.Cluster
+       clusterManager := server.GetClusterManager()
+       endpoint := clusterManager.PickEndpoint(clusterName)
+       if endpoint == nil {
+               bt, _ := json.Marshal(http.ErrResponse{Message: "cluster not 
found endpoint"})
+               w.WriteHeader(stdHttp.StatusServiceUnavailable)
+               w.Write(bt)
+               return
+       }
+
+       newReq := r.Clone(context.Background())
+       newReq.URL.Scheme = "http"
+       newReq.URL.Host = endpoint.Address.GetAddress()
+
+       // todo: need cache?
+       forwarder := gcm.newHttpForwarder()
+       res, err := forwarder.Forward(newReq)
+
+       if err != nil {
+               logger.Info("GrpcConnectionManager forward request error %v", 
err)
+               bt, _ := json.Marshal(http.ErrResponse{Message: "pixiu forward 
error"})
+               w.WriteHeader(stdHttp.StatusServiceUnavailable)
+               w.Write(bt)
+               return
+       }
+
+       if err := gcm.response(w, res); err != nil {
+               logger.Info("GrpcConnectionManager response  error %v", err)
+       }
+}
+
+func (gcm *GrpcConnectionManager) response(w stdHttp.ResponseWriter, res 
*stdHttp.Response) error {
+       defer res.Body.Close()
+
+       copyHeader(w.Header(), res.Header)
+       w.WriteHeader(res.StatusCode)
+
+       bytes, err := ioutil.ReadAll(res.Body)
+       if err != nil {
+               return err
+       }
+       w.Write(bytes)
+
+       for k, vv := range res.Trailer {
+               k = stdHttp.TrailerPrefix + k
+               for _, v := range vv {
+                       w.Header().Add(k, v)
+               }
+       }
+       return nil
+}
+
+func (gcm *GrpcConnectionManager) newHttpForwarder() *HttpForwarder {
+       transport := &http2.Transport{
+               DialTLS: func(network, addr string, _ *tls.Config) (net.Conn, 
error) {
+                       return net.Dial(network, addr)
+               },
+               AllowHTTP: true,
+       }
+       return &HttpForwarder{transport: transport}
+}
+
+func copyHeader(dst, src stdHttp.Header) {
+       for k, vv := range src {
+               for _, v := range vv {
+                       dst.Add(k, v)
+               }
+       }
+}
diff --git a/pkg/common/http/manager.go b/pkg/common/http/manager.go
index 2ecb8d7..ae291b8 100644
--- a/pkg/common/http/manager.go
+++ b/pkg/common/http/manager.go
@@ -21,7 +21,8 @@ import (
        "context"
        "fmt"
        "io/ioutil"
-       "net/http"
+       stdHttp "net/http"
+       "sync"
 )
 
 import (
@@ -44,18 +45,27 @@ type HttpConnectionManager struct {
        config            *model.HttpConnectionManagerConfig
        routerCoordinator *router2.RouterCoordinator
        filterManager     *filter.FilterManager
+       pool              sync.Pool
 }
 
 // CreateHttpConnectionManager create http connection manager
 func CreateHttpConnectionManager(hcmc *model.HttpConnectionManagerConfig, bs 
*model.Bootstrap) *HttpConnectionManager {
        hcm := &HttpConnectionManager{config: hcmc}
-       hcm.routerCoordinator = router2.CreateRouterCoordinator(hcmc)
+       hcm.pool.New = func() interface{} {
+               return hcm.allocateContext()
+       }
+       hcm.routerCoordinator = 
router2.CreateRouterCoordinator(&hcmc.RouteConfig)
        hcm.filterManager = filter.NewFilterManager(hcmc.HTTPFilters)
        hcm.filterManager.Load()
        return hcm
 }
 
-// OnData receive data from listener
+func (ls *HttpConnectionManager) allocateContext() *pch.HttpContext {
+       return &pch.HttpContext{
+               Params: make(map[string]interface{}),
+       }
+}
+
 func (hcm *HttpConnectionManager) OnData(hc *pch.HttpContext) error {
        hc.Ctx = context.Background()
        err := hcm.findRoute(hc)
@@ -66,6 +76,20 @@ func (hcm *HttpConnectionManager) OnData(hc 
*pch.HttpContext) error {
        return nil
 }
 
+func (hcm *HttpConnectionManager) ServeHTTP(w stdHttp.ResponseWriter, r 
*stdHttp.Request) {
+       hc := hcm.pool.Get().(*pch.HttpContext)
+       defer hcm.pool.Put(hc)
+
+       hc.Request = r
+       hc.Writer = w
+       hc.Reset()
+
+       err := hcm.OnData(hc)
+       if err != nil {
+               logger.Errorf("ServeHTTP %v", err)
+       }
+}
+
 // handleHTTPRequest handle http request
 func (hcm *HttpConnectionManager) handleHTTPRequest(c *pch.HttpContext) {
        filterChain := hcm.filterManager.CreateFilterChain(c)
@@ -74,7 +98,7 @@ func (hcm *HttpConnectionManager) handleHTTPRequest(c 
*pch.HttpContext) {
        defer func() {
                if err := recover(); err != nil {
                        logger.Warnf("[dubbopixiu go] Occur An Unexpected Err: 
%+v", err)
-                       c.SendLocalReply(http.StatusInternalServerError, 
[]byte(fmt.Sprintf("Occur An Unexpected Err: %v", err)))
+                       c.SendLocalReply(stdHttp.StatusInternalServerError, 
[]byte(fmt.Sprintf("Occur An Unexpected Err: %v", err)))
                }
        }()
 
@@ -101,7 +125,7 @@ func (hcm *HttpConnectionManager) buildTargetResponse(c 
*pch.HttpContext) {
        }
 
        switch res := c.SourceResp.(type) {
-       case *http.Response:
+       case *stdHttp.Response:
                body, err := ioutil.ReadAll(res.Body)
                if err != nil {
                        panic(err)
@@ -115,13 +139,13 @@ func (hcm *HttpConnectionManager) buildTargetResponse(c 
*pch.HttpContext) {
                c.StatusCode(res.StatusCode)
                c.TargetResp = &client.Response{Data: body}
        case []byte:
-               c.StatusCode(http.StatusOK)
+               c.StatusCode(stdHttp.StatusOK)
                c.AddHeader(constant.HeaderKeyContextType, 
constant.HeaderValueTextPlain)
                c.TargetResp = &client.Response{Data: res}
        default:
                //dubbo go generic invoke
                response := util.NewDubboResponse(res, false)
-               c.StatusCode(http.StatusOK)
+               c.StatusCode(stdHttp.StatusOK)
                c.AddHeader(constant.HeaderKeyContextType, 
constant.HeaderValueJsonUtf8)
                c.TargetResp = response
        }
@@ -131,7 +155,7 @@ func (hcm *HttpConnectionManager) findRoute(hc 
*pch.HttpContext) error {
        ra, err := hcm.routerCoordinator.Route(hc)
        if err != nil {
                hc.AddHeader(constant.HeaderKeyContextType, 
constant.HeaderValueTextPlain)
-               hc.SendLocalReply(http.StatusNotFound, constant.Default404Body)
+               hc.SendLocalReply(stdHttp.StatusNotFound, 
constant.Default404Body)
 
                e := errors.Errorf("Requested URL %s not found", hc.GetUrl())
                logger.Debug(e.Error())
diff --git a/pkg/common/router/router.go b/pkg/common/router/router.go
index ddbd3ce..80328f5 100644
--- a/pkg/common/router/router.go
+++ b/pkg/common/router/router.go
@@ -40,9 +40,9 @@ type (
 )
 
 // CreateRouterCoordinator create coordinator for http connection manager
-func CreateRouterCoordinator(hcmc *model.HttpConnectionManagerConfig) 
*RouterCoordinator {
-       rc := &RouterCoordinator{activeConfig: &hcmc.RouteConfig}
-       if hcmc.RouteConfig.Dynamic {
+func CreateRouterCoordinator(routeConfig *model.RouteConfiguration) 
*RouterCoordinator {
+       rc := &RouterCoordinator{activeConfig: routeConfig}
+       if routeConfig.Dynamic {
                server.GetRouterManager().AddRouterListener(rc)
        }
        rc.initTrie()
@@ -57,6 +57,13 @@ func (rm *RouterCoordinator) Route(hc *http.HttpContext) 
(*model.RouteAction, er
        return rm.activeConfig.Route(hc.Request)
 }
 
+func (rm *RouterCoordinator) RouteByPathAndName(path, method string) 
(*model.RouteAction, error) {
+       rm.rw.RLock()
+       defer rm.rw.RUnlock()
+
+       return rm.activeConfig.RouteByPathAndMethod(path, method)
+}
+
 func getTrieKey(method string, path string, isPrefix bool) string {
        if isPrefix {
                if !strings.HasSuffix(path, constant.PathSlash) {
diff --git a/pkg/common/router/router_test.go b/pkg/common/router/router_test.go
index 697a293..faa7eec 100644
--- a/pkg/common/router/router_test.go
+++ b/pkg/common/router/router_test.go
@@ -53,7 +53,7 @@ func TestCreateRouterCoordinator(t *testing.T) {
                IdleTimeoutStr:    "100",
        }
 
-       r := CreateRouterCoordinator(&hcmc)
+       r := CreateRouterCoordinator(&hcmc.RouteConfig)
        request, err := http.NewRequest("POST", 
"http://www.dubbogopixiu.com/api/v1?name=tc";, 
bytes.NewReader([]byte("{\"id\":\"12345\"}")))
        assert.NoError(t, err)
        c := mock.GetMockHTTPContext(request)
diff --git a/pkg/config/conf_test.yaml b/pkg/config/conf_test.yaml
index 2d4e6fb..170906c 100644
--- a/pkg/config/conf_test.yaml
+++ b/pkg/config/conf_test.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTPS"
       address:
         socket_address:
-          protocol_type: "HTTPS"
           address: "0.0.0.0"
           port: 443
       filter_chains:
-        - filter_chain_match:
-            domains:
-              - api.dubbo.com
-              - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/pkg/config/config_load.go b/pkg/config/config_load.go
index 16d8b5b..870e1be 100644
--- a/pkg/config/config_load.go
+++ b/pkg/config/config_load.go
@@ -113,10 +113,10 @@ func GetProtocol(cfg *model.Bootstrap) (err error) {
                return err
        }
        for _, l := range cfg.StaticResources.Listeners {
-               if l.Address.SocketAddress.ProtocolStr == "" {
-                       l.Address.SocketAddress.ProtocolStr = 
constant.DefaultProtocolType
+               if l.ProtocolStr == "" {
+                       l.ProtocolStr = constant.DefaultProtocolType
                }
-               l.Address.SocketAddress.Protocol = 
model.ProtocolType(model.ProtocolTypeValue[l.Address.SocketAddress.ProtocolStr])
+               l.Protocol = 
model.ProtocolType(model.ProtocolTypeValue[l.ProtocolStr])
        }
        return nil
 }
diff --git a/pkg/config/config_load_test.go b/pkg/config/config_load_test.go
index 94aef4d..b83d6bb 100644
--- a/pkg/config/config_load_test.go
+++ b/pkg/config/config_load_test.go
@@ -84,12 +84,12 @@ func TestMain(m *testing.M) {
                StaticResources: model.StaticResources{
                        Listeners: []*model.Listener{
                                {
-                                       Name: "net/http",
+                                       Name:        "net/http",
+                                       ProtocolStr: "HTTPS",
                                        Address: model.Address{
                                                SocketAddress: 
model.SocketAddress{
-                                                       ProtocolStr: "HTTPS",
-                                                       Address:     "0.0.0.0",
-                                                       Port:        443,
+                                                       Address: "0.0.0.0",
+                                                       Port:    443,
                                                },
                                        },
                                        Config: model.HttpConfig{
@@ -97,19 +97,11 @@ func TestMain(m *testing.M) {
                                                WriteTimeoutStr: "5s",
                                                ReadTimeoutStr:  "5s",
                                        },
-                                       FilterChains: []model.FilterChain{
-                                               {
-                                                       FilterChainMatch: 
model.FilterChainMatch{
-                                                               Domains: 
[]string{
-                                                                       
"api.dubbo.com",
-                                                                       
"api.pixiu.com",
-                                                               },
-                                                       },
-                                                       Filters: []model.Filter{
-                                                               {
-                                                                       Name:   
"dgp.filter.httpconnectionmanager",
-                                                                       Config: 
inInterface,
-                                                               },
+                                       FilterChain: model.FilterChain{
+                                               Filters: []model.NetworkFilter{
+                                                       {
+                                                               Name:   
"dgp.filter.httpconnectionmanager",
+                                                               Config: 
inInterface,
                                                        },
                                                },
                                        },
diff --git a/pkg/context/http/context.go b/pkg/context/http/context.go
index bd9c2a9..978ce68 100644
--- a/pkg/context/http/context.go
+++ b/pkg/context/http/context.go
@@ -63,7 +63,6 @@ type HttpContext struct {
        SourceResp interface{}
 
        HttpConnectionManager model.HttpConnectionManagerConfig
-       Listener              *model.Listener
        Route                 *model.RouteAction
        Api                   *router.API
 
diff --git a/pkg/server/listener_test.go 
b/pkg/filter/network/grpcconnectionmanager/plugin.go
similarity index 59%
copy from pkg/server/listener_test.go
copy to pkg/filter/network/grpcconnectionmanager/plugin.go
index b3401f7..3e66ac7 100644
--- a/pkg/server/listener_test.go
+++ b/pkg/filter/network/grpcconnectionmanager/plugin.go
@@ -15,32 +15,32 @@
  * limitations under the License.
  */
 
-package server
+package grpcconnectionmanager
 
 import (
-       ctxHttp "github.com/apache/dubbo-go-pixiu/pkg/context/http"
+       "github.com/apache/dubbo-go-pixiu/pkg/common/constant"
+       "github.com/apache/dubbo-go-pixiu/pkg/common/extension/filter"
+       "github.com/apache/dubbo-go-pixiu/pkg/common/grpc"
        "github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
-func getTestContext() *ctxHttp.HttpContext {
-       l := ListenerService{
-               cfg: &model.Listener{
-                       Name: "test",
-                       Address: model.Address{
-                               SocketAddress: model.SocketAddress{
-                                       Protocol: model.ProtocolTypeHTTP,
-                                       Address:  "0.0.0.0",
-                                       Port:     8888,
-                               },
-                       },
-                       FilterChains: []model.FilterChain{},
-               },
-       }
+const (
+       Kind = constant.GRPCConnectManagerFilter
+)
+
+func init() {
+       filter.RegisterNetworkFilter(&Plugin{})
+}
+
+type (
+       Plugin struct{}
+)
+
+func (p *Plugin) Kind() string {
+       return Kind
+}
 
-       hc := &ctxHttp.HttpContext{
-               Listener: l.cfg,
-               Filters:  []ctxHttp.FilterFunc{},
-       }
-       hc.Reset()
-       return hc
+func (hp *Plugin) CreateFilter(config interface{}, bs *model.Bootstrap) 
(filter.NetworkFilter, error) {
+       hcmc := config.(*model.GRPCConnectionManagerConfig)
+       return grpc.CreateGrpcConnectionManager(hcmc, bs), nil
 }
diff --git a/pkg/filterchain/network_filter_chain.go 
b/pkg/filterchain/network_filter_chain.go
new file mode 100644
index 0000000..dd04607
--- /dev/null
+++ b/pkg/filterchain/network_filter_chain.go
@@ -0,0 +1,84 @@
+/*
+ * 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 filterchain
+
+import (
+       "net/http"
+)
+
+import (
+       "github.com/apache/dubbo-go-pixiu/pkg/common/constant"
+       "github.com/apache/dubbo-go-pixiu/pkg/common/extension/filter"
+       "github.com/apache/dubbo-go-pixiu/pkg/common/yaml"
+       "github.com/apache/dubbo-go-pixiu/pkg/logger"
+       "github.com/apache/dubbo-go-pixiu/pkg/model"
+)
+
+type NetworkFilterChain struct {
+       filtersArray []filter.NetworkFilter
+       config       model.FilterChain
+}
+
+func (fc NetworkFilterChain) ServeHTTP(w http.ResponseWriter, r *http.Request) 
{
+       // todo: only one filter will exist for now, needs change when more 
than one
+       for _, filter := range fc.filtersArray {
+               filter.ServeHTTP(w, r)
+       }
+}
+
+func CreateNetworkFilterChain(config model.FilterChain, bs *model.Bootstrap) 
*NetworkFilterChain {
+       filtersArray := make([]filter.NetworkFilter, len(config.Filters))
+       // todo: split code block like http filter manager
+       // todo: only one filter will exist for now, needs change when more 
than one
+       for i, f := range config.Filters {
+               if f.Name == constant.GRPCConnectManagerFilter {
+                       gcmc := &model.GRPCConnectionManagerConfig{}
+                       if err := yaml.ParseConfig(gcmc, f.Config); err != nil {
+                               logger.Error("CreateNetworkFilterChain %s parse 
config error %s", f.Name, err)
+                       }
+                       p, err := 
filter.GetNetworkFilterPlugin(constant.GRPCConnectManagerFilter)
+                       if err != nil {
+                               logger.Error("CreateNetworkFilterChain %s 
getNetworkFilterPlugin error %s", f.Name, err)
+                       }
+                       filter, err := p.CreateFilter(gcmc, bs)
+                       if err != nil {
+                               logger.Error("CreateNetworkFilterChain %s 
createFilter error %s", f.Name, err)
+                       }
+                       filtersArray[i] = filter
+               } else if f.Name == constant.HTTPConnectManagerFilter {
+                       hcmc := &model.HttpConnectionManagerConfig{}
+                       if err := yaml.ParseConfig(hcmc, f.Config); err != nil {
+                               logger.Error("CreateNetworkFilterChain parse %s 
config error %s", f.Name, err)
+                       }
+                       p, err := 
filter.GetNetworkFilterPlugin(constant.HTTPConnectManagerFilter)
+                       if err != nil {
+                               logger.Error("CreateNetworkFilterChain %s 
getNetworkFilterPlugin error %s", f.Name, err)
+                       }
+                       filter, err := p.CreateFilter(hcmc, bs)
+                       if err != nil {
+                               logger.Error("CreateNetworkFilterChain %s 
createFilter error %s", f.Name, err)
+                       }
+                       filtersArray[i] = filter
+               }
+       }
+
+       return &NetworkFilterChain{
+               filtersArray: filtersArray,
+               config:       config,
+       }
+}
diff --git a/pkg/server/listener.go b/pkg/listener/http/http_listener.go
similarity index 54%
rename from pkg/server/listener.go
rename to pkg/listener/http/http_listener.go
index b71212c..5fc477c 100644
--- a/pkg/server/listener.go
+++ b/pkg/listener/http/http_listener.go
@@ -15,83 +15,82 @@
  * limitations under the License.
  */
 
-package server
+package http
 
 import (
+       "fmt"
        "log"
        "net/http"
        "strconv"
-       "sync"
        "time"
 )
 
 import (
+       "github.com/pkg/errors"
        "golang.org/x/crypto/acme/autocert"
 )
 
 import (
-       "github.com/apache/dubbo-go-pixiu/pkg/common/constant"
-       "github.com/apache/dubbo-go-pixiu/pkg/common/extension/filter"
-       "github.com/apache/dubbo-go-pixiu/pkg/common/yaml"
-       h "github.com/apache/dubbo-go-pixiu/pkg/context/http"
+       "github.com/apache/dubbo-go-pixiu/pkg/filterchain"
+       "github.com/apache/dubbo-go-pixiu/pkg/listener"
        "github.com/apache/dubbo-go-pixiu/pkg/logger"
        "github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
+func init() {
+       listener.SetListenerServiceFactory(model.ProtocolTypeHTTP, 
newHttpListenerService)
+}
+
 type (
        // ListenerService the facade of a listener
-       ListenerService struct {
-               cfg *model.Listener
-               // TODO: just temporary because only one network filter
-               nf  filter.NetworkFilter
+       HttpListenerService struct {
+               listener.BaseListenerService
                srv *http.Server
        }
 
        // DefaultHttpListener
        DefaultHttpWorker struct {
-               pool sync.Pool
-               ls   *ListenerService
+               ls *HttpListenerService
        }
 )
 
-// NewListenerService create listener service
-func CreateListenerService(lc *model.Listener, bs *model.Bootstrap) 
*ListenerService {
-       hcm := createHttpManager(lc, bs)
-       return &ListenerService{cfg: lc, nf: *hcm}
-}
-
-func (ls *ListenerService) GetNetworkFilter() filter.NetworkFilter {
-       return ls.nf
+func newHttpListenerService(lc *model.Listener, bs *model.Bootstrap) 
(listener.ListenerService, error) {
+       fc := filterchain.CreateNetworkFilterChain(lc.FilterChain, bs)
+       return &HttpListenerService{
+               BaseListenerService: listener.BaseListenerService{
+                       Config:      lc,
+                       FilterChain: fc,
+               },
+               srv: nil,
+       }, nil
 }
 
 // Start start the listener
-func (ls *ListenerService) Start() {
-       sa := ls.cfg.Address.SocketAddress
-       switch sa.Protocol {
+func (ls *HttpListenerService) Start() error {
+       switch ls.Config.Protocol {
        case model.ProtocolTypeHTTP:
                ls.httpListener()
        case model.ProtocolTypeHTTPS:
                ls.httpsListener()
        default:
-               panic("unsupported protocol start: " + sa.ProtocolStr)
+               return errors.New(fmt.Sprintf("unsupported protocol start: %d", 
ls.Config.Protocol))
        }
+       return nil
 }
 
-func (ls *ListenerService) httpsListener() {
-       hl := CreateDefaultHttpWorker(ls)
-       hl.pool.New = func() interface{} {
-               return ls.allocateContext()
-       }
+func (ls *HttpListenerService) httpsListener() {
+       hl := createDefaultHttpWorker(ls)
+
        // user customize http config
        var hc *model.HttpConfig
-       hc = model.MapInStruct(ls.cfg)
+       hc = model.MapInStruct(ls.Config)
 
        mux := http.NewServeMux()
        mux.HandleFunc("/", hl.ServeHTTP)
        m := &autocert.Manager{
-               Cache:      
autocert.DirCache(ls.cfg.Address.SocketAddress.CertsDir),
+               Cache:      
autocert.DirCache(ls.Config.Address.SocketAddress.CertsDir),
                Prompt:     autocert.AcceptTOS,
-               HostPolicy: 
autocert.HostWhitelist(ls.cfg.Address.SocketAddress.Domains...),
+               HostPolicy: 
autocert.HostWhitelist(ls.Config.Address.SocketAddress.Domains...),
        }
        ls.srv = &http.Server{
                Addr:           ":https",
@@ -102,26 +101,23 @@ func (ls *ListenerService) httpsListener() {
                MaxHeaderBytes: resolveInt2IntProp(hc.MaxHeaderBytes, 1<<20),
                TLSConfig:      m.TLSConfig(),
        }
-       autoLs := autocert.NewListener(ls.cfg.Address.SocketAddress.Domains...)
+       autoLs := 
autocert.NewListener(ls.Config.Address.SocketAddress.Domains...)
        logger.Infof("[dubbo-go-server] httpsListener start at : %s", 
ls.srv.Addr)
        err := ls.srv.Serve(autoLs)
        logger.Info("[dubbo-go-server] httpsListener result:", err)
 }
 
-func (ls *ListenerService) httpListener() {
-       hl := CreateDefaultHttpWorker(ls)
-       hl.pool.New = func() interface{} {
-               return ls.allocateContext()
-       }
+func (ls *HttpListenerService) httpListener() {
+       hl := createDefaultHttpWorker(ls)
 
        // user customize http config
        var hc *model.HttpConfig
-       hc = model.MapInStruct(ls.cfg)
+       hc = model.MapInStruct(ls.Config)
 
        mux := http.NewServeMux()
        mux.HandleFunc("/", hl.ServeHTTP)
 
-       sa := ls.cfg.Address.SocketAddress
+       sa := ls.Config.Address.SocketAddress
        ls.srv = &http.Server{
                Addr:           resolveAddress(sa.Address + ":" + 
strconv.Itoa(sa.Port)),
                Handler:        mux,
@@ -136,37 +132,16 @@ func (ls *ListenerService) httpListener() {
        log.Println(ls.srv.ListenAndServe())
 }
 
-func (ls *ListenerService) allocateContext() *h.HttpContext {
-       return &h.HttpContext{
-               Listener: ls.cfg,
-               Params:   make(map[string]interface{}),
-       }
-}
-
-// NewDefaultHttpListener create http listener
-func CreateDefaultHttpWorker(ls *ListenerService) *DefaultHttpWorker {
+// createDefaultHttpWorker create http listener
+func createDefaultHttpWorker(ls *HttpListenerService) *DefaultHttpWorker {
        return &DefaultHttpWorker{
-               pool: sync.Pool{},
-               ls:   ls,
+               ls: ls,
        }
 }
 
 // ServeHTTP http request entrance.
 func (s *DefaultHttpWorker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-       hc := s.pool.Get().(*h.HttpContext)
-       defer s.pool.Put(hc)
-
-       hc.Request = r
-       hc.Writer = w
-       hc.Reset()
-
-       // now only one filter http_connection_manager, so just get it and call
-       err := s.ls.nf.OnData(hc)
-
-       if err != nil {
-               s.pool.Put(hc)
-               logger.Errorf("ServeHTTP %s", err)
-       }
+       s.ls.FilterChain.ServeHTTP(w, r)
 }
 
 func resolveInt2IntProp(currentV, defaultV int) int {
@@ -197,34 +172,3 @@ func resolveAddress(addr string) string {
 
        return addr
 }
-
-func findHttpManager(l *model.Listener) *model.HttpConnectionManagerConfig {
-       for _, fc := range l.FilterChains {
-               for _, f := range fc.Filters {
-                       if f.Name == constant.HTTPConnectManagerFilter {
-                               hcmc := &model.HttpConnectionManagerConfig{}
-                               if err := yaml.ParseConfig(hcmc, f.Config); err 
!= nil {
-                                       return nil
-                               }
-
-                               return hcmc
-                       }
-               }
-       }
-
-       return DefaultHttpConnectionManager()
-}
-
-func createHttpManager(lc *model.Listener, bs *model.Bootstrap) 
*filter.NetworkFilter {
-       p, err := 
filter.GetNetworkFilterPlugin(constant.HTTPConnectManagerFilter)
-       if err != nil {
-               panic(err)
-       }
-
-       hcmc := findHttpManager(lc)
-       hcm, err := p.CreateFilter(hcmc, bs)
-       if err != nil {
-               panic(err)
-       }
-       return &hcm
-}
diff --git a/pkg/listener/http2/http2_listener.go 
b/pkg/listener/http2/http2_listener.go
new file mode 100644
index 0000000..5da0dbb
--- /dev/null
+++ b/pkg/listener/http2/http2_listener.go
@@ -0,0 +1,121 @@
+/*
+ * 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 http2
+
+import (
+       "net"
+       "net/http"
+       "strconv"
+)
+
+import (
+       "golang.org/x/net/http2"
+       "golang.org/x/net/http2/h2c"
+)
+
+import (
+       "github.com/apache/dubbo-go-pixiu/pkg/filterchain"
+       "github.com/apache/dubbo-go-pixiu/pkg/listener"
+       "github.com/apache/dubbo-go-pixiu/pkg/logger"
+       "github.com/apache/dubbo-go-pixiu/pkg/model"
+)
+
+func init() {
+       listener.SetListenerServiceFactory(model.ProtocolTypeHTTP2, 
newHttp2ListenerService)
+}
+
+type (
+       // Http2ListenerService the facade of a listener
+       Http2ListenerService struct {
+               listener.BaseListenerService
+               listener net.Listener
+               server   *http.Server
+       }
+)
+
+type handleWrapper struct {
+       fc *filterchain.NetworkFilterChain
+}
+
+type h2cWrapper struct {
+       w *handleWrapper
+       h http.Handler
+}
+
+// ServeHTTP call Handler to handle http request and response.
+func (h *h2cWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+       h.h.ServeHTTP(w, r)
+}
+
+// ServeHTTP call FilterChain to handle http request and response.
+func (h *handleWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+       h.fc.ServeHTTP(w, r)
+}
+
+func newHttp2ListenerService(lc *model.Listener, bs *model.Bootstrap) 
(listener.ListenerService, error) {
+       fc := filterchain.CreateNetworkFilterChain(lc.FilterChain, bs)
+       return &Http2ListenerService{
+               BaseListenerService: listener.BaseListenerService{
+                       Config:      lc,
+                       FilterChain: fc,
+               },
+               listener: nil,
+               server:   nil,
+       }, nil
+}
+
+// Start start listen
+func (ls Http2ListenerService) Start() error {
+
+       sa := ls.Config.Address.SocketAddress
+       addr := resolveAddress(sa.Address + ":" + strconv.Itoa(sa.Port))
+
+       l, err := net.Listen("tcp", addr)
+       if err != nil {
+               return err
+       }
+       ls.listener = l
+
+       handlerWrapper := &handleWrapper{ls.FilterChain}
+       h2s := &http2.Server{}
+       h := &h2cWrapper{
+               w: handlerWrapper,
+               h: h2c.NewHandler(handlerWrapper, h2s),
+       }
+
+       ls.server = &http.Server{
+               Addr:    addr,
+               Handler: h,
+       }
+
+       go func() {
+               if err := ls.server.Serve(ls.listener); err != nil {
+                       logger.Error("Http2ListenerService Start error %s", err)
+               }
+       }()
+       return nil
+}
+
+func resolveAddress(addr string) string {
+       if addr == "" {
+               logger.Debug("Addr is undefined. Using port :8080 by default")
+               return ":8080"
+       }
+
+       return addr
+}
diff --git a/pkg/listener/listener.go b/pkg/listener/listener.go
new file mode 100644
index 0000000..5b9a76d
--- /dev/null
+++ b/pkg/listener/listener.go
@@ -0,0 +1,57 @@
+/*
+ * 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 listener
+
+import (
+       "github.com/pkg/errors"
+)
+
+import (
+       "github.com/apache/dubbo-go-pixiu/pkg/filterchain"
+       "github.com/apache/dubbo-go-pixiu/pkg/model"
+)
+
+var factoryMap = make(map[model.ProtocolType]func(lc *model.Listener, bs 
*model.Bootstrap) (ListenerService, error), 8)
+
+type (
+       ListenerService interface {
+               Start() error
+       }
+
+       BaseListenerService struct {
+               Config      *model.Listener
+               FilterChain *filterchain.NetworkFilterChain
+       }
+)
+
+// SetListenerServiceFactory will store the listenerService factory by name
+func SetListenerServiceFactory(protocol model.ProtocolType, newRegFunc func(lc 
*model.Listener, bs *model.Bootstrap) (ListenerService, error)) {
+       factoryMap[protocol] = newRegFunc
+}
+
+// CreateListenerService create listener service
+func CreateListenerService(lc *model.Listener, bs *model.Bootstrap) 
(ListenerService, error) {
+       if registry, ok := factoryMap[lc.Protocol]; ok {
+               reg, err := registry(lc, bs)
+               if err != nil {
+                       panic("Initialize ListenerService " + lc.Name + "failed 
due to: " + err.Error())
+               }
+               return reg, nil
+       }
+       return nil, errors.New("Registry " + lc.ProtocolStr + " does not 
support yet")
+}
diff --git a/pkg/server/listener_test.go b/pkg/listener/listener_test.go
similarity index 71%
copy from pkg/server/listener_test.go
copy to pkg/listener/listener_test.go
index b3401f7..fe2514d 100644
--- a/pkg/server/listener_test.go
+++ b/pkg/listener/listener_test.go
@@ -15,31 +15,16 @@
  * limitations under the License.
  */
 
-package server
+package listener
 
 import (
        ctxHttp "github.com/apache/dubbo-go-pixiu/pkg/context/http"
-       "github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
 func getTestContext() *ctxHttp.HttpContext {
-       l := ListenerService{
-               cfg: &model.Listener{
-                       Name: "test",
-                       Address: model.Address{
-                               SocketAddress: model.SocketAddress{
-                                       Protocol: model.ProtocolTypeHTTP,
-                                       Address:  "0.0.0.0",
-                                       Port:     8888,
-                               },
-                       },
-                       FilterChains: []model.FilterChain{},
-               },
-       }
 
        hc := &ctxHttp.HttpContext{
-               Listener: l.cfg,
-               Filters:  []ctxHttp.FilterFunc{},
+               Filters: []ctxHttp.FilterFunc{},
        }
        hc.Reset()
        return hc
diff --git a/pkg/model/base.go b/pkg/model/base.go
index 6503f32..ea76b7f 100644
--- a/pkg/model/base.go
+++ b/pkg/model/base.go
@@ -42,20 +42,6 @@ const (
 )
 
 const (
-       ProtocolTypeHTTP ProtocolType = 0 + iota // support for 1.0
-       ProtocolTypeTCP
-       ProtocolTypeUDP
-       ProtocolTypeHTTPS
-       ProtocolTypeGRPC
-)
-
-const (
-       REST_VALUE  = "REST"
-       GRPC_VALUE  = "GRPC"
-       DUBBO_VALUE = "DUBBO"
-)
-
-const (
        ApiTypeREST api.ApiType = 0 + iota // support for 1.0
        ApiTypeGRPC
        ApiTypeDUBBO
@@ -74,24 +60,6 @@ var (
                "Unknown": 2,
        }
 
-       // ProtocolTypeName enum seq to protocol type name
-       ProtocolTypeName = map[int32]string{
-               0: "HTTP",
-               1: "TCP",
-               2: "UDP",
-               3: "HTTPS",
-               4: "GRPC",
-       }
-
-       // ProtocolTypeValue protocol type name to enum seq
-       ProtocolTypeValue = map[string]int32{
-               "HTTP":  0,
-               "TCP":   1,
-               "UDP":   2,
-               "HTTPS": 3,
-               "GRPC":  4,
-       }
-
        ApiTypeName = map[int32]string{
                0: REST_VALUE,
                1: GRPC_VALUE,
@@ -106,8 +74,6 @@ var (
 )
 
 type (
-       // ProtocolType protocol type enum
-       ProtocolType int32
 
        // Address the address
        Address struct {
@@ -119,13 +85,11 @@ type (
        // used to tell server where to bind/listen, connect to upstream and 
find
        // management servers
        SocketAddress struct {
-               ProtocolStr  string       `yaml:"protocol_type" 
json:"protocol_type" mapstructure:"protocol_type"`
-               Protocol     ProtocolType `default:"http" yaml:"omitempty" 
json:"omitempty"`
-               Address      string       `default:"0.0.0.0" yaml:"address" 
json:"address" mapstructure:"address"`
-               Port         int          `default:"8881" yaml:"port" 
json:"port" mapstructure:"port"`
-               ResolverName string       `yaml:"resolver_name" 
json:"resolver_name" mapstructure:"resolver_name"`
-               Domains      []string     `yaml:"domains" json:"domains" 
mapstructure:"domains"`
-               CertsDir     string       `yaml:"certs_dir" json:"certs_dir" 
mapstructure:"certs_dir"`
+               Address      string   `default:"0.0.0.0" yaml:"address" 
json:"address" mapstructure:"address"`
+               Port         int      `default:"8881" yaml:"port" json:"port" 
mapstructure:"port"`
+               ResolverName string   `yaml:"resolver_name" 
json:"resolver_name" mapstructure:"resolver_name"`
+               Domains      []string `yaml:"domains" json:"domains" 
mapstructure:"domains"`
+               CertsDir     string   `yaml:"certs_dir" json:"certs_dir" 
mapstructure:"certs_dir"`
        }
 
        // ConfigSource
diff --git a/pkg/model/filter.go b/pkg/model/filter.go
index 4214bf6..a03abe4 100644
--- a/pkg/model/filter.go
+++ b/pkg/model/filter.go
@@ -19,12 +19,11 @@ package model
 
 // FilterChain filter chain
 type FilterChain struct {
-       FilterChainMatch FilterChainMatch `yaml:"filter_chain_match" 
json:"filter_chain_match" mapstructure:"filter_chain_match"`
-       Filters          []Filter         `yaml:"filters" json:"filters" 
mapstructure:"filters"`
+       Filters []NetworkFilter `yaml:"filters" json:"filters" 
mapstructure:"filters"`
 }
 
-// Filter core struct, filter is extend by user
-type Filter struct {
+// NetworkFilter core struct, filter is extend by user
+type NetworkFilter struct {
        Name   string                 `yaml:"name" json:"name" 
mapstructure:"name"`       // Name filter name unique
        Config map[string]interface{} `yaml:"config" json:"config" 
mapstructure:"config"` // Config filter config
 }
diff --git a/pkg/model/http.go b/pkg/model/http.go
index aa944d9..05ba60b 100644
--- a/pkg/model/http.go
+++ b/pkg/model/http.go
@@ -34,6 +34,11 @@ type HttpConnectionManagerConfig struct {
        GenerateRequestID bool               `yaml:"generate_request_id" 
json:"generate_request_id" mapstructure:"generate_request_id"`
 }
 
+// GRPCConnectionManagerConfig
+type GRPCConnectionManagerConfig struct {
+       RouteConfig RouteConfiguration `yaml:"route_config" json:"route_config" 
mapstructure:"route_config"`
+}
+
 // HTTPFilter http filter
 type HTTPFilter struct {
        Name   string                 `yaml:"name" json:"name" 
mapstructure:"name"`
diff --git a/pkg/model/listener.go b/pkg/model/listener.go
index 730f00d..73ea0f6 100644
--- a/pkg/model/listener.go
+++ b/pkg/model/listener.go
@@ -17,11 +17,54 @@
 
 package model
 
-// Listener is a server, listener a port
-type Listener struct {
-       Name    string  `yaml:"name" json:"name" mapstructure:"name"`
-       Address Address `yaml:"address" json:"address" mapstructure:"address"`
+const (
+       ProtocolTypeHTTP ProtocolType = 0 + iota // support for 1.0
+       ProtocolTypeTCP
+       ProtocolTypeUDP
+       ProtocolTypeHTTPS
+       ProtocolTypeGRPC
+       ProtocolTypeHTTP2
+)
 
-       FilterChains []FilterChain `yaml:"filter_chains" json:"filter_chains" 
mapstructure:"filter_chains"`
-       Config       interface{}   `yaml:"config" json:"config" 
mapstructure:"config"`
-}
+const (
+       REST_VALUE  = "REST"
+       GRPC_VALUE  = "GRPC"
+       DUBBO_VALUE = "DUBBO"
+)
+
+var (
+       // ProtocolTypeName enum seq to protocol type name
+       ProtocolTypeName = map[int32]string{
+               0: "HTTP",
+               1: "TCP",
+               2: "UDP",
+               3: "HTTPS",
+               4: "GRPC",
+               5: "HTTP2",
+       }
+
+       // ProtocolTypeValue protocol type name to enum seq
+       ProtocolTypeValue = map[string]int32{
+               "HTTP":  0,
+               "TCP":   1,
+               "UDP":   2,
+               "HTTPS": 3,
+               "GRPC":  4,
+               "HTTP2": 5,
+       }
+)
+
+type (
+       // ProtocolType protocol type enum
+       ProtocolType int32
+
+       // Listener is a server, listener a port
+       Listener struct {
+               Name        string       `yaml:"name" json:"name" 
mapstructure:"name"`
+               Address     Address      `yaml:"address" json:"address" 
mapstructure:"address"`
+               ProtocolStr string       `default:"http" yaml:"protocol_type" 
json:"protocol_type" mapstructure:"protocol_type"`
+               Protocol    ProtocolType `default:"http" yaml:"omitempty" 
json:"omitempty"`
+               FilterChain FilterChain  `yaml:"filter_chains" 
json:"filter_chains" mapstructure:"filter_chains"`
+               Config      interface{}  `yaml:"config" json:"config" 
mapstructure:"config"`
+       }
+)
diff --git a/pkg/model/router.go b/pkg/model/router.go
index 5314418..af8fc6f 100644
--- a/pkg/model/router.go
+++ b/pkg/model/router.go
@@ -71,14 +71,14 @@ type (
        }
 )
 
-func (rc *RouteConfiguration) Route(req *stdHttp.Request) (*RouteAction, 
error) {
+func (rc *RouteConfiguration) RouteByPathAndMethod(path, method string) 
(*RouteAction, error) {
        if rc.RouteTrie.IsEmpty() {
                return nil, errors.Errorf("router configuration is empty")
        }
 
-       node, _, _ := rc.RouteTrie.Match(stringutil.GetTrieKey(req.Method, 
req.URL.Path))
+       node, _, _ := rc.RouteTrie.Match(stringutil.GetTrieKey(method, path))
        if node == nil {
-               return nil, errors.Errorf("route failed for %s,no rules 
matched.", stringutil.GetTrieKey(req.Method, req.URL.Path))
+               return nil, errors.Errorf("route failed for %s,no rules 
matched.", stringutil.GetTrieKey(method, path))
        }
        if node.GetBizInfo() == nil {
                return nil, errors.Errorf("info is nil.please check your 
configuration.")
@@ -86,3 +86,7 @@ func (rc *RouteConfiguration) Route(req *stdHttp.Request) 
(*RouteAction, error)
        ret := (node.GetBizInfo()).(RouteAction)
        return &ret, nil
 }
+
+func (rc *RouteConfiguration) Route(req *stdHttp.Request) (*RouteAction, 
error) {
+       return rc.RouteByPathAndMethod(req.URL.Path, req.Method)
+}
diff --git a/pkg/pluginregistry/registry.go b/pkg/pluginregistry/registry.go
index 367d394..df9f33e 100644
--- a/pkg/pluginregistry/registry.go
+++ b/pkg/pluginregistry/registry.go
@@ -34,7 +34,10 @@ import (
        _ "github.com/apache/dubbo-go-pixiu/pkg/filter/http/proxyrewrite"
        _ "github.com/apache/dubbo-go-pixiu/pkg/filter/http/remote"
        _ "github.com/apache/dubbo-go-pixiu/pkg/filter/metric"
+       _ 
"github.com/apache/dubbo-go-pixiu/pkg/filter/network/grpcconnectionmanager"
        _ 
"github.com/apache/dubbo-go-pixiu/pkg/filter/network/httpconnectionmanager"
        _ "github.com/apache/dubbo-go-pixiu/pkg/filter/seata"
        _ "github.com/apache/dubbo-go-pixiu/pkg/filter/tracing"
+       _ "github.com/apache/dubbo-go-pixiu/pkg/listener/http"
+       _ "github.com/apache/dubbo-go-pixiu/pkg/listener/http2"
 )
diff --git a/pkg/server/listener_manager.go b/pkg/server/listener_manager.go
index 9bee77d..3c433fe 100644
--- a/pkg/server/listener_manager.go
+++ b/pkg/server/listener_manager.go
@@ -18,19 +18,26 @@
 package server
 
 import (
+       "github.com/apache/dubbo-go-pixiu/pkg/listener"
+       "github.com/apache/dubbo-go-pixiu/pkg/logger"
        "github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
+// ListenerManager the listener manager
 type ListenerManager struct {
        activeListener        []*model.Listener
-       activeListenerService []*ListenerService
+       activeListenerService []listener.ListenerService
 }
 
+// CreateDefaultListenerManager create listener manager from config
 func CreateDefaultListenerManager(bs *model.Bootstrap) *ListenerManager {
        sl := bs.GetStaticListeners()
-       var ls []*ListenerService
+       var ls []listener.ListenerService
        for _, l := range bs.StaticResources.Listeners {
-               listener := CreateListenerService(l, bs)
+               listener, err := listener.CreateListenerService(l, bs)
+               if err != nil {
+                       logger.Error("CreateDefaultListenerManager %s error: 
%v", l.Name, err)
+               }
                ls = append(ls, listener)
        }
 
@@ -44,21 +51,15 @@ func (lm *ListenerManager) addOrUpdateListener(l 
*model.Listener) {
        lm.activeListener = append(lm.activeListener, l)
 }
 
+// StartListen make active listener to start listening
 func (lm *ListenerManager) StartListen() {
        for _, s := range lm.activeListenerService {
-               go s.Start()
-       }
-}
-
-func (lm *ListenerManager) addListenerService(ls *ListenerService) {
-       lm.activeListenerService = append(lm.activeListenerService, ls)
-}
-
-func (lm *ListenerManager) GetListenerService(name string) *ListenerService {
-       for i := range lm.activeListenerService {
-               if lm.activeListenerService[i].cfg.Name == name {
-                       return lm.activeListenerService[i]
-               }
+               s := s
+               go func() {
+                       err := s.Start()
+                       if err != nil {
+                               panic(err)
+                       }
+               }()
        }
-       return nil
 }
diff --git a/samples/dubbogo/http/pixiu/conf.yaml 
b/samples/dubbogo/http/pixiu/conf.yaml
index 24ae301..e7ddc6a 100644
--- a/samples/dubbogo/http/pixiu/conf.yaml
+++ b/samples/dubbogo/http/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/multi/config/conf.yaml 
b/samples/dubbogo/multi/config/conf.yaml
index e1f0eb8..bcb21ed 100644
--- a/samples/dubbogo/multi/config/conf.yaml
+++ b/samples/dubbogo/multi/config/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8882
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/body/pixiu/conf.yaml 
b/samples/dubbogo/simple/body/pixiu/conf.yaml
index 0aa215d..1d58203 100644
--- a/samples/dubbogo/simple/body/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/body/pixiu/conf.yaml
@@ -21,7 +21,7 @@ static_resources:
   listeners:
     - name: "net/http"
       filter_chains:
-        - filters:
+        filters:
           - name: dgp.filter.httpconnectionmanager
             config:
               route_config:
diff --git a/samples/dubbogo/simple/csrf/pixiu/conf.yaml 
b/samples/dubbogo/simple/csrf/pixiu/conf.yaml
index ea6eea0..f6b28a5 100644
--- a/samples/dubbogo/simple/csrf/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/csrf/pixiu/conf.yaml
@@ -22,14 +22,9 @@ static_resources:
     - name: "net/http"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/jaeger/pixiu/conf.yaml 
b/samples/dubbogo/simple/jaeger/pixiu/conf.yaml
index 2199759..eb85ee5 100644
--- a/samples/dubbogo/simple/jaeger/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/jaeger/pixiu/conf.yaml
@@ -21,7 +21,7 @@ static_resources:
   listeners:
     - name: "net/http"
       filter_chains:
-        - filters:
+        filters:
           - name: dgp.filter.httpconnectionmanager
             config:
               route_config:
diff --git a/samples/dubbogo/simple/mix/pixiu/conf.yaml 
b/samples/dubbogo/simple/mix/pixiu/conf.yaml
index d241130..c5cb2ad 100644
--- a/samples/dubbogo/simple/mix/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/mix/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8882
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/proxy/pixiu/conf.yaml 
b/samples/dubbogo/simple/proxy/pixiu/conf.yaml
index a5c89c5..be9e70d 100644
--- a/samples/dubbogo/simple/proxy/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/proxy/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8883
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/query/pixiu/conf.yaml 
b/samples/dubbogo/simple/query/pixiu/conf.yaml
index 7f2386c..d300d8c 100644
--- a/samples/dubbogo/simple/query/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/query/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8884
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/registry/pixiu/conf.yaml 
b/samples/dubbogo/simple/registry/dist/darwin_amd64/pixiuconf/conf.yaml
similarity index 96%
copy from samples/dubbogo/simple/registry/pixiu/conf.yaml
copy to samples/dubbogo/simple/registry/dist/darwin_amd64/pixiuconf/conf.yaml
index 3112742..1c2bdab 100644
--- a/samples/dubbogo/simple/registry/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/registry/dist/darwin_amd64/pixiuconf/conf.yaml
@@ -58,7 +58,8 @@ static_resources:
                         timeout_config:
                           connect_timeout: 5s
                           request_timeout: 5s
-
+                  - name: dgp.filter.http.response
+                    config:
                 server_name: "test_http_dubbo"
                 generate_request_id: false
       config:
@@ -86,4 +87,4 @@ static_resources:
           "zookeeper":
             protocol: zookeeper
             address: "127.0.0.1:2181"
-            timeout: "5s"
\ No newline at end of file
+            timeout: "5s"
diff --git a/samples/dubbogo/simple/uri/conf.yaml 
b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/log.yml
similarity index 55%
copy from samples/dubbogo/simple/uri/conf.yaml
copy to samples/dubbogo/simple/registry/dist/darwin_amd64/server/log.yml
index af60e20..9330cda 100644
--- a/samples/dubbogo/simple/uri/conf.yaml
+++ b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/log.yml
@@ -16,32 +16,30 @@
 # specific language governing permissions and limitations
 # under the License.
 #
----
-static_resources:
-  listeners:
-    - name: "net/http"
-      address:
-        socket_address:
-          protocol_type: "HTTP"
-          address: "0.0.0.0"
-          port: 8885
-      config:
-        idle_timeout: 5s
-        read_timeout: 5s
-        write_timeout: 5s
-  clusters:
-    - name: "test_dubbo"
-      lb_policy: "RoundRobin"
-      registries:
-        "zookeeper":
-          timeout: "3s"
-          address: "127.0.0.1:2181"
-          username: ""
-          password: ""
-  timeout_config:
-    connect_timeout: "5s"
-    request_timeout: "10s"
-  shutdown_config:
-    timeout: "60s"
-    step_timeout: "10s"
-    reject_policy: "immediacy"
\ No newline at end of file
+level: "debug"
+development: true
+disableCaller: false
+disableStacktrace: false
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/samples/dubbogo/simple/uri/conf.yaml 
b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/server.yml
similarity index 55%
copy from samples/dubbogo/simple/uri/conf.yaml
copy to samples/dubbogo/simple/registry/dist/darwin_amd64/server/server.yml
index af60e20..1fbfa46 100644
--- a/samples/dubbogo/simple/uri/conf.yaml
+++ b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/server.yml
@@ -16,32 +16,26 @@
 # specific language governing permissions and limitations
 # under the License.
 #
----
-static_resources:
-  listeners:
-    - name: "net/http"
-      address:
-        socket_address:
-          protocol_type: "HTTP"
-          address: "0.0.0.0"
-          port: 8885
-      config:
-        idle_timeout: 5s
-        read_timeout: 5s
-        write_timeout: 5s
-  clusters:
-    - name: "test_dubbo"
-      lb_policy: "RoundRobin"
-      registries:
-        "zookeeper":
-          timeout: "3s"
-          address: "127.0.0.1:2181"
-          username: ""
-          password: ""
-  timeout_config:
-    connect_timeout: "5s"
-    request_timeout: "10s"
-  shutdown_config:
-    timeout: "60s"
-    step_timeout: "10s"
-    reject_policy: "immediacy"
\ No newline at end of file
+# dubbo server yaml configure file
+# application config
+dubbo:
+  application:
+    name: BDTService
+  registries:
+    zk:
+      protocol: zookeeper
+      timeout: 3s
+      address: 127.0.0.1:2181
+  protocols:
+    dubbo:
+      name: dubbo
+      port: 20000
+  provider:
+    registry-ids: zk
+    services:
+      UserProvider:
+        group: test
+        version: 1.0.0
+        cluster: test_dubbo
+        serialization: hessian2
+        interface: com.dubbogo.pixiu.UserService
diff --git a/samples/dubbogo/simple/registry/pixiu/conf.yaml 
b/samples/dubbogo/simple/registry/pixiu/conf.yaml
index 3112742..f48327b 100644
--- a/samples/dubbogo/simple/registry/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/registry/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/triple/pixiu/conf.yaml 
b/samples/dubbogo/simple/triple/pixiu/conf.yaml
index 652310e..9f52173 100644
--- a/samples/dubbogo/simple/triple/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/triple/pixiu/conf.yaml
@@ -20,13 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/uri/conf.yaml 
b/samples/dubbogo/simple/uri/conf.yaml
index af60e20..2e162b8 100644
--- a/samples/dubbogo/simple/uri/conf.yaml
+++ b/samples/dubbogo/simple/uri/conf.yaml
@@ -20,9 +20,9 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8885
       config:
diff --git a/samples/dubbogo/simple/uri/pixiu/conf.yaml 
b/samples/dubbogo/simple/uri/pixiu/conf.yaml
index ecab81d..f40bf35 100644
--- a/samples/dubbogo/simple/uri/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/uri/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8885
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/http/grpc/pixiu/conf.yaml b/samples/grpc/pixiu/conf.yaml
similarity index 70%
copy from samples/http/grpc/pixiu/conf.yaml
copy to samples/grpc/pixiu/conf.yaml
index 5b6faab..84fdad5 100644
--- a/samples/http/grpc/pixiu/conf.yaml
+++ b/samples/grpc/pixiu/conf.yaml
@@ -20,33 +20,22 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP2"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
-            - name: dgp.filter.httpconnectionmanager
+            - name: dgp.filter.grpcconnectionmanager
               config:
                 route_config:
                   routes:
                     - match:
-                        prefix: "/api/v1"
+                        prefix: "/provider.UserProvider/"
                       route:
                         cluster: "test-grpc"
                         cluster_not_found_response_code: 505
-                http_filters:
-                  - name: dgp.filter.http.grpcproxy
-                    config:
-                      descriptor_source_strategy: auto  # none, auto( invoke: 
->reflection->file), local, remote  ## default: auto
-                      path: samples/http/grpc/pixiu/proto
-                server_name: "test-http-grpc"
-                generate_request_id: false
       config:
         idle_timeout: 5s
         read_timeout: 5s
diff --git a/samples/grpc/proto/hello_grpc.pb.go 
b/samples/grpc/proto/hello_grpc.pb.go
new file mode 100644
index 0000000..7403d6e
--- /dev/null
+++ b/samples/grpc/proto/hello_grpc.pb.go
@@ -0,0 +1,320 @@
+/*
+ * 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.
+ */
+// protoc --proto_path=. --go_out=. --go-grpc_out=. 
--go_opt=paths=source_relative --go-grpc_opt=paths=source_relative 
.\hello_grpc.proto
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+//     protoc-gen-go v1.27.1
+//     protoc        v3.15.0--rc2
+// source: hello_grpc.proto
+
+package proto
+
+import (
+       reflect "reflect"
+       sync "sync"
+)
+
+import (
+       protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+
+       protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+)
+
+const (
+       // Verify that this generated code is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+       // Verify that runtime/protoimpl is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type GetUserRequest struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       UserId int32 `protobuf:"varint,1,opt,name=userId,proto3" 
json:"userId,omitempty"`
+}
+
+func (x *GetUserRequest) Reset() {
+       *x = GetUserRequest{}
+       if protoimpl.UnsafeEnabled {
+               mi := &file_hello_grpc_proto_msgTypes[0]
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               ms.StoreMessageInfo(mi)
+       }
+}
+
+func (x *GetUserRequest) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserRequest) ProtoMessage() {}
+
+func (x *GetUserRequest) ProtoReflect() protoreflect.Message {
+       mi := &file_hello_grpc_proto_msgTypes[0]
+       if protoimpl.UnsafeEnabled && x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserRequest.ProtoReflect.Descriptor instead.
+func (*GetUserRequest) Descriptor() ([]byte, []int) {
+       return file_hello_grpc_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GetUserRequest) GetUserId() int32 {
+       if x != nil {
+               return x.UserId
+       }
+       return 0
+}
+
+type GetUserResponse struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       Message string  `protobuf:"bytes,1,opt,name=message,proto3" 
json:"message,omitempty"`
+       Users   []*User `protobuf:"bytes,2,rep,name=users,proto3" 
json:"users,omitempty"`
+}
+
+func (x *GetUserResponse) Reset() {
+       *x = GetUserResponse{}
+       if protoimpl.UnsafeEnabled {
+               mi := &file_hello_grpc_proto_msgTypes[1]
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               ms.StoreMessageInfo(mi)
+       }
+}
+
+func (x *GetUserResponse) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserResponse) ProtoMessage() {}
+
+func (x *GetUserResponse) ProtoReflect() protoreflect.Message {
+       mi := &file_hello_grpc_proto_msgTypes[1]
+       if protoimpl.UnsafeEnabled && x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserResponse.ProtoReflect.Descriptor instead.
+func (*GetUserResponse) Descriptor() ([]byte, []int) {
+       return file_hello_grpc_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GetUserResponse) GetMessage() string {
+       if x != nil {
+               return x.Message
+       }
+       return ""
+}
+
+func (x *GetUserResponse) GetUsers() []*User {
+       if x != nil {
+               return x.Users
+       }
+       return nil
+}
+
+type User struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       UserId int32  `protobuf:"varint,1,opt,name=userId,proto3" 
json:"userId,omitempty"`
+       Name   string `protobuf:"bytes,2,opt,name=name,proto3" 
json:"name,omitempty"`
+}
+
+func (x *User) Reset() {
+       *x = User{}
+       if protoimpl.UnsafeEnabled {
+               mi := &file_hello_grpc_proto_msgTypes[2]
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               ms.StoreMessageInfo(mi)
+       }
+}
+
+func (x *User) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*User) ProtoMessage() {}
+
+func (x *User) ProtoReflect() protoreflect.Message {
+       mi := &file_hello_grpc_proto_msgTypes[2]
+       if protoimpl.UnsafeEnabled && x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use User.ProtoReflect.Descriptor instead.
+func (*User) Descriptor() ([]byte, []int) {
+       return file_hello_grpc_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *User) GetUserId() int32 {
+       if x != nil {
+               return x.UserId
+       }
+       return 0
+}
+
+func (x *User) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+var File_hello_grpc_proto protoreflect.FileDescriptor
+
+var file_hello_grpc_proto_rawDesc = []byte{
+       0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x5f, 0x67, 0x72, 0x70, 0x63, 
0x2e, 0x70, 0x72, 0x6f,
+       0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 
0x22, 0x28, 0x0a, 0x0e,
+       0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 
0x73, 0x74, 0x12, 0x16,
+       0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 
0x28, 0x05, 0x52, 0x06,
+       0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x51, 0x0a, 0x0f, 0x47, 0x65, 
0x74, 0x55, 0x73, 0x65,
+       0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 
0x07, 0x6d, 0x65, 0x73,
+       0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 
0x6d, 0x65, 0x73, 0x73,
+       0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 
0x18, 0x02, 0x20, 0x03,
+       0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 
0x72, 0x2e, 0x55, 0x73,
+       0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x32, 0x0a, 
0x04, 0x55, 0x73, 0x65,
+       0x72, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 
0x01, 0x20, 0x01, 0x28,
+       0x05, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 
0x04, 0x6e, 0x61, 0x6d,
+       0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 
0x65, 0x32, 0x4e, 0x0a,
+       0x0c, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 
0x72, 0x12, 0x3e, 0x0a,
+       0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x70, 
0x72, 0x6f, 0x76, 0x69,
+       0x64, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 
0x65, 0x71, 0x75, 0x65,
+       0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 
0x72, 0x2e, 0x47, 0x65,
+       0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 
0x65, 0x42, 0x3a, 0x5a,
+       0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 
0x61, 0x70, 0x61, 0x63,
+       0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x67, 0x6f, 0x2d, 
0x70, 0x69, 0x78, 0x69,
+       0x75, 0x2f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x74, 
0x74, 0x70, 0x2f, 0x67,
+       0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 
0x72, 0x6f, 0x74, 0x6f,
+       0x33,
+}
+
+var (
+       file_hello_grpc_proto_rawDescOnce sync.Once
+       file_hello_grpc_proto_rawDescData = file_hello_grpc_proto_rawDesc
+)
+
+func file_hello_grpc_proto_rawDescGZIP() []byte {
+       file_hello_grpc_proto_rawDescOnce.Do(func() {
+               file_hello_grpc_proto_rawDescData = 
protoimpl.X.CompressGZIP(file_hello_grpc_proto_rawDescData)
+       })
+       return file_hello_grpc_proto_rawDescData
+}
+
+var file_hello_grpc_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_hello_grpc_proto_goTypes = []interface{}{
+       (*GetUserRequest)(nil),  // 0: provider.GetUserRequest
+       (*GetUserResponse)(nil), // 1: provider.GetUserResponse
+       (*User)(nil),            // 2: provider.User
+}
+var file_hello_grpc_proto_depIdxs = []int32{
+       2, // 0: provider.GetUserResponse.users:type_name -> provider.User
+       0, // 1: provider.UserProvider.GetUser:input_type -> 
provider.GetUserRequest
+       1, // 2: provider.UserProvider.GetUser:output_type -> 
provider.GetUserResponse
+       2, // [2:3] is the sub-list for method output_type
+       1, // [1:2] is the sub-list for method input_type
+       1, // [1:1] is the sub-list for extension type_name
+       1, // [1:1] is the sub-list for extension extendee
+       0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_hello_grpc_proto_init() }
+func file_hello_grpc_proto_init() {
+       if File_hello_grpc_proto != nil {
+               return
+       }
+       if !protoimpl.UnsafeEnabled {
+               file_hello_grpc_proto_msgTypes[0].Exporter = func(v 
interface{}, i int) interface{} {
+                       switch v := v.(*GetUserRequest); i {
+                       case 0:
+                               return &v.state
+                       case 1:
+                               return &v.sizeCache
+                       case 2:
+                               return &v.unknownFields
+                       default:
+                               return nil
+                       }
+               }
+               file_hello_grpc_proto_msgTypes[1].Exporter = func(v 
interface{}, i int) interface{} {
+                       switch v := v.(*GetUserResponse); i {
+                       case 0:
+                               return &v.state
+                       case 1:
+                               return &v.sizeCache
+                       case 2:
+                               return &v.unknownFields
+                       default:
+                               return nil
+                       }
+               }
+               file_hello_grpc_proto_msgTypes[2].Exporter = func(v 
interface{}, i int) interface{} {
+                       switch v := v.(*User); i {
+                       case 0:
+                               return &v.state
+                       case 1:
+                               return &v.sizeCache
+                       case 2:
+                               return &v.unknownFields
+                       default:
+                               return nil
+                       }
+               }
+       }
+       type x struct{}
+       out := protoimpl.TypeBuilder{
+               File: protoimpl.DescBuilder{
+                       GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+                       RawDescriptor: file_hello_grpc_proto_rawDesc,
+                       NumEnums:      0,
+                       NumMessages:   3,
+                       NumExtensions: 0,
+                       NumServices:   1,
+               },
+               GoTypes:           file_hello_grpc_proto_goTypes,
+               DependencyIndexes: file_hello_grpc_proto_depIdxs,
+               MessageInfos:      file_hello_grpc_proto_msgTypes,
+       }.Build()
+       File_hello_grpc_proto = out.File
+       file_hello_grpc_proto_rawDesc = nil
+       file_hello_grpc_proto_goTypes = nil
+       file_hello_grpc_proto_depIdxs = nil
+}
diff --git a/samples/grpc/proto/hello_grpc.proto 
b/samples/grpc/proto/hello_grpc.proto
new file mode 100644
index 0000000..f3d4bcb
--- /dev/null
+++ b/samples/grpc/proto/hello_grpc.proto
@@ -0,0 +1,40 @@
+// 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.
+
+
+// protoc --proto_path=. --go_out=. --go-grpc_out=. 
--go_opt=paths=source_relative --go-grpc_opt=paths=source_relative 
.\hello_grpc.proto
+syntax = "proto3";
+
+option go_package = "github.com/apache/dubbo-go-pixiu/samples/http/grpc/proto";
+
+package provider;
+
+service UserProvider {
+    rpc GetUser (GetUserRequest) returns (GetUserResponse);
+}
+
+message GetUserRequest {
+    int32 userId = 1;
+}
+
+message GetUserResponse {
+    string message = 1;
+    repeated User users = 2;
+}
+
+message User {
+    int32 userId = 1;
+    string name = 2;
+}
\ No newline at end of file
diff --git a/samples/grpc/proto/hello_grpc_grpc.pb.go 
b/samples/grpc/proto/hello_grpc_grpc.pb.go
new file mode 100644
index 0000000..48b5f4c
--- /dev/null
+++ b/samples/grpc/proto/hello_grpc_grpc.pb.go
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package proto
+
+import (
+       context "context"
+)
+
+import (
+       grpc "google.golang.org/grpc"
+       codes "google.golang.org/grpc/codes"
+       status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// UserProviderClient is the client API for UserProvider service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please 
refer to 
https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type UserProviderClient interface {
+       GetUser(ctx context.Context, in *GetUserRequest, opts 
...grpc.CallOption) (*GetUserResponse, error)
+}
+
+type userProviderClient struct {
+       cc grpc.ClientConnInterface
+}
+
+func NewUserProviderClient(cc grpc.ClientConnInterface) UserProviderClient {
+       return &userProviderClient{cc}
+}
+
+func (c *userProviderClient) GetUser(ctx context.Context, in *GetUserRequest, 
opts ...grpc.CallOption) (*GetUserResponse, error) {
+       out := new(GetUserResponse)
+       err := c.cc.Invoke(ctx, "/provider.UserProvider/GetUser", in, out, 
opts...)
+       if err != nil {
+               return nil, err
+       }
+       return out, nil
+}
+
+// UserProviderServer is the server API for UserProvider service.
+// All implementations must embed UnimplementedUserProviderServer
+// for forward compatibility
+type UserProviderServer interface {
+       GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
+       mustEmbedUnimplementedUserProviderServer()
+}
+
+// UnimplementedUserProviderServer must be embedded to have forward compatible 
implementations.
+type UnimplementedUserProviderServer struct {
+}
+
+func (UnimplementedUserProviderServer) GetUser(context.Context, 
*GetUserRequest) (*GetUserResponse, error) {
+       return nil, status.Errorf(codes.Unimplemented, "method GetUser not 
implemented")
+}
+func (UnimplementedUserProviderServer) 
mustEmbedUnimplementedUserProviderServer() {}
+
+// UnsafeUserProviderServer may be embedded to opt out of forward 
compatibility for this service.
+// Use of this interface is not recommended, as added methods to 
UserProviderServer will
+// result in compilation errors.
+type UnsafeUserProviderServer interface {
+       mustEmbedUnimplementedUserProviderServer()
+}
+
+func RegisterUserProviderServer(s *grpc.Server, srv UserProviderServer) {
+       s.RegisterService(&_UserProvider_serviceDesc, srv)
+}
+
+func _UserProvider_GetUser_Handler(srv interface{}, ctx context.Context, dec 
func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, 
error) {
+       in := new(GetUserRequest)
+       if err := dec(in); err != nil {
+               return nil, err
+       }
+       if interceptor == nil {
+               return srv.(UserProviderServer).GetUser(ctx, in)
+       }
+       info := &grpc.UnaryServerInfo{
+               Server:     srv,
+               FullMethod: "/provider.UserProvider/GetUser",
+       }
+       handler := func(ctx context.Context, req interface{}) (interface{}, 
error) {
+               return srv.(UserProviderServer).GetUser(ctx, 
req.(*GetUserRequest))
+       }
+       return interceptor(ctx, in, info, handler)
+}
+
+var _UserProvider_serviceDesc = grpc.ServiceDesc{
+       ServiceName: "provider.UserProvider",
+       HandlerType: (*UserProviderServer)(nil),
+       Methods: []grpc.MethodDesc{
+               {
+                       MethodName: "GetUser",
+                       Handler:    _UserProvider_GetUser_Handler,
+               },
+       },
+       Streams:  []grpc.StreamDesc{},
+       Metadata: "hello_grpc.proto",
+}
diff --git a/samples/grpc/server/app/server.go 
b/samples/grpc/server/app/server.go
new file mode 100644
index 0000000..776d4cc
--- /dev/null
+++ b/samples/grpc/server/app/server.go
@@ -0,0 +1,85 @@
+/*
+ * 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"
+       "net"
+)
+
+import (
+       "google.golang.org/grpc"
+)
+
+import (
+       "github.com/apache/dubbo-go-pixiu/pkg/logger"
+       "github.com/apache/dubbo-go-pixiu/samples/http/grpc/proto"
+)
+
+const (
+       MsgUserNotFound          = "user not found"
+       MsgUserQuerySuccessfully = "user(s) query successfully"
+)
+
+// Test Cases
+// curl http://127.0.0.1:8881/api/v1/provider.UserProvider/GetUser
+// curl http://127.0.0.1:8881/api/v1/provider.UserProvider/GetUser -X POST -d 
'{"userId":1}'
+
+type server struct {
+       users map[int32]*proto.User
+       proto.UnimplementedUserProviderServer
+}
+
+func (s *server) GetUser(ctx context.Context, request *proto.GetUserRequest) 
(*proto.GetUserResponse, error) {
+       us := make([]*proto.User, 0)
+       if request.GetUserId() == 0 {
+               for i := 1; i <= 2; i++ {
+                       us = append(us, s.users[int32(i)])
+               }
+       } else {
+               u, ok := s.users[request.GetUserId()]
+               if !ok {
+                       return &proto.GetUserResponse{Message: 
MsgUserNotFound}, nil
+               }
+               us = append(us, u)
+       }
+       return &proto.GetUserResponse{Message: MsgUserQuerySuccessfully, Users: 
us}, nil
+}
+
+func initUsers(s *server) {
+       s.users[1] = &proto.User{UserId: 1, Name: "Kenway"}
+       s.users[2] = &proto.User{UserId: 2, Name: "Ken"}
+}
+
+func main() {
+       l, err := net.Listen("tcp", ":50001") //nolint:gosec
+       if err != nil {
+               panic(err)
+       }
+
+       s := &server{users: make(map[int32]*proto.User)}
+       initUsers(s)
+
+       gs := grpc.NewServer()
+       proto.RegisterUserProviderServer(gs, s)
+       logger.Info("grpc test server is now running...")
+       err = gs.Serve(l)
+       if err != nil {
+               panic(err)
+       }
+}
diff --git a/pkg/server/listener_test.go b/samples/grpc/test/pixiu_test.go
similarity index 50%
rename from pkg/server/listener_test.go
rename to samples/grpc/test/pixiu_test.go
index b3401f7..250f75e 100644
--- a/pkg/server/listener_test.go
+++ b/samples/grpc/test/pixiu_test.go
@@ -15,32 +15,43 @@
  * limitations under the License.
  */
 
-package server
+package test
 
 import (
-       ctxHttp "github.com/apache/dubbo-go-pixiu/pkg/context/http"
-       "github.com/apache/dubbo-go-pixiu/pkg/model"
+       "context"
+       "flag"
+       "log"
+       "testing"
+       "time"
 )
 
-func getTestContext() *ctxHttp.HttpContext {
-       l := ListenerService{
-               cfg: &model.Listener{
-                       Name: "test",
-                       Address: model.Address{
-                               SocketAddress: model.SocketAddress{
-                                       Protocol: model.ProtocolTypeHTTP,
-                                       Address:  "0.0.0.0",
-                                       Port:     8888,
-                               },
-                       },
-                       FilterChains: []model.FilterChain{},
-               },
-       }
+import (
+       "github.com/stretchr/testify/assert"
+       "google.golang.org/grpc"
+)
 
-       hc := &ctxHttp.HttpContext{
-               Listener: l.cfg,
-               Filters:  []ctxHttp.FilterFunc{},
+import (
+       pb "github.com/apache/dubbo-go-pixiu/samples/http/grpc/proto"
+)
+
+var (
+       addr = flag.String("addr", "localhost:8881", "the address to connect 
to")
+)
+
+func TestGet(t *testing.T) {
+       flag.Parse()
+       // Set up a connection to the server.
+       conn, err := grpc.Dial(*addr, grpc.WithInsecure())
+       if err != nil {
+               log.Fatalf("did not connect: %v", err)
        }
-       hc.Reset()
-       return hc
+       defer conn.Close()
+       c := pb.NewUserProviderClient(conn)
+
+       // Contact the server and print out its response.
+       ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+       defer cancel()
+       r, err := c.GetUser(ctx, &pb.GetUserRequest{UserId: 1})
+       assert.NoError(t, err)
+       assert.Equal(t, "user(s) query successfully", r.Message)
 }
diff --git a/samples/http/grpc/pixiu/conf.yaml 
b/samples/http/grpc/pixiu/conf.yaml
index 5b6faab..0489aea 100644
--- a/samples/http/grpc/pixiu/conf.yaml
+++ b/samples/http/grpc/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/http/simple/pixiu/conf.yaml 
b/samples/http/simple/pixiu/conf.yaml
index 9eebd84..ad238c1 100644
--- a/samples/http/simple/pixiu/conf.yaml
+++ b/samples/http/simple/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/https/pixiu/conf.yaml b/samples/https/pixiu/conf.yaml
index 334dc73..2515f5a 100644
--- a/samples/https/pixiu/conf.yaml
+++ b/samples/https/pixiu/conf.yaml
@@ -20,19 +20,15 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTPS"
       address:
         socket_address:
-          protocol_type: "HTTPS"
           domains:
             - "sample.domain.com"
             - "sample.domain-1.com"
             - "sample.domain-2.com"
           certs_dir: $PROJECT_DIR/cert
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/gateway/conf.yaml b/samples/seata/gateway/conf.yaml
index 9fca54c..dea4153 100644
--- a/samples/seata/gateway/conf.yaml
+++ b/samples/seata/gateway/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2046
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
@@ -62,16 +58,12 @@ static_resources:
         read_timeout: 5s
         write_timeout: 5s
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2047
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
@@ -105,16 +97,12 @@ static_resources:
         read_timeout: 5s
         write_timeout: 5s
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2048
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/sidecar/server_a/conf.yaml 
b/samples/seata/sidecar/server_a/conf.yaml
index dd57eac..fb24d51 100644
--- a/samples/seata/sidecar/server_a/conf.yaml
+++ b/samples/seata/sidecar/server_a/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2046
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/sidecar/server_b/conf.yaml 
b/samples/seata/sidecar/server_b/conf.yaml
index 60e75f3..2977ad6 100644
--- a/samples/seata/sidecar/server_b/conf.yaml
+++ b/samples/seata/sidecar/server_b/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2047
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/sidecar/server_c/conf.yaml 
b/samples/seata/sidecar/server_c/conf.yaml
index 66cc3d3..81d93ab 100644
--- a/samples/seata/sidecar/server_c/conf.yaml
+++ b/samples/seata/sidecar/server_c/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2048
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/springcloud/pixiu/conf.yaml 
b/samples/springcloud/pixiu/conf.yaml
index 897dc9a..f322eac 100644
--- a/samples/springcloud/pixiu/conf.yaml
+++ b/samples/springcloud/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/start_integrate_test.sh b/start_integrate_test.sh
index f55b57c..2d2cc6b 100755
--- a/start_integrate_test.sh
+++ b/start_integrate_test.sh
@@ -27,6 +27,8 @@ array+=("samples/dubbogo/http")
 ##http
 array+=("samples/http/grpc")
 array+=("samples/http/simple")
+## grpc proxy
+array+=("samples/grpc")
 
 for((i=0;i<${#array[*]};i++))
 do

Reply via email to