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  }