dubbo.apache.org/dubbo-go/v3@v3.1.1/protocol/rest/config/reader/rest_config_reader.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 reader
    19  
    20  import (
    21  	"bytes"
    22  	"strconv"
    23  	"strings"
    24  )
    25  
    26  import (
    27  	"github.com/dubbogo/gost/log/logger"
    28  
    29  	perrors "github.com/pkg/errors"
    30  
    31  	"gopkg.in/yaml.v2"
    32  )
    33  
    34  import (
    35  	"dubbo.apache.org/dubbo-go/v3/common/constant"
    36  	"dubbo.apache.org/dubbo-go/v3/common/extension"
    37  	"dubbo.apache.org/dubbo-go/v3/config/interfaces"
    38  	"dubbo.apache.org/dubbo-go/v3/protocol/rest/config"
    39  )
    40  
    41  const REST = "rest"
    42  
    43  func init() {
    44  	extension.SetConfigReaders(REST, NewRestConfigReader)
    45  	extension.SetDefaultConfigReader(REST, REST)
    46  }
    47  
    48  type RestConfigReader struct{}
    49  
    50  func NewRestConfigReader() interfaces.ConfigReader {
    51  	return &RestConfigReader{}
    52  }
    53  
    54  // ReadConsumerConfig read consumer config for rest protocol
    55  func (cr *RestConfigReader) ReadConsumerConfig(reader *bytes.Buffer) error {
    56  	restConsumerConfig := &config.RestConsumerConfig{}
    57  	err := yaml.Unmarshal(reader.Bytes(), restConsumerConfig)
    58  	if err != nil {
    59  		return perrors.Errorf("[Rest ShutdownConfig] unmarshal Consumer error %#v", perrors.WithStack(err))
    60  	}
    61  
    62  	restConsumerServiceConfigMap := make(map[string]*config.RestServiceConfig, len(restConsumerConfig.RestServiceConfigsMap))
    63  	for key, rc := range restConsumerConfig.RestServiceConfigsMap {
    64  		rc.Client = getNotEmptyStr(rc.Client, restConsumerConfig.Client, constant.DefaultRestClient)
    65  		rc.RestMethodConfigsMap = initMethodConfigMap(rc, restConsumerConfig.Consumes, restConsumerConfig.Produces)
    66  		restConsumerServiceConfigMap[key] = rc
    67  	}
    68  	config.SetRestConsumerServiceConfigMap(restConsumerServiceConfigMap)
    69  	return nil
    70  }
    71  
    72  // ReadProviderConfig read provider config for rest protocol
    73  func (cr *RestConfigReader) ReadProviderConfig(reader *bytes.Buffer) error {
    74  	restProviderConfig := &config.RestProviderConfig{}
    75  	err := yaml.Unmarshal(reader.Bytes(), restProviderConfig)
    76  	if err != nil {
    77  		return perrors.Errorf("[Rest ShutdownConfig] unmarshal Provider error %#v", perrors.WithStack(err))
    78  	}
    79  	restProviderServiceConfigMap := make(map[string]*config.RestServiceConfig, len(restProviderConfig.RestServiceConfigsMap))
    80  	for key, rc := range restProviderConfig.RestServiceConfigsMap {
    81  		rc.Server = getNotEmptyStr(rc.Server, restProviderConfig.Server, constant.DefaultRestServer)
    82  		rc.RestMethodConfigsMap = initMethodConfigMap(rc, restProviderConfig.Consumes, restProviderConfig.Produces)
    83  		restProviderServiceConfigMap[key] = rc
    84  	}
    85  	config.SetRestProviderServiceConfigMap(restProviderServiceConfigMap)
    86  	return nil
    87  }
    88  
    89  // initProviderRestConfig ...
    90  func initMethodConfigMap(rc *config.RestServiceConfig, consumes string, produces string) map[string]*config.RestMethodConfig {
    91  	mcm := make(map[string]*config.RestMethodConfig, len(rc.RestMethodConfigs))
    92  	for _, mc := range rc.RestMethodConfigs {
    93  		mc.InterfaceName = rc.InterfaceName
    94  		mc.Path = rc.Path + mc.Path
    95  		mc.Consumes = getNotEmptyStr(mc.Consumes, rc.Consumes, consumes)
    96  		mc.Produces = getNotEmptyStr(mc.Produces, rc.Produces, produces)
    97  		mc.MethodType = getNotEmptyStr(mc.MethodType, rc.MethodType)
    98  		mc = transformMethodConfig(mc)
    99  		mcm[mc.MethodName] = mc
   100  	}
   101  	return mcm
   102  }
   103  
   104  // function will return first not empty string ..
   105  func getNotEmptyStr(args ...string) string {
   106  	var r string
   107  	for _, t := range args {
   108  		if len(t) > 0 {
   109  			r = t
   110  			break
   111  		}
   112  	}
   113  	return r
   114  }
   115  
   116  // transformMethodConfig
   117  func transformMethodConfig(methodConfig *config.RestMethodConfig) *config.RestMethodConfig {
   118  	if len(methodConfig.PathParamsMap) == 0 && len(methodConfig.PathParams) > 0 {
   119  		paramsMap, err := parseParamsString2Map(methodConfig.PathParams)
   120  		if err != nil {
   121  			logger.Warnf("[Rest ShutdownConfig] Path Param parse error:%v", err)
   122  		} else {
   123  			methodConfig.PathParamsMap = paramsMap
   124  		}
   125  	}
   126  	if len(methodConfig.QueryParamsMap) == 0 && len(methodConfig.QueryParams) > 0 {
   127  		paramsMap, err := parseParamsString2Map(methodConfig.QueryParams)
   128  		if err != nil {
   129  			logger.Warnf("[Rest ShutdownConfig] Argument Param parse error:%v", err)
   130  		} else {
   131  			methodConfig.QueryParamsMap = paramsMap
   132  		}
   133  	}
   134  	if len(methodConfig.HeadersMap) == 0 && len(methodConfig.Headers) > 0 {
   135  		headersMap, err := parseParamsString2Map(methodConfig.Headers)
   136  		if err != nil {
   137  			logger.Warnf("[Rest ShutdownConfig] Argument Param parse error:%v", err)
   138  		} else {
   139  			methodConfig.HeadersMap = headersMap
   140  		}
   141  	}
   142  	return methodConfig
   143  }
   144  
   145  // transform a string to a map
   146  // for example:
   147  // string "0:id,1:name" => map [0:id,1:name]
   148  func parseParamsString2Map(params string) (map[int]string, error) {
   149  	m := make(map[int]string, 8)
   150  	for _, p := range strings.Split(params, ",") {
   151  		pa := strings.Split(p, ":")
   152  		key, err := strconv.Atoi(pa[0])
   153  		if err != nil {
   154  			return nil, err
   155  		}
   156  		m[key] = pa[1]
   157  	}
   158  	return m, nil
   159  }