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

Removed and renamed some content #15285

Merged
merged 1 commit into from
Aug 13, 2021
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
61 changes: 8 additions & 53 deletions sdk/azcore/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package azcore

import (
"context"
"errors"
"io"
"net/http"
Expand All @@ -31,33 +30,24 @@ type Policy interface {
Do(req *Request) (*Response, error)
}

// PolicyFunc is a type that implements the Policy interface.
// policyFunc is a type that implements the Policy interface.
// Use this type when implementing a stateless policy as a first-class function.
type PolicyFunc func(*Request) (*Response, error)
type policyFunc func(*Request) (*Response, error)

// Do implements the Policy interface on PolicyFunc.
func (pf PolicyFunc) Do(req *Request) (*Response, error) {
func (pf policyFunc) Do(req *Request) (*Response, error) {
return pf(req)
}

// Transport represents an HTTP pipeline transport used to send HTTP requests and receive responses.
type Transport interface {
// Transporter represents an HTTP pipeline transport used to send HTTP requests and receive responses.
type Transporter interface {
// Do sends the HTTP request and returns the HTTP response or error.
Do(req *http.Request) (*http.Response, error)
}

// TransportFunc is a type that implements the Transport interface.
// Use this type when implementing a stateless transport as a first-class function.
type TransportFunc func(*http.Request) (*http.Response, error)

// Do implements the Transport interface on TransportFunc.
func (tf TransportFunc) Do(req *http.Request) (*http.Response, error) {
return tf(req)
}

// used to adapt a TransportPolicy to a Policy
type transportPolicy struct {
trans Transport
trans Transporter
}

func (tp transportPolicy) Do(req *Request) (*Response, error) {
Expand All @@ -80,12 +70,12 @@ type Pipeline struct {

// NewPipeline creates a new Pipeline object from the specified Transport and Policies.
// If no transport is provided then the default *http.Client transport will be used.
func NewPipeline(transport Transport, policies ...Policy) Pipeline {
func NewPipeline(transport Transporter, policies ...Policy) Pipeline {
if transport == nil {
transport = defaultHTTPClient
}
// transport policy must always be the last in the slice
policies = append(policies, PolicyFunc(httpHeaderPolicy), PolicyFunc(bodyDownloadPolicy), transportPolicy{trans: transport})
policies = append(policies, policyFunc(httpHeaderPolicy), policyFunc(bodyDownloadPolicy), transportPolicy{trans: transport})
return Pipeline{
policies: policies,
}
Expand Down Expand Up @@ -121,41 +111,6 @@ func NopCloser(rs io.ReadSeeker) ReadSeekCloser {
return nopCloser{rs}
}

// Poller provides operations for checking the state of a long-running operation.
// An LRO can be in either a non-terminal or terminal state. A non-terminal state
// indicates the LRO is still in progress. A terminal state indicates the LRO has
// completed successfully, failed, or was cancelled.
type Poller interface {
// Done returns true if the LRO has reached a terminal state.
Done() bool

// Poll fetches the latest state of the LRO. It returns an HTTP response or error.
// If the LRO has completed successfully, the poller's state is update and the HTTP
// response is returned.
// If the LRO has completed with failure or was cancelled, the poller's state is
// updated and the error is returned.
// If the LRO has not reached a terminal state, the poller's state is updated and
// the latest HTTP response is returned.
// If Poll fails, the poller's state is unmodified and the error is returned.
// Calling Poll on an LRO that has reached a terminal state will return the final
// HTTP response or error.
Poll(context.Context) (*http.Response, error)

// ResumeToken returns a value representing the poller that can be used to resume
// the LRO at a later time. ResumeTokens are unique per service operation.
ResumeToken() (string, error)
}

// Pager provides operations for iterating over paged responses.
type Pager interface {
// NextPage returns true if the pager advanced to the next page.
// Returns false if there are no more pages or an error occurred.
NextPage(context.Context) bool

// Err returns the last error encountered while paging.
Err() error
}

// holds sentinel values used to send nulls
var nullables map[reflect.Type]interface{} = map[reflect.Type]interface{}{}

Expand Down
41 changes: 28 additions & 13 deletions sdk/azcore/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,7 @@
package azcore

import (
"errors"
"net/http"

sdkruntime "github.com/Azure/azure-sdk-for-go/sdk/internal/runtime"
)

var (
// ErrNoMorePolicies is returned from Request.Next() if there are no more policies in the pipeline.
ErrNoMorePolicies = errors.New("no more policies")
)

var (
Expand All @@ -31,9 +23,6 @@ type HTTPResponse interface {
RawResponse() *http.Response
}

// ensure our internal ResponseError type implements HTTPResponse
var _ HTTPResponse = (*sdkruntime.ResponseError)(nil)

// NonRetriableError represents a non-transient error. This works in
// conjunction with the retry policy, indicating that the error condition
// is idempotent, so no retries will be attempted.
Expand All @@ -48,7 +37,33 @@ type NonRetriableError interface {
// in this error type so that callers can access the underlying *http.Response as required.
// DO NOT wrap failed HTTP requests that returned an error and no response with this type.
func NewResponseError(inner error, resp *http.Response) error {
return sdkruntime.NewResponseError(inner, resp)
return &responseError{inner: inner, resp: resp}
}

type responseError struct {
inner error
resp *http.Response
}

// Error implements the error interface for type ResponseError.
func (e *responseError) Error() string {
return e.inner.Error()
}

// Unwrap returns the inner error.
func (e *responseError) Unwrap() error {
return e.inner
}

// RawResponse returns the HTTP response associated with this error.
func (e *responseError) RawResponse() *http.Response {
return e.resp
}

// NonRetriable indicates this error is non-transient.
func (e *responseError) NonRetriable() {
// marker method
}

var _ NonRetriableError = (*sdkruntime.ResponseError)(nil)
var _ HTTPResponse = (*responseError)(nil)
var _ NonRetriableError = (*responseError)(nil)
8 changes: 4 additions & 4 deletions sdk/azcore/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ func ExampleRequest_SetBody() {
}

// false positive by linter
func ExampleLogger_SetClassifications() { //nolint:govet
func ExampleLogSetClassifications() { //nolint:govet
// only log HTTP requests and responses
azcore.SetClassifications(azcore.LogRequest, azcore.LogResponse)
azcore.LogSetClassifications(azcore.LogRequest, azcore.LogResponse)
}

// false positive by linter
func ExampleLogger_SetListener() { //nolint:govet
func ExampleLogSetListener() { //nolint:govet
// a simple logger that writes to stdout
azcore.SetListener(func(cls azcore.LogClassification, msg string) {
azcore.LogSetListener(func(cls azcore.LogClassification, msg string) {
fmt.Printf("%s: %s\n", cls, msg)
})
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/azcore/go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/Azure/azure-sdk-for-go/sdk/azcore

require (
github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.2
github.com/stretchr/testify v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v0.6.0
github.com/stretchr/testify v1.7.0
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b
)

Expand Down
5 changes: 3 additions & 2 deletions sdk/azcore/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.2 h1:E2xwjsWU81O/XuSaxAGa8Jmqz4Vm4NmrpMSO9/XevDg=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.2/go.mod h1:Hl9Vte0DDolj9zqzmfnmY9/zfZbiT5KnvXqVwAvnR8Q=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.6.0 h1:Lozt96x50m14Kb7U9FgYkI44AYXVa4lVhRF6exoLlqE=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.6.0/go.mod h1:Hl9Vte0DDolj9zqzmfnmY9/zfZbiT5KnvXqVwAvnR8Q=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -18,6 +18,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
Expand Down
47 changes: 13 additions & 34 deletions sdk/azcore/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,41 @@
package azcore

import (
"github.com/Azure/azure-sdk-for-go/sdk/internal/logger"
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
)

// LogClassification is used to group entries. Each group can be toggled on or off
type LogClassification logger.LogClassification
// LogClassification is used to group entries. Each group can be toggled on or off.
type LogClassification = log.Classification

const (
// LogRequest entries contain information about HTTP requests.
// This includes information like the URL, query parameters, and headers.
LogRequest LogClassification = "Request"
LogRequest = log.Request
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll get stuttering here: log.LogRequest. How about RequestClassification, etc?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be fixed in a subsequent PR to move logging to its own package (will post shortly).


// LogResponse entries contain information about HTTP responses.
// This includes information like the HTTP status code, headers, and request URL.
LogResponse LogClassification = "Response"
LogResponse = log.Response

// LogRetryPolicy entries contain information specific to the retry policy in use.
LogRetryPolicy LogClassification = "RetryPolicy"
LogRetryPolicy = log.RetryPolicy

// LogLongRunningOperation entries contain information specific to long-running operations.
// This includes information like polling location, operation state and sleep intervals.
LogLongRunningOperation LogClassification = "LongRunningOperation"
LogLongRunningOperation = log.LongRunningOperation
)

// SetClassifications is used to control which classifications are written to
// LogSetClassifications is used to control which classifications are written to
// the log. By default all log classifications are writen.
func SetClassifications(cls ...LogClassification) {
input := make([]logger.LogClassification, 0)
for _, l := range cls {
input = append(input, logger.LogClassification(l))
}
logger.Log().SetClassifications(input...)
}

// Listener is the function signature invoked when writing log entries.
// A Listener is required to perform its own synchronization if it's expected to be called
// from multiple Go routines
type Listener func(LogClassification, string)

// transform to convert the azcore.Listener type into a usable one for internal.logger module
func transform(lst Listener) logger.Listener {
return func(l logger.LogClassification, msg string) {
azcoreL := LogClassification(l)
lst(azcoreL, msg)
}
func LogSetClassifications(cls ...LogClassification) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stuttering

log.SetClassifications(cls...)
}

// SetListener will set the Logger to write to the specified Listener.
func SetListener(lst Listener) {
if lst == nil {
logger.Log().SetListener(nil)
} else {
logger.Log().SetListener(transform(lst))
}
func LogSetListener(lst func(log.Classification, string)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stuttering

log.SetListener(lst)
}

// for testing purposes
func resetClassifications() {
logger.Log().SetClassifications([]logger.LogClassification{}...)
log.TestResetClassifications()
}
44 changes: 22 additions & 22 deletions sdk/azcore/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,47 @@ import (
"net/http"
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/internal/logger"
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
)

func TestLoggingDefault(t *testing.T) {
// ensure logging with nil listener doesn't fail
SetListener(nil)
logger.Log().Write(logger.LogRequest, "this should work just fine")
LogSetListener(nil)
log.Write(log.Request, "this should work just fine")

log := map[LogClassification]string{}
SetListener(func(cls LogClassification, msg string) {
log[cls] = msg
testlog := map[LogClassification]string{}
LogSetListener(func(cls LogClassification, msg string) {
testlog[cls] = msg
})
const req = "this is a request"
logger.Log().Write(logger.LogRequest, req)
log.Write(log.Request, req)
const resp = "this is a response: %d"
logger.Log().Writef(logger.LogResponse, resp, http.StatusOK)
if l := len(log); l != 2 {
log.Writef(log.Response, resp, http.StatusOK)
if l := len(testlog); l != 2 {
t.Fatalf("unexpected log entry count: %d", l)
}
if log[LogRequest] != req {
t.Fatalf("unexpected log request: %s", log[LogRequest])
if testlog[LogRequest] != req {
t.Fatalf("unexpected log request: %s", testlog[LogRequest])
}
if log[LogResponse] != fmt.Sprintf(resp, http.StatusOK) {
t.Fatalf("unexpected log response: %s", log[LogResponse])
if testlog[LogResponse] != fmt.Sprintf(resp, http.StatusOK) {
t.Fatalf("unexpected log response: %s", testlog[LogResponse])
}
}

func TestLoggingClassification(t *testing.T) {
log := map[LogClassification]string{}
SetListener(func(cls LogClassification, msg string) {
log[cls] = msg
testlog := map[LogClassification]string{}
LogSetListener(func(cls LogClassification, msg string) {
testlog[cls] = msg
})
SetClassifications(LogRequest)
LogSetClassifications(LogRequest)
defer resetClassifications()
logger.Log().Write(logger.LogResponse, "this shouldn't be in the log")
if s, ok := log[LogResponse]; ok {
log.Write(log.Response, "this shouldn't be in the log")
if s, ok := testlog[LogResponse]; ok {
t.Fatalf("unexpected log entry %s", s)
}
const req = "this is a request"
logger.Log().Write(logger.LogRequest, req)
if log[LogRequest] != req {
t.Fatalf("unexpected log entry: %s", log[LogRequest])
log.Write(log.Request, req)
if testlog[LogRequest] != req {
t.Fatalf("unexpected log entry: %s", testlog[LogRequest])
}
}
2 changes: 1 addition & 1 deletion sdk/azcore/policy_anonymous_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package azcore

func anonCredAuthPolicyFunc(AuthenticationOptions) Policy {
return PolicyFunc(anonCredPolicyFunc)
return policyFunc(anonCredPolicyFunc)
}

func anonCredPolicyFunc(req *Request) (*Response, error) {
Expand Down
Loading