@@ -92,18 +92,17 @@ type CallOptions struct {
92
92
// To is the Target to be called. Required.
93
93
To Instance
94
94
95
- // Port on the target Instance. Either Port or PortName must be specified.
96
- Port * Port
95
+ // Port to be used for the call. Ignored if Scheme == DNS. If the Port.ServicePort is set,
96
+ // either Port.Protocol or Scheme must also be set. If Port.ServicePort is not set,
97
+ // the port is looked up in To by either Port.Name or Port.Protocol.
98
+ Port Port
97
99
98
- // PortName of the port on the target Instance. Either Port or PortName must be specified.
99
- PortName string
100
-
101
- // Scheme to be used when making the call. If not provided, an appropriate default for the
102
- // port will be used (if feasible).
100
+ // Scheme to be used when making the call. If not provided, the Scheme will be selected
101
+ // based on the Port.Protocol.
103
102
Scheme scheme.Instance
104
103
105
104
// Address specifies the host name or IP address to be used on the request. If not provided,
106
- // an appropriate default is chosen for the target Instance .
105
+ // an appropriate default is chosen for To .
107
106
Address string
108
107
109
108
// Count indicates the number of exchanges that should be made with the service endpoint.
@@ -161,10 +160,6 @@ func (o CallOptions) GetHost() string {
161
160
162
161
func (o CallOptions ) DeepCopy () CallOptions {
163
162
clone := o
164
- if o .Port != nil {
165
- dc := * o .Port
166
- clone .Port = & dc
167
- }
168
163
if o .TLS .Alpn != nil {
169
164
clone .TLS .Alpn = make ([]string , len (o .TLS .Alpn ))
170
165
copy (clone .TLS .Alpn , o .TLS .Alpn )
@@ -174,50 +169,112 @@ func (o CallOptions) DeepCopy() CallOptions {
174
169
175
170
// FillDefaults fills out any defaults that haven't been explicitly specified.
176
171
func (o * CallOptions ) FillDefaults () error {
172
+ // Fill in the address if not set.
173
+ if err := o .fillAddress (); err != nil {
174
+ return err
175
+ }
176
+
177
+ // Fill in the port if not set or the service port is missing.
178
+ if err := o .fillPort (); err != nil {
179
+ return err
180
+ }
181
+
182
+ // Fill in the scheme if not set, using the port information.
183
+ if err := o .fillScheme (); err != nil {
184
+ return err
185
+ }
186
+
187
+ // Fill in HTTP headers
188
+ o .fillHeaders ()
189
+
190
+ if o .Timeout <= 0 {
191
+ o .Timeout = common .DefaultRequestTimeout
192
+ }
193
+
194
+ if o .Count <= 0 {
195
+ o .Count = common .DefaultCount
196
+ }
197
+
198
+ // Add any user-specified options after the default options (last option wins for each type of option).
199
+ o .Retry .Options = append (append ([]retry.Option {}, DefaultCallRetryOptions ()... ), o .Retry .Options ... )
200
+
201
+ // If no Check was specified, assume no error.
202
+ if o .Check == nil {
203
+ o .Check = check .None ()
204
+ }
205
+ return nil
206
+ }
207
+
208
+ func (o * CallOptions ) fillAddress () error {
209
+ if o .Address == "" {
210
+ if o .To == nil {
211
+ return errors .New ("if address is not set, then To must be set" )
212
+ }
213
+
214
+ // No host specified, use the fully qualified domain name for the service.
215
+ o .Address = o .To .Config ().ClusterLocalFQDN ()
216
+ }
217
+ return nil
218
+ }
219
+
220
+ func (o * CallOptions ) fillPort () error {
221
+ if o .Scheme == scheme .DNS {
222
+ // Port is not used for DNS.
223
+ return nil
224
+ }
225
+
226
+ if o .Port .ServicePort > 0 {
227
+ if o .Port .Protocol == "" && o .Scheme == "" {
228
+ return errors .New ("callOptions: servicePort specified, but no protocol or scheme was set" )
229
+ }
230
+
231
+ // The service port was set explicitly. Nothing else to do.
232
+ return nil
233
+ }
234
+
177
235
if o .To != nil {
178
236
servicePorts := o .To .Config ().Ports .GetServicePorts ()
179
- if o .PortName == "" {
180
- // Validate the Port value.
181
237
182
- if o .Port == nil {
183
- return errors .New ("callOptions: PortName or Port must be provided" )
238
+ if o .Port .Name != "" {
239
+ // Look up the port by name.
240
+ p , found := servicePorts .ForName (o .Port .Name )
241
+ if ! found {
242
+ return fmt .Errorf ("callOptions: no port named %s available in To Instance" , o .Port .Name )
184
243
}
244
+ o .Port = p
245
+ return nil
246
+ }
185
247
186
- // Check the specified port for a match against the To Instance
187
- if ! servicePorts .Contains (* o .Port ) {
188
- return fmt .Errorf ("callOptions: Port does not match any To port" )
189
- }
190
- } else {
191
- // Look up the port.
192
- p , found := servicePorts .ForName (o .PortName )
248
+ if o .Port .Protocol != "" {
249
+ // Look up the port by protocol.
250
+ p , found := servicePorts .ForProtocol (o .Port .Protocol )
193
251
if ! found {
194
- return fmt .Errorf ("callOptions: no port named %s available in To Instance" , o .PortName )
252
+ return fmt .Errorf ("callOptions: no port for protocol %s available in To Instance" , o .Port . Protocol )
195
253
}
196
- o .Port = & p
197
- }
198
- } else if o .Scheme == scheme .DNS {
199
- // Just need address
200
- if o .Address == "" {
201
- return fmt .Errorf ("for DNS, address must be set" )
254
+ o .Port = p
255
+ return nil
202
256
}
203
- o .Port = & Port {}
204
- } else if o .Port == nil || o .Port .ServicePort <= 0 || (o .Port .Protocol == "" && o .Scheme == "" ) || o .Address == "" {
257
+ }
258
+
259
+ if o .Port .ServicePort <= 0 || (o .Port .Protocol == "" && o .Scheme == "" ) || o .Address == "" {
205
260
return fmt .Errorf ("if target is not set, then port.servicePort, port.protocol or schema, and address must be set" )
206
261
}
207
262
263
+ return nil
264
+ }
265
+
266
+ func (o * CallOptions ) fillScheme () error {
208
267
if o .Scheme == "" {
209
268
// No protocol, fill it in.
210
269
var err error
211
270
if o .Scheme , err = o .Port .Scheme (); err != nil {
212
271
return err
213
272
}
214
273
}
274
+ return nil
275
+ }
215
276
216
- if o .Address == "" {
217
- // No host specified, use the fully qualified domain name for the service.
218
- o .Address = o .To .Config ().ClusterLocalFQDN ()
219
- }
220
-
277
+ func (o * CallOptions ) fillHeaders () {
221
278
// Initialize the headers and add a default Host header if none provided.
222
279
if o .HTTP .Headers == nil {
223
280
o .HTTP .Headers = make (http.Header )
@@ -229,21 +286,4 @@ func (o *CallOptions) FillDefaults() error {
229
286
if h := o .GetHost (); len (h ) > 0 {
230
287
o .HTTP .Headers .Set (headers .Host , h )
231
288
}
232
-
233
- if o .Timeout <= 0 {
234
- o .Timeout = common .DefaultRequestTimeout
235
- }
236
-
237
- if o .Count <= 0 {
238
- o .Count = common .DefaultCount
239
- }
240
-
241
- // Add any user-specified options after the default options (last option wins for each type of option).
242
- o .Retry .Options = append (append ([]retry.Option {}, DefaultCallRetryOptions ()... ), o .Retry .Options ... )
243
-
244
- // If no Check was specified, assume no error.
245
- if o .Check == nil {
246
- o .Check = check .None ()
247
- }
248
- return nil
249
289
}
0 commit comments