go.uber.org/yarpc@v1.72.1/api/transport/request.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package transport 22 23 import ( 24 "context" 25 "io" 26 "strings" 27 28 "go.uber.org/yarpc/yarpcerrors" 29 "go.uber.org/zap/zapcore" 30 ) 31 32 // Request is the low level request representation. 33 type Request struct { 34 // Name of the service making the request. 35 Caller string 36 37 // Name of the service to which the request is being made. 38 // The service refers to the canonical traffic group for the service. 39 Service string 40 41 // Name of the transport used for the call. 42 Transport string 43 44 // Name of the encoding used for the request body. 45 Encoding Encoding 46 47 // Name of the procedure being called. 48 Procedure string 49 50 // Headers for the request. 51 Headers Headers 52 53 // ShardKey is an opaque string that is meaningful to the destined service 54 // for how to relay a request within a cluster to the shard that owns the 55 // key. 56 ShardKey string 57 58 // RoutingKey refers to a traffic group for the destined service, and when 59 // present may override the service name for purposes of routing. 60 RoutingKey string 61 62 // RoutingDelegate refers to the traffic group for a service that proxies 63 // for the destined service for routing purposes. The routing delegate may 64 // override the routing key and service. 65 RoutingDelegate string 66 67 // CallerProcedure refers to the name of the rpc procedure from the service making this request. 68 CallerProcedure string 69 70 // Request payload. 71 Body io.Reader 72 73 // Request payload size before any compression applied by the protocol 74 // When using the HTTP transport, this value is set from the HTTP header 75 // content-length. It should be noted that this value is set manually and 76 // will not be updated automatically if the body is being modified 77 BodySize int 78 } 79 80 // ToRequestMeta converts a Request into a RequestMeta. 81 func (r *Request) ToRequestMeta() *RequestMeta { 82 return &RequestMeta{ 83 Caller: r.Caller, 84 Service: r.Service, 85 Transport: r.Transport, 86 Encoding: r.Encoding, 87 Procedure: r.Procedure, 88 Headers: r.Headers, 89 ShardKey: r.ShardKey, 90 RoutingKey: r.RoutingKey, 91 RoutingDelegate: r.RoutingDelegate, 92 CallerProcedure: r.CallerProcedure, 93 } 94 } 95 96 // MarshalLogObject implements zap.ObjectMarshaler. 97 func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error { 98 // TODO (#788): Include headers once we can omit PII. 99 enc.AddString("caller", r.Caller) 100 enc.AddString("service", r.Service) 101 enc.AddString("transport", r.Transport) 102 enc.AddString("encoding", string(r.Encoding)) 103 enc.AddString("procedure", r.Procedure) 104 enc.AddString("shardKey", r.ShardKey) 105 enc.AddString("routingKey", r.RoutingKey) 106 enc.AddString("routingDelegate", r.RoutingDelegate) 107 enc.AddString("callerProcedure", r.CallerProcedure) 108 return nil 109 } 110 111 // Encoding represents an encoding format for requests. 112 type Encoding string 113 114 // ValidateRequest validates the given request. An error is returned if the 115 // request is invalid. 116 // 117 // Inbound transport implementations may use this to validate requests before 118 // handling them. Outbound implementations don't need to validate requests; 119 // they are always validated before the outbound is called. 120 func ValidateRequest(req *Request) error { 121 var missingParams []string 122 if req.Service == "" { 123 missingParams = append(missingParams, "service name") 124 } 125 if req.Procedure == "" { 126 missingParams = append(missingParams, "procedure") 127 } 128 if req.Caller == "" { 129 missingParams = append(missingParams, "caller name") 130 } 131 if req.Encoding == "" { 132 missingParams = append(missingParams, "encoding") 133 } 134 if len(missingParams) > 0 { 135 return yarpcerrors.Newf(yarpcerrors.CodeInvalidArgument, "missing %s", strings.Join(missingParams, ", ")) 136 } 137 return nil 138 } 139 140 // ValidateUnaryContext validates that a context for a unary request is valid 141 // and contains all required information, and returns a YARPC error with code 142 // yarpcerrors.CodeInvalidArgument otherwise. 143 // 144 // Deprecated: Use ValidateRequestContext instead. 145 func ValidateUnaryContext(ctx context.Context) error { 146 if _, hasDeadline := ctx.Deadline(); !hasDeadline { 147 return yarpcerrors.Newf(yarpcerrors.CodeInvalidArgument, "missing TTL") 148 } 149 return nil 150 } 151 152 // ValidateRequestContext validates that a context for a request is valid 153 // and contains all required information, and returns a YARPC error with code 154 // yarpcerrors.CodeInvalidArgument otherwise. 155 func ValidateRequestContext(ctx context.Context) error { 156 if _, hasDeadline := ctx.Deadline(); !hasDeadline { 157 return yarpcerrors.Newf(yarpcerrors.CodeInvalidArgument, "missing TTL") 158 } 159 return nil 160 } 161 162 // RequestMeta is the low level request metadata representation. It does not 163 // include any "body" information, and should only be used for information about 164 // a connection's metadata. 165 type RequestMeta struct { 166 // Name of the service making the request. 167 Caller string 168 169 // Name of the service to which the request is being made. 170 // The service refers to the canonical traffic group for the service. 171 Service string 172 173 // Name of the transport used for the call. 174 Transport string 175 176 // Name of the encoding used for the request body. 177 Encoding Encoding 178 179 // Name of the procedure being called. 180 Procedure string 181 182 // Headers for the request. 183 Headers Headers 184 185 // ShardKey is an opaque string that is meaningful to the destined service 186 // for how to relay a request within a cluster to the shard that owns the 187 // key. 188 ShardKey string 189 190 // RoutingKey refers to a traffic group for the destined service, and when 191 // present may override the service name for purposes of routing. 192 RoutingKey string 193 194 // RoutingDelegate refers to the traffic group for a service that proxies 195 // for the destined service for routing purposes. The routing delegate may 196 // override the routing key and service. 197 RoutingDelegate string 198 199 // CallerProcedure refers to the name of the rpc procedure of the service making this request. 200 CallerProcedure string 201 } 202 203 // ToRequest converts a RequestMeta into a Request. 204 func (r *RequestMeta) ToRequest() *Request { 205 if r == nil { 206 return &Request{} 207 } 208 return &Request{ 209 Caller: r.Caller, 210 Service: r.Service, 211 Transport: r.Transport, 212 Encoding: r.Encoding, 213 Procedure: r.Procedure, 214 Headers: r.Headers, 215 ShardKey: r.ShardKey, 216 RoutingKey: r.RoutingKey, 217 RoutingDelegate: r.RoutingDelegate, 218 CallerProcedure: r.CallerProcedure, 219 } 220 }