Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customer APIs should not be in the runtime package #21406

Merged
merged 1 commit into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions sdk/azcore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

### Other Changes

* The following functions in the `runtime` package are now exposed from the `policy` package, and the `runtime` versions have been deprecated.
* `WithCaptureResponse`
* `WithHTTPHeader`
* `WithRetryOptions`

## 1.8.0-beta.2 (2023-08-14)

### Features Added
Expand Down
4 changes: 2 additions & 2 deletions sdk/azcore/internal/shared/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ type CtxWithHTTPHeaderKey struct{}
// CtxWithRetryOptionsKey is used as a context key for adding/retrieving RetryOptions.
type CtxWithRetryOptionsKey struct{}

// CtxIncludeResponseKey is used as a context key for retrieving the raw response.
type CtxIncludeResponseKey struct{}
// CtxWithCaptureResponse is used as a context key for retrieving the raw response.
type CtxWithCaptureResponse struct{}

// CtxWithTracingTracer is used as a context key for adding/retrieving tracing.Tracer.
type CtxWithTracingTracer struct{}
Expand Down
46 changes: 46 additions & 0 deletions sdk/azcore/policy/examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//go:build go1.16
// +build go1.16

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package policy_test

import (
"context"
"net/http"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
)

func ExampleWithCaptureResponse() {
// policy.WithCaptureResponse provides a mechanism for obtaining an API's underlying *http.Response
var respFromCtx *http.Response
ctx := policy.WithCaptureResponse(context.TODO(), &respFromCtx)
// make some client method call using the updated context
// resp, err := client.SomeMethod(ctx, ...)
// *respFromCtx contains the raw *http.Response returned during the client method call.
// if the HTTP transport didn't return a response due to an error then *respFromCtx will be nil.
_ = ctx
}

func ExampleWithHTTPHeader() {
// policy.WithHTTPHeader allows callers to augment API calls with custom headers
customHeaders := http.Header{}
customHeaders.Add("key", "value")
ctx := policy.WithHTTPHeader(context.TODO(), customHeaders)
// make some client method call using the updated context
// resp, err := client.SomeMethod(ctx, ...)
// the underlying HTTP request will include the values in customHeaders
_ = ctx
}

func ExampleWithRetryOptions() {
// policy.WithRetryOptions contains a [policy.RetryOptions] that can be used to customize the retry policy on a per-API call basis
customRetryOptions := policy.RetryOptions{ /* populate with custom values */ }
ctx := policy.WithRetryOptions(context.TODO(), customRetryOptions)
// make some client method call using the updated context
// resp, err := client.SomeMethod(ctx, ...)
// the behavior of the retry policy will correspond to the values provided in customRetryPolicy
_ = ctx
}
21 changes: 21 additions & 0 deletions sdk/azcore/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
package policy

import (
"context"
"net/http"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
)

Expand Down Expand Up @@ -163,3 +165,22 @@ type AuthorizationHandler struct {
// the policy will return any 401 response to the client.
OnChallenge func(*Request, *http.Response, func(TokenRequestOptions) error) error
}

// WithCaptureResponse applies the HTTP response retrieval annotation to the parent context.
// The resp parameter will contain the HTTP response after the request has completed.
func WithCaptureResponse(parent context.Context, resp **http.Response) context.Context {
return context.WithValue(parent, shared.CtxWithCaptureResponse{}, resp)
}

// WithHTTPHeader adds the specified http.Header to the parent context.
// Use this to specify custom HTTP headers at the API-call level.
// Any overlapping headers will have their values replaced with the values specified here.
func WithHTTPHeader(parent context.Context, header http.Header) context.Context {
return context.WithValue(parent, shared.CtxWithHTTPHeaderKey{}, header)
}

// WithRetryOptions adds the specified RetryOptions to the parent context.
// Use this to specify custom RetryOptions at the API-call level.
func WithRetryOptions(parent context.Context, options RetryOptions) context.Context {
return context.WithValue(parent, shared.CtxWithRetryOptionsKey{}, options)
}
53 changes: 53 additions & 0 deletions sdk/azcore/policy/policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//go:build go1.18
// +build go1.18

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package policy

import (
"context"
"math"
"net/http"
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
"github.com/stretchr/testify/require"
)

