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 }