dubbo.apache.org/dubbo-go/v3@v3.1.1/protocol/rest/server/server_impl/go_restful_server.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package server_impl 19 20 import ( 21 "context" 22 "fmt" 23 "net" 24 "net/http" 25 "strings" 26 "time" 27 ) 28 29 import ( 30 "github.com/dubbogo/gost/log/logger" 31 32 "github.com/emicklei/go-restful/v3" 33 34 perrors "github.com/pkg/errors" 35 ) 36 37 import ( 38 "dubbo.apache.org/dubbo-go/v3/common" 39 "dubbo.apache.org/dubbo-go/v3/common/constant" 40 "dubbo.apache.org/dubbo-go/v3/common/extension" 41 "dubbo.apache.org/dubbo-go/v3/protocol/rest/config" 42 "dubbo.apache.org/dubbo-go/v3/protocol/rest/server" 43 ) 44 45 func init() { 46 extension.SetRestServer(constant.DefaultRestServer, NewGoRestfulServer) 47 } 48 49 var filterSlice []restful.FilterFunction 50 51 // GoRestfulServer a rest server implement by go-restful 52 type GoRestfulServer struct { 53 srv *http.Server 54 ws *restful.WebService 55 } 56 57 // NewGoRestfulServer a constructor of GoRestfulServer 58 func NewGoRestfulServer() server.RestServer { 59 return &GoRestfulServer{} 60 } 61 62 // Start go-restful server 63 // It will add all go-restful filters 64 func (grs *GoRestfulServer) Start(url *common.URL) { 65 container := restful.NewContainer() 66 for _, filter := range filterSlice { 67 container.Filter(filter) 68 } 69 grs.srv = &http.Server{ 70 Handler: container, 71 } 72 grs.ws = &restful.WebService{} 73 grs.ws.Path("/") 74 grs.ws.SetDynamicRoutes(true) 75 container.Add(grs.ws) 76 ln, err := net.Listen("tcp", url.Location) 77 if err != nil { 78 panic(perrors.New(fmt.Sprintf("Restful Server start error:%v", err))) 79 } 80 81 go func() { 82 err := grs.srv.Serve(ln) 83 if err != nil && err != http.ErrServerClosed { 84 logger.Errorf("[Go Restful] http.server.Serve(addr{%s}) = err{%+v}", url.Location, err) 85 } 86 }() 87 } 88 89 // Deploy is to Publish a http api in go-restful server 90 // The routeFunc should be invoked when the server receive a request 91 func (grs *GoRestfulServer) Deploy(restMethodConfig *config.RestMethodConfig, routeFunc func(request server.RestServerRequest, response server.RestServerResponse)) { 92 rf := func(req *restful.Request, resp *restful.Response) { 93 routeFunc(NewGoRestfulRequestAdapter(req), resp) 94 } 95 grs.ws.Route(grs.ws.Method(restMethodConfig.MethodType). 96 Produces(strings.Split(restMethodConfig.Produces, ",")...). 97 Consumes(strings.Split(restMethodConfig.Consumes, ",")...). 98 Path(restMethodConfig.Path).To(rf)) 99 } 100 101 // UnDeploy is to Delete a http api in go-restful server 102 func (grs *GoRestfulServer) UnDeploy(restMethodConfig *config.RestMethodConfig) { 103 err := grs.ws.RemoveRoute(restMethodConfig.Path, restMethodConfig.MethodType) 104 if err != nil { 105 logger.Warnf("[Go restful] Remove web service error:%v", err) 106 } 107 } 108 109 // Destroy the go-restful server 110 func (grs *GoRestfulServer) Destroy() { 111 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 112 defer cancel() 113 if err := grs.srv.Shutdown(ctx); err != nil { 114 logger.Errorf("[Go Restful] Server Shutdown:", err) 115 } 116 logger.Infof("[Go Restful] Server exiting") 117 } 118 119 // AddGoRestfulServerFilter let user add the http server of go-restful 120 // addFilter should before config.Load() 121 func AddGoRestfulServerFilter(filterFuc restful.FilterFunction) { 122 filterSlice = append(filterSlice, filterFuc) 123 } 124 125 // GoRestfulRequestAdapter a adapter struct about RestServerRequest 126 type GoRestfulRequestAdapter struct { 127 server.RestServerRequest 128 request *restful.Request 129 } 130 131 // NewGoRestfulRequestAdapter a constructor of GoRestfulRequestAdapter 132 func NewGoRestfulRequestAdapter(request *restful.Request) *GoRestfulRequestAdapter { 133 return &GoRestfulRequestAdapter{request: request} 134 } 135 136 // RawRequest a adapter function of server.RestServerRequest's RawRequest 137 func (grra *GoRestfulRequestAdapter) RawRequest() *http.Request { 138 return grra.request.Request 139 } 140 141 // PathParameter a adapter function of server.RestServerRequest's PathParameter 142 func (grra *GoRestfulRequestAdapter) PathParameter(name string) string { 143 return grra.request.PathParameter(name) 144 } 145 146 // PathParameters a adapter function of server.RestServerRequest's QueryParameter 147 func (grra *GoRestfulRequestAdapter) PathParameters() map[string]string { 148 return grra.request.PathParameters() 149 } 150 151 // QueryParameter a adapter function of server.RestServerRequest's QueryParameters 152 func (grra *GoRestfulRequestAdapter) QueryParameter(name string) string { 153 return grra.request.QueryParameter(name) 154 } 155 156 // QueryParameters a adapter function of server.RestServerRequest's QueryParameters 157 func (grra *GoRestfulRequestAdapter) QueryParameters(name string) []string { 158 return grra.request.QueryParameters(name) 159 } 160 161 // BodyParameter a adapter function of server.RestServerRequest's BodyParameter 162 func (grra *GoRestfulRequestAdapter) BodyParameter(name string) (string, error) { 163 return grra.request.BodyParameter(name) 164 } 165 166 // HeaderParameter a adapter function of server.RestServerRequest's HeaderParameter 167 func (grra *GoRestfulRequestAdapter) HeaderParameter(name string) string { 168 return grra.request.HeaderParameter(name) 169 } 170 171 // ReadEntity a adapter func of server.RestServerRequest's ReadEntity 172 func (grra *GoRestfulRequestAdapter) ReadEntity(entityPointer interface{}) error { 173 return grra.request.ReadEntity(entityPointer) 174 }