func TestWithCaptureResponse(t *testing.T) {
var httpResp *http.Response
ctx := WithCaptureResponse(context.Background(), &httpResp)
require.NotNil(t, ctx)
raw := ctx.Value(shared.CtxWithCaptureResponse{})
resp, ok := raw.(**http.Response)
require.True(t, ok)
require.Same(t, &httpResp, resp)
}

func TestWithHTTPHeader(t *testing.T) {
const (
key = "some"
val = "thing"
)
input := http.Header{}
input.Set(key, val)
ctx := WithHTTPHeader(context.Background(), input)
require.NotNil(t, ctx)
raw := ctx.Value(shared.CtxWithHTTPHeaderKey{})
header, ok := raw.(http.Header)
require.True(t, ok)
require.EqualValues(t, val, header.Get(key))
}

func TestWithRetryOptions(t *testing.T) {
ctx := WithRetryOptions(context.Background(), RetryOptions{
MaxRetries: math.MaxInt32,
})
require.NotNil(t, ctx)
raw := ctx.Value(shared.CtxWithRetryOptionsKey{})
opts, ok := raw.(RetryOptions)
require.True(t, ok)
require.EqualValues(t, math.MaxInt32, opts.MaxRetries)
}
25 changes: 0 additions & 25 deletions sdk/azcore/runtime/examples_test.go

This file was deleted.

3 changes: 2 additions & 1 deletion sdk/azcore/runtime/policy_http_header.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func httpHeaderPolicy(req *policy.Request) (*http.Response, error) {
// WithHTTPHeader adds the specified http.Header to the parent context.
// Use this to specify custom HTTP headers at the API-call level.
// Any overlapping headers will have their values replaced with the values specified here.
// Deprecated: use [policy.WithHTTPHeader] instead.
func WithHTTPHeader(parent context.Context, header http.Header) context.Context {
return context.WithValue(parent, shared.CtxWithHTTPHeaderKey{}, header)
return policy.WithHTTPHeader(parent, header)
}
5 changes: 3 additions & 2 deletions sdk/azcore/runtime/policy_include_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func includeResponsePolicy(req *policy.Request) (*http.Response, error) {
if resp == nil {
return resp, err
}
if httpOutRaw := req.Raw().Context().Value(shared.CtxIncludeResponseKey{}); httpOutRaw != nil {
if httpOutRaw := req.Raw().Context().Value(shared.CtxWithCaptureResponse{}); httpOutRaw != nil {
httpOut := httpOutRaw.(**http.Response)
*httpOut = resp
}
Expand All @@ -29,6 +29,7 @@ func includeResponsePolicy(req *policy.Request) (*http.Response, error) {

// WithCaptureResponse applies the HTTP response retrieval annotation to the parent context.
// The resp parameter will contain the HTTP response after the request has completed.
// Deprecated: use [policy.WithCaptureResponse] instead.
func WithCaptureResponse(parent context.Context, resp **http.Response) context.Context {
return context.WithValue(parent, shared.CtxIncludeResponseKey{}, resp)
return policy.WithCaptureResponse(parent, resp)
}
2 changes: 1 addition & 1 deletion sdk/azcore/runtime/policy_include_response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestIncludeResponse(t *testing.T) {
var respFromCtx *http.Response
ctx := WithCaptureResponse(context.Background(), &respFromCtx)
require.NotNil(t, ctx)
raw := ctx.Value(shared.CtxIncludeResponseKey{})
raw := ctx.Value(shared.CtxWithCaptureResponse{})
_, ok := raw.(**http.Response)
require.Truef(t, ok, "unexpected type %T", raw)
require.Nil(t, respFromCtx)
Expand Down
3 changes: 2 additions & 1 deletion sdk/azcore/runtime/policy_retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,9 @@ func (p *retryPolicy) Do(req *policy.Request) (resp *http.Response, err error) {

// WithRetryOptions adds the specified RetryOptions to the parent context.
// Use this to specify custom RetryOptions at the API-call level.
// Deprecated: use [policy.WithRetryOptions] instead.
func WithRetryOptions(parent context.Context, options policy.RetryOptions) context.Context {
return context.WithValue(parent, shared.CtxWithRetryOptionsKey{}, options)
return policy.WithRetryOptions(parent, options)
}

// ********** The following type/methods implement the retryableRequestBody (a ReadSeekCloser)
Expand Down