Bump Godeps
This commit is contained in:
parent
3dd27c3900
commit
be255ad46c
|
@ -15,58 +15,58 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/endpoints",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/ec2query",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/query",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/rest",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/restxml",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/signer/v4",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/iam",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/s3",
|
||||
"Comment": "v0.9.15",
|
||||
"Rev": "7ab6754ddaaa7972ac1c896ddd7f796cc726e79d"
|
||||
"Comment": "v0.9.16-1-g66c840e",
|
||||
"Rev": "66c840e9981dd121a4239fc25e33b6c1c1caa781"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-etcd/etcd",
|
||||
|
@ -93,8 +93,8 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/gocql/gocql",
|
||||
"Comment": "1st_gen_framing-282-g6e86253",
|
||||
"Rev": "6e86253e1c7c91bcdcfe3afd6417d3ddfbe5771c"
|
||||
"Comment": "1st_gen_framing-323-g8041a37",
|
||||
"Rev": "8041a37b40f2ca115d6c2902b279250eb627d7af"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/snappy",
|
||||
|
@ -102,7 +102,7 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/go-github/github",
|
||||
"Rev": "9420d0f48acb838ccf8a7f8dde9eaee19af71132"
|
||||
"Rev": "84fc80440d3bb3a82d297b827308ce11dcf047eb"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/go-querystring/query",
|
||||
|
@ -110,13 +110,17 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/consul/api",
|
||||
"Comment": "v0.5.2-334-gd6af59c",
|
||||
"Rev": "d6af59cdedcc01e71bccf90061decbb724425fe5"
|
||||
"Comment": "v0.5.2-469-g6a350d5",
|
||||
"Rev": "6a350d5d19a41f94e0c99a933410e8545c4e7a51"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/errwrap",
|
||||
"Rev": "7554cd9344cec97297fa6649b055a8c98c2a1e55"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/go-cleanhttp",
|
||||
"Rev": "5df5ddc69534f1a4697289f1dca2193fbb40213f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/go-multierror",
|
||||
"Rev": "d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5"
|
||||
|
@ -147,8 +151,8 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/lib/pq",
|
||||
"Comment": "go1.0-cutoff-60-gffe986a",
|
||||
"Rev": "ffe986aba3e6cfcded8b06615965941408891ef0"
|
||||
"Comment": "go1.0-cutoff-61-g83c4f41",
|
||||
"Rev": "83c4f410d0aed80a0f44bac6a576a7f2435791f3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/cli",
|
||||
|
@ -213,11 +217,11 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context",
|
||||
"Rev": "21c3935a8fc0f954d03e6b8a560c9600ffee38d2"
|
||||
"Rev": "2cba614e8ff920c60240d2677bc019af32ee04e5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2",
|
||||
"Rev": "ef4eca6b097fad7cec79afcc278d213a6de1c960"
|
||||
"Rev": "038cb4adce85ed41e285c2e7cc6221a92bfa44aa"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/asn1-ber.v1",
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
)
|
||||
|
||||
// The default number of retries for a service. The value of -1 indicates that
|
||||
// the service specific retry default will be used.
|
||||
// DefaultRetries is the default number of retries for a service. The value of
|
||||
// -1 indicates that the service specific retry default will be used.
|
||||
const DefaultRetries = -1
|
||||
|
||||
// A Config provides service configuration for service clients. By default,
|
||||
|
|
|
@ -20,7 +20,7 @@ type lener interface {
|
|||
Len() int
|
||||
}
|
||||
|
||||
// BuildContentLength builds the content length of a request based on the body,
|
||||
// BuildContentLengthHandler builds the content length of a request based on the body,
|
||||
// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
|
||||
// to determine request body length and no "Content-Length" was specified it will panic.
|
||||
var BuildContentLengthHandler = request.NamedHandler{"core.BuildContentLengthHandler", func(r *request.Request) {
|
||||
|
|
2
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
2
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// ValidateParameters is a request handler to validate the input parameters.
|
||||
// ValidateParametersHandler is a request handler to validate the input parameters.
|
||||
// Validating parameters only has meaning if done prior to the request being sent.
|
||||
var ValidateParametersHandler = request.NamedHandler{"core.ValidateParametersHandler", func(r *request.Request) {
|
||||
if r.ParamsFilled() {
|
||||
|
|
|
@ -53,8 +53,8 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Create an empty Credential object that can be used as dummy placeholder
|
||||
// credentials for requests that do not need signed.
|
||||
// AnonymousCredentials is an empty Credential object that can be used as
|
||||
// dummy placeholder credentials for requests that do not need signed.
|
||||
//
|
||||
// This Credentials can be used to configure a service to not sign requests
|
||||
// when making service API calls. For example, when accessing public
|
||||
|
|
|
@ -5,4 +5,4 @@ package aws
|
|||
const SDKName = "aws-sdk-go"
|
||||
|
||||
// SDKVersion is the version of this SDK
|
||||
const SDKVersion = "0.9.15"
|
||||
const SDKVersion = "0.9.16"
|
||||
|
|
|
@ -3572,23 +3572,23 @@ func (c *IAM) SimulateCustomPolicyRequest(input *SimulateCustomPolicyInput) (req
|
|||
return
|
||||
}
|
||||
|
||||
// Simulate a set of IAM policies against a list of API actions and AWS resources
|
||||
// to determine the policies' effective permissions. The policies are provided
|
||||
// as a list of strings.
|
||||
// Simulate how a set of IAM policies and optionally a resource-based policy
|
||||
// works with a list of API actions and AWS resources to determine the policies'
|
||||
// effective permissions. The policies are provided as strings.
|
||||
//
|
||||
// The simulation does not perform the API actions, it only checks the authorization
|
||||
// The simulation does not perform the API actions; it only checks the authorization
|
||||
// to determine if the simulated policies allow or deny the actions.
|
||||
//
|
||||
// If you want to simulate existing policies attached to an IAM user, group,
|
||||
// or role, use SimulatePrincipalPolicy instead.
|
||||
//
|
||||
// Context keys are variables maintained by AWS and its services that provide
|
||||
// details about the context of an API query request, and can be evaluated by
|
||||
// using the Condition element of an IAM policy. To get the list of context
|
||||
// keys required by the policies to simulate them correctly, use GetContextKeysForCustomPolicy.
|
||||
// details about the context of an API query request. You can use the Condition
|
||||
// element of an IAM policy to evaluate context keys. To get the list of context
|
||||
// keys that the policies require for correct simulation, use GetContextKeysForCustomPolicy.
|
||||
//
|
||||
// If the output is long, you can paginate the results using the MaxItems and
|
||||
// Marker parameters.
|
||||
// If the output is long, you can use MaxItems and Marker parameters to paginate
|
||||
// the results.
|
||||
func (c *IAM) SimulateCustomPolicy(input *SimulateCustomPolicyInput) (*SimulatePolicyResponse, error) {
|
||||
req, out := c.SimulateCustomPolicyRequest(input)
|
||||
err := req.Send()
|
||||
|
@ -3615,16 +3615,19 @@ func (c *IAM) SimulatePrincipalPolicyRequest(input *SimulatePrincipalPolicyInput
|
|||
return
|
||||
}
|
||||
|
||||
// Simulate the set of IAM policies attached to an IAM entity against a list
|
||||
// of API actions and AWS resources to determine the policies' effective permissions.
|
||||
// The entity can be an IAM user, group, or role. If you specify a user, then
|
||||
// the simulation also includes all of the policies attached to groups that
|
||||
// the user is a member of.
|
||||
// Simulate how a set of IAM policies attached to an IAM entity works with a
|
||||
// list of API actions and AWS resources to determine the policies' effective
|
||||
// permissions. The entity can be an IAM user, group, or role. If you specify
|
||||
// a user, then the simulation also includes all of the policies that are attached
|
||||
// to groups that the user belongs to .
|
||||
//
|
||||
// You can optionally include a list of one or more additional policies specified
|
||||
// as strings to include in the simulation. If you want to simulate only policies
|
||||
// specified as strings, use SimulateCustomPolicy instead.
|
||||
//
|
||||
// You can also optionally include one resource-based policy to be evaluated
|
||||
// with each of the resources included in the simulation.
|
||||
//
|
||||
// The simulation does not perform the API actions, it only checks the authorization
|
||||
// to determine if the simulated policies allow or deny the actions.
|
||||
//
|
||||
|
@ -3633,12 +3636,12 @@ func (c *IAM) SimulatePrincipalPolicyRequest(input *SimulatePrincipalPolicyInput
|
|||
// allowing them to use SimulateCustomPolicy instead.
|
||||
//
|
||||
// Context keys are variables maintained by AWS and its services that provide
|
||||
// details about the context of an API query request, and can be evaluated by
|
||||
// using the Condition element of an IAM policy. To get the list of context
|
||||
// keys required by the policies to simulate them correctly, use GetContextKeysForPrincipalPolicy.
|
||||
// details about the context of an API query request. You can use the Condition
|
||||
// element of an IAM policy to evaluate context keys. To get the list of context
|
||||
// keys that the policies require for correct simulation, use GetContextKeysForPrincipalPolicy.
|
||||
//
|
||||
// If the output is long, you can paginate the results using the MaxItems and
|
||||
// Marker parameters.
|
||||
// If the output is long, you can use the MaxItems and Marker parameters to
|
||||
// paginate the results.
|
||||
func (c *IAM) SimulatePrincipalPolicy(input *SimulatePrincipalPolicyInput) (*SimulatePolicyResponse, error) {
|
||||
req, out := c.SimulatePrincipalPolicyRequest(input)
|
||||
err := req.Send()
|
||||
|
@ -6335,6 +6338,14 @@ type EvaluationResult struct {
|
|||
// The result of the simulation.
|
||||
EvalDecision *string `type:"string" required:"true" enum:"PolicyEvaluationDecisionType"`
|
||||
|
||||
// Additional details about the results of the evaluation decision. When there
|
||||
// are both IAM policies and resource policies, this parameter explains how
|
||||
// each set of policies contributes to the final evaluation decision. When simulating
|
||||
// cross-account access to a resource, both the resource-based policy and the
|
||||
// caller's IAM policy must grant access. See How IAM Roles Differ from Resource-based
|
||||
// Policies
|
||||
EvalDecisionDetails map[string]*string `type:"map"`
|
||||
|
||||
// The ARN of the resource that the indicated API action was tested on.
|
||||
EvalResourceName *string `min:"1" type:"string" required:"true"`
|
||||
|
||||
|
@ -6471,19 +6482,19 @@ type GetAccountAuthorizationDetailsInput struct {
|
|||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
metadataGetAccountAuthorizationDetailsInput `json:"-" xml:"-"`
|
||||
|
@ -6901,19 +6912,19 @@ type GetGroupInput struct {
|
|||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
metadataGetGroupInput `json:"-" xml:"-"`
|
||||
|
@ -7757,19 +7768,19 @@ func (s InstanceProfile) GoString() string {
|
|||
type ListAccessKeysInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the user.
|
||||
|
@ -7829,19 +7840,19 @@ func (s ListAccessKeysOutput) GoString() string {
|
|||
type ListAccountAliasesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
metadataListAccountAliasesInput `json:"-" xml:"-"`
|
||||
|
@ -7902,19 +7913,19 @@ type ListAttachedGroupPoliciesInput struct {
|
|||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. This parameter is optional. If
|
||||
|
@ -7975,19 +7986,19 @@ func (s ListAttachedGroupPoliciesOutput) GoString() string {
|
|||
type ListAttachedRolePoliciesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. This parameter is optional. If
|
||||
|
@ -8051,19 +8062,19 @@ func (s ListAttachedRolePoliciesOutput) GoString() string {
|
|||
type ListAttachedUserPoliciesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. This parameter is optional. If
|
||||
|
@ -8134,19 +8145,19 @@ type ListEntitiesForPolicyInput struct {
|
|||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. This parameter is optional. If
|
||||
|
@ -8223,19 +8234,19 @@ type ListGroupPoliciesInput struct {
|
|||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
metadataListGroupPoliciesInput `json:"-" xml:"-"`
|
||||
|
@ -8292,19 +8303,19 @@ func (s ListGroupPoliciesOutput) GoString() string {
|
|||
type ListGroupsForUserInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the user to list groups for.
|
||||
|
@ -8364,19 +8375,19 @@ func (s ListGroupsForUserOutput) GoString() string {
|
|||
type ListGroupsInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. For example, the prefix /division_abc/subdivision_xyz/
|
||||
|
@ -8440,19 +8451,19 @@ func (s ListGroupsOutput) GoString() string {
|
|||
type ListInstanceProfilesForRoleInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the role to list instance profiles for.
|
||||
|
@ -8512,19 +8523,19 @@ func (s ListInstanceProfilesForRoleOutput) GoString() string {
|
|||
type ListInstanceProfilesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. For example, the prefix /application_abc/component_xyz/
|
||||
|
@ -8588,19 +8599,19 @@ func (s ListInstanceProfilesOutput) GoString() string {
|
|||
type ListMFADevicesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the user whose MFA devices you want to list.
|
||||
|
@ -8700,19 +8711,19 @@ func (s ListOpenIDConnectProvidersOutput) GoString() string {
|
|||
type ListPoliciesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// A flag to filter the results to only the attached policies.
|
||||
|
@ -8789,19 +8800,19 @@ func (s ListPoliciesOutput) GoString() string {
|
|||
type ListPolicyVersionsInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
|
||||
|
@ -8869,19 +8880,19 @@ func (s ListPolicyVersionsOutput) GoString() string {
|
|||
type ListRolePoliciesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the role to list policies for.
|
||||
|
@ -8941,19 +8952,19 @@ func (s ListRolePoliciesOutput) GoString() string {
|
|||
type ListRolesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. For example, the prefix /application_abc/component_xyz/
|
||||
|
@ -9057,19 +9068,19 @@ func (s ListSAMLProvidersOutput) GoString() string {
|
|||
type ListSSHPublicKeysInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the IAM user to list SSH public keys for. If none is specified,
|
||||
|
@ -9131,19 +9142,19 @@ func (s ListSSHPublicKeysOutput) GoString() string {
|
|||
type ListServerCertificatesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. For example: /company/servercerts
|
||||
|
@ -9207,19 +9218,19 @@ func (s ListServerCertificatesOutput) GoString() string {
|
|||
type ListSigningCertificatesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the user.
|
||||
|
@ -9279,19 +9290,19 @@ func (s ListSigningCertificatesOutput) GoString() string {
|
|||
type ListUserPoliciesInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The name of the user to list policies for.
|
||||
|
@ -9351,19 +9362,19 @@ func (s ListUserPoliciesOutput) GoString() string {
|
|||
type ListUsersInput struct {
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// The path prefix for filtering the results. For example: /division_abc/subdivision_xyz/,
|
||||
|
@ -9432,19 +9443,19 @@ type ListVirtualMFADevicesInput struct {
|
|||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
metadataListVirtualMFADevicesInput `json:"-" xml:"-"`
|
||||
|
@ -10693,35 +10704,48 @@ func (s SigningCertificate) GoString() string {
|
|||
|
||||
type SimulateCustomPolicyInput struct {
|
||||
// A list of names of API actions to evaluate in the simulation. Each action
|
||||
// is evaluated for each resource. Each action must include the service identifier,
|
||||
// such as iam:CreateUser.
|
||||
// is evaluated against each resource. Each action must include the service
|
||||
// identifier, such as iam:CreateUser.
|
||||
ActionNames []*string `type:"list" required:"true"`
|
||||
|
||||
// A list of context keys and corresponding values that are used by the simulation.
|
||||
// The ARN of the user that you want to use as the simulated caller of the APIs.
|
||||
// CallerArn is required if you include a ResourcePolicy so that the policy's
|
||||
// Principal element has a value to use in evaluating the policy.
|
||||
//
|
||||
// You can specify only the ARN of an IAM user. You cannot specify the ARN
|
||||
// of an assumed role, federated user, or a service principal.
|
||||
CallerArn *string `min:"1" type:"string"`
|
||||
|
||||
// A list of context keys and corresponding values for the simulation to use.
|
||||
// Whenever a context key is evaluated by a Condition element in one of the
|
||||
// simulated IAM permission policies, the corresponding value is supplied.
|
||||
ContextEntries []*ContextEntry `type:"list"`
|
||||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// A list of policy documents to include in the simulation. Each document is
|
||||
// specified as a string containing the complete, valid JSON text of an IAM
|
||||
// policy.
|
||||
// policy. Do not include any resource-based policies in this parameter. Any
|
||||
// resource-based policy must be submitted with the ResourcePolicy parameter.
|
||||
// The policies cannot be "scope-down" policies, such as you could include in
|
||||
// a call to GetFederationToken (http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetFederationToken.html)
|
||||
// or one of the AssumeRole (http://docs.aws.amazon.com/IAM/latest/APIReference/API_AssumeRole.html)
|
||||
// APIs to restrict what a user can do while using the temporary credentials.
|
||||
PolicyInputList []*string `type:"list" required:"true"`
|
||||
|
||||
// A list of ARNs of AWS resources to include in the simulation. If this parameter
|
||||
|
@ -10729,8 +10753,31 @@ type SimulateCustomPolicyInput struct {
|
|||
// the ActionNames parameter is evaluated for each resource in this list. The
|
||||
// simulation determines the access result (allowed or denied) of each combination
|
||||
// and reports it in the response.
|
||||
//
|
||||
// The simulation does not automatically retrieve policies for the specified
|
||||
// resources. If you want to include a resource policy in the simulation, then
|
||||
// you must include the policy as a string in the ResourcePolicy parameter.
|
||||
//
|
||||
// If you include a ResourcePolicy, then it must be applicable to all of the
|
||||
// resources included in the simulation or you receive an invalid input error.
|
||||
ResourceArns []*string `type:"list"`
|
||||
|
||||
// An AWS account ID that specifies the owner of any simulated resource that
|
||||
// does not identify its owner in the resource ARN, such as an S3 bucket or
|
||||
// object. If ResourceOwner is specified, it is also used as the account owner
|
||||
// of any ResourcePolicy included in the simulation. If the ResourceOwner parameter
|
||||
// is not specified, then the owner of the resources and the resource policy
|
||||
// defaults to the account of the identity provided in CallerArn. This parameter
|
||||
// is required only if you specify a resource-based policy and account that
|
||||
// owns the resource is different from the account that owns the simulated calling
|
||||
// user CallerArn.
|
||||
ResourceOwner *string `min:"1" type:"string"`
|
||||
|
||||
// A resource-based policy to include in the simulation provided as a string.
|
||||
// Each resource in the simulation is treated as if it had this policy attached.
|
||||
// You can include only one resource-based policy in a simulation.
|
||||
ResourcePolicy *string `min:"1" type:"string"`
|
||||
|
||||
metadataSimulateCustomPolicyInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
|
@ -10789,26 +10836,41 @@ type SimulatePrincipalPolicyInput struct {
|
|||
// such as iam:CreateUser.
|
||||
ActionNames []*string `type:"list" required:"true"`
|
||||
|
||||
// A list of context keys and corresponding values that are used by the simulation.
|
||||
// The ARN of the user that you want to specify as the simulated caller of the
|
||||
// APIs. If you do not specify a CallerArn, it defaults to the ARN of the user
|
||||
// that you specify in PolicySourceArn, if you specified a user. If you include
|
||||
// both a PolicySourceArn (for example, arn:aws:iam::123456789012:user/David)
|
||||
// and a CallerArn (for example, arn:aws:iam::123456789012:user/Bob), the result
|
||||
// is that you simulate calling the APIs as Bob, as if Bob had David's policies.
|
||||
//
|
||||
// You can specify only the ARN of an IAM user. You cannot specify the ARN
|
||||
// of an assumed role, federated user, or a service principal.
|
||||
//
|
||||
// CallerArn is required if you include a ResourcePolicy and the PolicySourceArn
|
||||
// is not the ARN for an IAM user. This is required so that the resource-based
|
||||
// policy's Principal element has a value to use in evaluating the policy.
|
||||
CallerArn *string `min:"1" type:"string"`
|
||||
|
||||
// A list of context keys and corresponding values for the simulation to use.
|
||||
// Whenever a context key is evaluated by a Condition element in one of the
|
||||
// simulated IAM permission policies, the corresponding value is supplied.
|
||||
// simulated policies, the corresponding value is supplied.
|
||||
ContextEntries []*ContextEntry `type:"list"`
|
||||
|
||||
// Use this parameter only when paginating results and only after you receive
|
||||
// a response indicating that the results are truncated. Set it to the value
|
||||
// of the Marker element in the response you received to inform the next call
|
||||
// about where to start.
|
||||
// of the Marker element in the response that you received to indicate where
|
||||
// the next call should start.
|
||||
Marker *string `min:"1" type:"string"`
|
||||
|
||||
// Use this only when paginating results to indicate the maximum number of items
|
||||
// you want in the response. If there are additional items beyond the maximum
|
||||
// you specify, the IsTruncated response element is true.
|
||||
// you want in the response. If additional items exist beyond the maximum you
|
||||
// specify, the IsTruncated response element is true.
|
||||
//
|
||||
// This parameter is optional. If you do not include it, it defaults to 100.
|
||||
// Note that IAM might return fewer results, even when there are more results
|
||||
// available. If this is the case, the IsTruncated response element returns
|
||||
// true and Marker contains a value to include in the subsequent call that tells
|
||||
// the service where to continue from.
|
||||
// available. In that case, the IsTruncated response element returns true and
|
||||
// Marker contains a value to include in the subsequent call that tells the
|
||||
// service where to continue from.
|
||||
MaxItems *int64 `min:"1" type:"integer"`
|
||||
|
||||
// An optional list of additional policy documents to include in the simulation.
|
||||
|
@ -10818,9 +10880,9 @@ type SimulatePrincipalPolicyInput struct {
|
|||
|
||||
// The Amazon Resource Name (ARN) of a user, group, or role whose policies you
|
||||
// want to include in the simulation. If you specify a user, group, or role,
|
||||
// the simulation includes all policies associated with that entity. If you
|
||||
// specify a user, the simulation also includes all policies attached to any
|
||||
// groups the user is a member of.
|
||||
// the simulation includes all policies that are associated with that entity.
|
||||
// If you specify a user, the simulation also includes all policies that are
|
||||
// attached to any groups the user belongs to.
|
||||
PolicySourceArn *string `min:"20" type:"string" required:"true"`
|
||||
|
||||
// A list of ARNs of AWS resources to include in the simulation. If this parameter
|
||||
|
@ -10828,8 +10890,28 @@ type SimulatePrincipalPolicyInput struct {
|
|||
// the ActionNames parameter is evaluated for each resource in this list. The
|
||||
// simulation determines the access result (allowed or denied) of each combination
|
||||
// and reports it in the response.
|
||||
//
|
||||
// The simulation does not automatically retrieve policies for the specified
|
||||
// resources. If you want to include a resource policy in the simulation, then
|
||||
// you must include the policy as a string in the ResourcePolicy parameter.
|
||||
ResourceArns []*string `type:"list"`
|
||||
|
||||
// An AWS account ID that specifies the owner of any simulated resource that
|
||||
// does not identify its owner in the resource ARN, such as an S3 bucket or
|
||||
// object. If ResourceOwner is specified, it is also used as the account owner
|
||||
// of any ResourcePolicy included in the simulation. If the ResourceOwner parameter
|
||||
// is not specified, then the owner of the resources and the resource policy
|
||||
// defaults to the account of the identity provided in CallerArn. This parameter
|
||||
// is required only if you specify a resource-based policy and account that
|
||||
// owns the resource is different from the account that owns the simulated calling
|
||||
// user CallerArn.
|
||||
ResourceOwner *string `min:"1" type:"string"`
|
||||
|
||||
// A resource-based policy to include in the simulation provided as a string.
|
||||
// Each resource in the simulation is treated as if it had this policy attached.
|
||||
// You can include only one resource-based policy in a simulation.
|
||||
ResourcePolicy *string `min:"1" type:"string"`
|
||||
|
||||
metadataSimulatePrincipalPolicyInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
|
@ -11831,6 +11913,8 @@ const (
|
|||
// @enum PolicySourceType
|
||||
PolicySourceTypeUserManaged = "user-managed"
|
||||
// @enum PolicySourceType
|
||||
PolicySourceTypeResource = "resource"
|
||||
// @enum PolicySourceType
|
||||
PolicySourceTypeNone = "none"
|
||||
)
|
||||
|
||||
|
|
9
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/s3/s3manager/download.go
generated
vendored
9
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/s3/s3manager/download.go
generated
vendored
|
@ -13,13 +13,16 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/s3/s3iface"
|
||||
)
|
||||
|
||||
// The default range of bytes to get at a time when using Download().
|
||||
// DefaultDownloadPartSize is the default range of bytes to get at a time when
|
||||
// using Download().
|
||||
var DefaultDownloadPartSize int64 = 1024 * 1024 * 5
|
||||
|
||||
// The default number of goroutines to spin up when using Download().
|
||||
// DefaultDownloadConcurrency is the default number of goroutines to spin up
|
||||
// when using Download().
|
||||
var DefaultDownloadConcurrency = 5
|
||||
|
||||
// The default set of options used when opts is nil in Download().
|
||||
// DefaultDownloadOptions is the default set of options used when opts is nil
|
||||
// in Download().
|
||||
var DefaultDownloadOptions = &DownloadOptions{
|
||||
PartSize: DefaultDownloadPartSize,
|
||||
Concurrency: DefaultDownloadConcurrency,
|
||||
|
|
15
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/s3/s3manager/upload.go
generated
vendored
15
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/s3/s3manager/upload.go
generated
vendored
|
@ -14,19 +14,24 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/s3/s3iface"
|
||||
)
|
||||
|
||||
// The maximum allowed number of parts in a multi-part upload on Amazon S3.
|
||||
// MaxUploadParts is the maximum allowed number of parts in a multi-part upload
|
||||
// on Amazon S3.
|
||||
var MaxUploadParts = 10000
|
||||
|
||||
// The minimum allowed part size when uploading a part to Amazon S3.
|
||||
// MinUploadPartSize is the minimum allowed part size when uploading a part to
|
||||
// Amazon S3.
|
||||
var MinUploadPartSize int64 = 1024 * 1024 * 5
|
||||
|
||||
// The default part size to buffer chunks of a payload into.
|
||||
// DefaultUploadPartSize is the default part size to buffer chunks of a
|
||||
// payload into.
|
||||
var DefaultUploadPartSize = MinUploadPartSize
|
||||
|
||||
// The default number of goroutines to spin up when using Upload().
|
||||
// DefaultUploadConcurrency is the default number of goroutines to spin up when
|
||||
// using Upload().
|
||||
var DefaultUploadConcurrency = 5
|
||||
|
||||
// The default set of options used when opts is nil in Upload().
|
||||
// DefaultUploadOptions is the default set of options used when opts is nil in
|
||||
// Upload().
|
||||
var DefaultUploadOptions = &UploadOptions{
|
||||
PartSize: DefaultUploadPartSize,
|
||||
Concurrency: DefaultUploadConcurrency,
|
||||
|
|
|
@ -13,10 +13,14 @@ env:
|
|||
global:
|
||||
- GOMAXPROCS=2
|
||||
matrix:
|
||||
- CASS=2.0.17 AUTH=false
|
||||
- CASS=2.1.9 AUTH=false
|
||||
- CASS=2.1.9 AUTH=true
|
||||
- CASS=2.2.1 AUTH=false
|
||||
- CASS=2.0.17
|
||||
AUTH=false
|
||||
- CASS=2.1.11
|
||||
AUTH=false
|
||||
- CASS=2.1.11
|
||||
AUTH=true
|
||||
- CASS=2.2.3
|
||||
AUTH=false
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
|
@ -35,7 +39,7 @@ install:
|
|||
script:
|
||||
- set -e
|
||||
- go test -v -tags unit
|
||||
- PATH=$PATH:$HOME/.local/bin bash -x integration.sh $CASS $AUTH
|
||||
- PATH=$PATH:$HOME/.local/bin bash integration.sh $CASS $AUTH
|
||||
- go vet .
|
||||
|
||||
notifications:
|
||||
|
|
|
@ -55,3 +55,4 @@ Adrian Casajus <adriancasajus@gmail.com>
|
|||
John Weldon <johnweldon4@gmail.com>
|
||||
Adrien Bustany <adrien@bustany.org>
|
||||
Andrey Smirnov <smirnov.andrey@gmail.com>
|
||||
Adam Weiner <adamsweiner@gmail.com>
|
||||
|
|
|
@ -50,6 +50,33 @@ type DiscoveryConfig struct {
|
|||
Sleep time.Duration
|
||||
}
|
||||
|
||||
// PoolConfig configures the connection pool used by the driver, it defaults to
|
||||
// using a round robbin host selection policy and a round robbin connection selection
|
||||
// policy for each host.
|
||||
type PoolConfig struct {
|
||||
// HostSelectionPolicy sets the policy for selecting which host to use for a
|
||||
// given query (default: RoundRobinHostPolicy())
|
||||
HostSelectionPolicy HostSelectionPolicy
|
||||
|
||||
// ConnSelectionPolicy sets the policy factory for selecting a connection to use for
|
||||
// each host for a query (default: RoundRobinConnPolicy())
|
||||
ConnSelectionPolicy func() ConnSelectionPolicy
|
||||
}
|
||||
|
||||
func (p PoolConfig) buildPool(cfg *ClusterConfig) (*policyConnPool, error) {
|
||||
hostSelection := p.HostSelectionPolicy
|
||||
if hostSelection == nil {
|
||||
hostSelection = RoundRobinHostPolicy()
|
||||
}
|
||||
|
||||
connSelection := p.ConnSelectionPolicy
|
||||
if connSelection == nil {
|
||||
connSelection = RoundRobinConnPolicy()
|
||||
}
|
||||
|
||||
return newPolicyConnPool(cfg, hostSelection, connSelection)
|
||||
}
|
||||
|
||||
// ClusterConfig is a struct to configure the default cluster implementation
|
||||
// of gocoql. It has a varity of attributes that can be used to modify the
|
||||
// behavior to fit the most common use cases. Applications that requre a
|
||||
|
@ -68,7 +95,6 @@ type ClusterConfig struct {
|
|||
Authenticator Authenticator // authenticator (default: nil)
|
||||
RetryPolicy RetryPolicy // Default retry policy to use for queries (default: 0)
|
||||
SocketKeepalive time.Duration // The keepalive period to use, enabled if > 0 (default: 0)
|
||||
ConnPoolType NewPoolFunc // The function used to create the connection pool for the session (default: NewSimplePool)
|
||||
DiscoverHosts bool // If set, gocql will attempt to automatically discover other members of the Cassandra cluster (default: false)
|
||||
MaxPreparedStmts int // Sets the maximum cache size for prepared statements globally for gocql (default: 1000)
|
||||
MaxRoutingKeyInfo int // Sets the maximum cache size for query info about statements for each session (default: 1000)
|
||||
|
@ -77,6 +103,12 @@ type ClusterConfig struct {
|
|||
Discovery DiscoveryConfig
|
||||
SslOpts *SslOptions
|
||||
DefaultTimestamp bool // Sends a client side timestamp for all requests which overrides the timestamp at which it arrives at the server. (default: true, only enabled for protocol 3 and above)
|
||||
// PoolConfig configures the underlying connection pool, allowing the
|
||||
// configuration of host selection and connection selection policies.
|
||||
PoolConfig PoolConfig
|
||||
|
||||
// internal config for testing
|
||||
disableControlConn bool
|
||||
}
|
||||
|
||||
// NewCluster generates a new config for the default cluster implementation.
|
||||
|
@ -89,7 +121,6 @@ func NewCluster(hosts ...string) *ClusterConfig {
|
|||
Port: 9042,
|
||||
NumConns: 2,
|
||||
Consistency: Quorum,
|
||||
ConnPoolType: NewSimplePool,
|
||||
DiscoverHosts: false,
|
||||
MaxPreparedStmts: defaultMaxPreparedStmts,
|
||||
MaxRoutingKeyInfo: 1000,
|
||||
|
|
|
@ -99,6 +99,7 @@ type Conn struct {
|
|||
conn net.Conn
|
||||
r *bufio.Reader
|
||||
timeout time.Duration
|
||||
cfg *ConnConfig
|
||||
|
||||
headerBuf []byte
|
||||
|
||||
|
@ -121,7 +122,7 @@ type Conn struct {
|
|||
|
||||
// Connect establishes a connection to a Cassandra node.
|
||||
// You must also call the Serve method before you can execute any queries.
|
||||
func Connect(addr string, cfg ConnConfig, errorHandler ConnErrorHandler) (*Conn, error) {
|
||||
func Connect(addr string, cfg *ConnConfig, errorHandler ConnErrorHandler) (*Conn, error) {
|
||||
var (
|
||||
err error
|
||||
conn net.Conn
|
||||
|
@ -166,6 +167,7 @@ func Connect(addr string, cfg ConnConfig, errorHandler ConnErrorHandler) (*Conn,
|
|||
c := &Conn{
|
||||
conn: conn,
|
||||
r: bufio.NewReader(conn),
|
||||
cfg: cfg,
|
||||
uniq: make(chan int, cfg.NumStreams),
|
||||
calls: make([]callReq, cfg.NumStreams),
|
||||
timeout: cfg.Timeout,
|
||||
|
@ -191,7 +193,7 @@ func Connect(addr string, cfg ConnConfig, errorHandler ConnErrorHandler) (*Conn,
|
|||
|
||||
go c.serve()
|
||||
|
||||
if err := c.startup(&cfg); err != nil {
|
||||
if err := c.startup(); err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
@ -231,16 +233,21 @@ func (c *Conn) Read(p []byte) (n int, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (c *Conn) startup(cfg *ConnConfig) error {
|
||||
func (c *Conn) startup() error {
|
||||
m := map[string]string{
|
||||
"CQL_VERSION": cfg.CQLVersion,
|
||||
"CQL_VERSION": c.cfg.CQLVersion,
|
||||
}
|
||||
|
||||
if c.compressor != nil {
|
||||
m["COMPRESSION"] = c.compressor.Name()
|
||||
}
|
||||
|
||||
frame, err := c.exec(&writeStartupFrame{opts: m}, nil)
|
||||
framer, err := c.exec(&writeStartupFrame{opts: m}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frame, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -270,7 +277,12 @@ func (c *Conn) authenticateHandshake(authFrame *authenticateFrame) error {
|
|||
req := &writeAuthResponseFrame{data: resp}
|
||||
|
||||
for {
|
||||
frame, err := c.exec(req, nil)
|
||||
framer, err := c.exec(req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frame, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -295,6 +307,8 @@ func (c *Conn) authenticateHandshake(authFrame *authenticateFrame) error {
|
|||
default:
|
||||
return fmt.Errorf("unknown frame response during authentication: %v", v)
|
||||
}
|
||||
|
||||
framerPool.Put(framer)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,6 +399,7 @@ func (c *Conn) recv() error {
|
|||
if err := framer.readFrame(&head); err != nil {
|
||||
return err
|
||||
}
|
||||
defer framerPool.Put(framer)
|
||||
|
||||
frame, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
|
@ -435,7 +450,6 @@ type callReq struct {
|
|||
|
||||
func (c *Conn) releaseStream(stream int) {
|
||||
call := &c.calls[stream]
|
||||
framerPool.Put(call.framer)
|
||||
call.framer = nil
|
||||
|
||||
select {
|
||||
|
@ -450,7 +464,7 @@ func (c *Conn) handleTimeout() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Conn) exec(req frameWriter, tracer Tracer) (frame, error) {
|
||||
func (c *Conn) exec(req frameWriter, tracer Tracer) (*framer, error) {
|
||||
// TODO: move tracer onto conn
|
||||
var stream int
|
||||
select {
|
||||
|
@ -512,19 +526,10 @@ func (c *Conn) exec(req frameWriter, tracer Tracer) (frame, error) {
|
|||
return nil, NewErrProtocol("unexpected protocol version in response: got %d expected %d", v, c.version)
|
||||
}
|
||||
|
||||
frame, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(framer.traceID) > 0 {
|
||||
tracer.Trace(framer.traceID)
|
||||
}
|
||||
|
||||
return frame, nil
|
||||
return framer, nil
|
||||
}
|
||||
|
||||
func (c *Conn) prepareStatement(stmt string, trace Tracer) (*resultPreparedFrame, error) {
|
||||
func (c *Conn) prepareStatement(stmt string, tracer Tracer) (*QueryInfo, error) {
|
||||
stmtsLRU.Lock()
|
||||
if stmtsLRU.lru == nil {
|
||||
initStmtsLRU(defaultMaxPreparedStmts)
|
||||
|
@ -536,7 +541,7 @@ func (c *Conn) prepareStatement(stmt string, trace Tracer) (*resultPreparedFrame
|
|||
stmtsLRU.Unlock()
|
||||
flight := val.(*inflightPrepare)
|
||||
flight.wg.Wait()
|
||||
return flight.info, flight.err
|
||||
return &flight.info, flight.err
|
||||
}
|
||||
|
||||
flight := new(inflightPrepare)
|
||||
|
@ -548,16 +553,36 @@ func (c *Conn) prepareStatement(stmt string, trace Tracer) (*resultPreparedFrame
|
|||
statement: stmt,
|
||||
}
|
||||
|
||||
resp, err := c.exec(prep, trace)
|
||||
framer, err := c.exec(prep, tracer)
|
||||
if err != nil {
|
||||
flight.err = err
|
||||
flight.wg.Done()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch x := resp.(type) {
|
||||
frame, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
flight.err = err
|
||||
flight.wg.Done()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO(zariel): tidy this up, simplify handling of frame parsing so its not duplicated
|
||||
// everytime we need to parse a frame.
|
||||
if len(framer.traceID) > 0 {
|
||||
tracer.Trace(framer.traceID)
|
||||
}
|
||||
|
||||
switch x := frame.(type) {
|
||||
case *resultPreparedFrame:
|
||||
flight.info = x
|
||||
// defensivly copy as we will recycle the underlying buffer after we
|
||||
// return.
|
||||
flight.info.Id = copyBytes(x.preparedID)
|
||||
// the type info's should _not_ have a reference to the framers read buffer,
|
||||
// therefore we can just copy them directly.
|
||||
flight.info.Args = x.reqMeta.columns
|
||||
flight.info.PKeyColumns = x.reqMeta.pkeyColumns
|
||||
flight.info.Rval = x.respMeta.columns
|
||||
case error:
|
||||
flight.err = x
|
||||
default:
|
||||
|
@ -571,7 +596,9 @@ func (c *Conn) prepareStatement(stmt string, trace Tracer) (*resultPreparedFrame
|
|||
stmtsLRU.Unlock()
|
||||
}
|
||||
|
||||
return flight.info, flight.err
|
||||
framerPool.Put(framer)
|
||||
|
||||
return &flight.info, flight.err
|
||||
}
|
||||
|
||||
func (c *Conn) executeQuery(qry *Query) *Iter {
|
||||
|
@ -603,24 +630,19 @@ func (c *Conn) executeQuery(qry *Query) *Iter {
|
|||
if qry.binding == nil {
|
||||
values = qry.values
|
||||
} else {
|
||||
binding := &QueryInfo{
|
||||
Id: info.preparedID,
|
||||
Args: info.reqMeta.columns,
|
||||
Rval: info.respMeta.columns,
|
||||
}
|
||||
|
||||
values, err = qry.binding(binding)
|
||||
values, err = qry.binding(info)
|
||||
if err != nil {
|
||||
return &Iter{err: err}
|
||||
}
|
||||
}
|
||||
|
||||
if len(values) != len(info.reqMeta.columns) {
|
||||
if len(values) != len(info.Args) {
|
||||
return &Iter{err: ErrQueryArgLength}
|
||||
}
|
||||
|
||||
params.values = make([]queryValues, len(values))
|
||||
for i := 0; i < len(values); i++ {
|
||||
val, err := Marshal(info.reqMeta.columns[i].TypeInfo, values[i])
|
||||
val, err := Marshal(info.Args[i].TypeInfo, values[i])
|
||||
if err != nil {
|
||||
return &Iter{err: err}
|
||||
}
|
||||
|
@ -631,7 +653,7 @@ func (c *Conn) executeQuery(qry *Query) *Iter {
|
|||
}
|
||||
|
||||
frame = &writeExecuteFrame{
|
||||
preparedID: info.preparedID,
|
||||
preparedID: info.Id,
|
||||
params: params,
|
||||
}
|
||||
} else {
|
||||
|
@ -641,18 +663,28 @@ func (c *Conn) executeQuery(qry *Query) *Iter {
|
|||
}
|
||||
}
|
||||
|
||||
resp, err := c.exec(frame, qry.trace)
|
||||
framer, err := c.exec(frame, qry.trace)
|
||||
if err != nil {
|
||||
return &Iter{err: err}
|
||||
}
|
||||
|
||||
resp, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
return &Iter{err: err}
|
||||
}
|
||||
|
||||
if len(framer.traceID) > 0 {
|
||||
qry.trace.Trace(framer.traceID)
|
||||
}
|
||||
|
||||
switch x := resp.(type) {
|
||||
case *resultVoidFrame:
|
||||
return &Iter{}
|
||||
return &Iter{framer: framer}
|
||||
case *resultRowsFrame:
|
||||
iter := &Iter{
|
||||
meta: x.meta,
|
||||
rows: x.rows,
|
||||
meta: x.meta,
|
||||
rows: x.rows,
|
||||
framer: framer,
|
||||
}
|
||||
|
||||
if len(x.meta.pagingState) > 0 && !qry.disableAutoPage {
|
||||
|
@ -668,8 +700,8 @@ func (c *Conn) executeQuery(qry *Query) *Iter {
|
|||
}
|
||||
|
||||
return iter
|
||||
case *resultKeyspaceFrame, *resultSchemaChangeFrame, *schemaChangeKeyspace, *schemaChangeTable:
|
||||
return &Iter{}
|
||||
case *resultKeyspaceFrame, *resultSchemaChangeFrame, *schemaChangeKeyspace, *schemaChangeTable, *schemaChangeFunction:
|
||||
return &Iter{framer: framer}
|
||||
case *RequestErrUnprepared:
|
||||
stmtsLRU.Lock()
|
||||
stmtCacheKey := c.addr + c.currentKeyspace + qry.stmt
|
||||
|
@ -679,11 +711,14 @@ func (c *Conn) executeQuery(qry *Query) *Iter {
|
|||
return c.executeQuery(qry)
|
||||
}
|
||||
stmtsLRU.Unlock()
|
||||
return &Iter{err: x}
|
||||
return &Iter{err: x, framer: framer}
|
||||
case error:
|
||||
return &Iter{err: x}
|
||||
return &Iter{err: x, framer: framer}
|
||||
default:
|
||||
return &Iter{err: NewErrProtocol("Unknown type in response to execute query (%T): %s", x, x)}
|
||||
return &Iter{
|
||||
err: NewErrProtocol("Unknown type in response to execute query (%T): %s", x, x),
|
||||
framer: framer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -710,7 +745,12 @@ func (c *Conn) UseKeyspace(keyspace string) error {
|
|||
q := &writeQueryFrame{statement: `USE "` + keyspace + `"`}
|
||||
q.params.consistency = Any
|
||||
|
||||
resp, err := c.exec(q, nil)
|
||||
framer, err := c.exec(q, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -728,9 +768,9 @@ func (c *Conn) UseKeyspace(keyspace string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) executeBatch(batch *Batch) error {
|
||||
func (c *Conn) executeBatch(batch *Batch) (*Iter, error) {
|
||||
if c.version == protoVersion1 {
|
||||
return ErrUnsupported
|
||||
return nil, ErrUnsupported
|
||||
}
|
||||
|
||||
n := len(batch.Entries)
|
||||
|
@ -750,37 +790,32 @@ func (c *Conn) executeBatch(batch *Batch) error {
|
|||
if len(entry.Args) > 0 || entry.binding != nil {
|
||||
info, err := c.prepareStatement(entry.Stmt, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var args []interface{}
|
||||
if entry.binding == nil {
|
||||
args = entry.Args
|
||||
} else {
|
||||
binding := &QueryInfo{
|
||||
Id: info.preparedID,
|
||||
Args: info.reqMeta.columns,
|
||||
Rval: info.respMeta.columns,
|
||||
}
|
||||
args, err = entry.binding(binding)
|
||||
args, err = entry.binding(info)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) != len(info.reqMeta.columns) {
|
||||
return ErrQueryArgLength
|
||||
if len(args) != len(info.Args) {
|
||||
return nil, ErrQueryArgLength
|
||||
}
|
||||
|
||||
b.preparedID = info.preparedID
|
||||
stmts[string(info.preparedID)] = entry.Stmt
|
||||
b.preparedID = info.Id
|
||||
stmts[string(info.Id)] = entry.Stmt
|
||||
|
||||
b.values = make([]queryValues, len(info.reqMeta.columns))
|
||||
b.values = make([]queryValues, len(info.Args))
|
||||
|
||||
for j := 0; j < len(info.reqMeta.columns); j++ {
|
||||
val, err := Marshal(info.reqMeta.columns[j].TypeInfo, args[j])
|
||||
for j := 0; j < len(info.Args); j++ {
|
||||
val, err := Marshal(info.Args[j].TypeInfo, args[j])
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.values[j].value = val
|
||||
|
@ -792,14 +827,20 @@ func (c *Conn) executeBatch(batch *Batch) error {
|
|||
}
|
||||
|
||||
// TODO: should batch support tracing?
|
||||
resp, err := c.exec(req, nil)
|
||||
framer, err := c.exec(req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := framer.parseFrame()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch x := resp.(type) {
|
||||
case *resultVoidFrame:
|
||||
return nil
|
||||
framerPool.Put(framer)
|
||||
return nil, nil
|
||||
case *RequestErrUnprepared:
|
||||
stmt, found := stmts[string(x.StatementId)]
|
||||
if found {
|
||||
|
@ -807,15 +848,28 @@ func (c *Conn) executeBatch(batch *Batch) error {
|
|||
stmtsLRU.lru.Remove(c.addr + c.currentKeyspace + stmt)
|
||||
stmtsLRU.Unlock()
|
||||
}
|
||||
|
||||
framerPool.Put(framer)
|
||||
|
||||
if found {
|
||||
return c.executeBatch(batch)
|
||||
} else {
|
||||
return x
|
||||
return nil, x
|
||||
}
|
||||
case *resultRowsFrame:
|
||||
iter := &Iter{
|
||||
meta: x.meta,
|
||||
rows: x.rows,
|
||||
framer: framer,
|
||||
}
|
||||
|
||||
return iter, nil
|
||||
case error:
|
||||
return x
|
||||
framerPool.Put(framer)
|
||||
return nil, x
|
||||
default:
|
||||
return NewErrProtocol("Unknown type in response to batch statement: %s", x)
|
||||
framerPool.Put(framer)
|
||||
return nil, NewErrProtocol("Unknown type in response to batch statement: %s", x)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -833,7 +887,7 @@ func (c *Conn) setKeepalive(d time.Duration) error {
|
|||
}
|
||||
|
||||
type inflightPrepare struct {
|
||||
info *resultPreparedFrame
|
||||
info QueryInfo
|
||||
err error
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
|
|
@ -17,89 +17,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
/*ConnectionPool represents the interface gocql will use to work with a collection of connections.
|
||||
|
||||
Purpose
|
||||
|
||||
The connection pool in gocql opens and closes connections as well as selects an available connection
|
||||
for gocql to execute a query against. The pool is also responsible for handling connection errors that
|
||||
are caught by the connection experiencing the error.
|
||||
|
||||
A connection pool should make a copy of the variables used from the ClusterConfig provided to the pool
|
||||
upon creation. ClusterConfig is a pointer and can be modified after the creation of the pool. This can
|
||||
lead to issues with variables being modified outside the expectations of the ConnectionPool type.
|
||||
|
||||
Example of Single Connection Pool:
|
||||
|
||||
type SingleConnection struct {
|
||||
conn *Conn
|
||||
cfg *ClusterConfig
|
||||
}
|
||||
|
||||
func NewSingleConnection(cfg *ClusterConfig) ConnectionPool {
|
||||
addr := JoinHostPort(cfg.Hosts[0], cfg.Port)
|
||||
|
||||
connCfg := ConnConfig{
|
||||
ProtoVersion: cfg.ProtoVersion,
|
||||
CQLVersion: cfg.CQLVersion,
|
||||
Timeout: cfg.Timeout,
|
||||
NumStreams: cfg.NumStreams,
|
||||
Compressor: cfg.Compressor,
|
||||
Authenticator: cfg.Authenticator,
|
||||
Keepalive: cfg.SocketKeepalive,
|
||||
}
|
||||
pool := SingleConnection{cfg:cfg}
|
||||
pool.conn = Connect(addr,connCfg,pool)
|
||||
return &pool
|
||||
}
|
||||
|
||||
func (s *SingleConnection) HandleError(conn *Conn, err error, closed bool) {
|
||||
if closed {
|
||||
connCfg := ConnConfig{
|
||||
ProtoVersion: cfg.ProtoVersion,
|
||||
CQLVersion: cfg.CQLVersion,
|
||||
Timeout: cfg.Timeout,
|
||||
NumStreams: cfg.NumStreams,
|
||||
Compressor: cfg.Compressor,
|
||||
Authenticator: cfg.Authenticator,
|
||||
Keepalive: cfg.SocketKeepalive,
|
||||
}
|
||||
s.conn = Connect(conn.Address(),connCfg,s)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SingleConnection) Pick(qry *Query) *Conn {
|
||||
if s.conn.isClosed {
|
||||
return nil
|
||||
}
|
||||
return s.conn
|
||||
}
|
||||
|
||||
func (s *SingleConnection) Size() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (s *SingleConnection) Close() {
|
||||
s.conn.Close()
|
||||
}
|
||||
|
||||
This is a very simple example of a type that exposes the connection pool interface. To assign
|
||||
this type as the connection pool to use you would assign it to the ClusterConfig like so:
|
||||
|
||||
cluster := NewCluster("127.0.0.1")
|
||||
cluster.ConnPoolType = NewSingleConnection
|
||||
...
|
||||
session, err := cluster.CreateSession()
|
||||
|
||||
To see a more complete example of a ConnectionPool implementation please see the SimplePool type.
|
||||
*/
|
||||
type ConnectionPool interface {
|
||||
SetHosts
|
||||
Pick(*Query) *Conn
|
||||
Size() int
|
||||
Close()
|
||||
}
|
||||
|
||||
// interface to implement to receive the host information
|
||||
type SetHosts interface {
|
||||
SetHosts(hosts []HostInfo)
|
||||
|
@ -110,35 +27,6 @@ type SetPartitioner interface {
|
|||
SetPartitioner(partitioner string)
|
||||
}
|
||||
|
||||
//NewPoolFunc is the type used by ClusterConfig to create a pool of a specific type.
|
||||
type NewPoolFunc func(*ClusterConfig) (ConnectionPool, error)
|
||||
|
||||
//SimplePool is the current implementation of the connection pool inside gocql. This
|
||||
//pool is meant to be a simple default used by gocql so users can get up and running
|
||||
//quickly.
|
||||
type SimplePool struct {
|
||||
cfg *ClusterConfig
|
||||
hostPool *RoundRobin
|
||||
connPool map[string]*RoundRobin
|
||||
conns map[*Conn]struct{}
|
||||
keyspace string
|
||||
|
||||
hostMu sync.RWMutex
|
||||
// this is the set of current hosts which the pool will attempt to connect to
|
||||
hosts map[string]*HostInfo
|
||||
|
||||
// protects hostpool, connPoll, conns, quit
|
||||
mu sync.Mutex
|
||||
|
||||
cFillingPool chan int
|
||||
|
||||
quit bool
|
||||
quitWait chan bool
|
||||
quitOnce sync.Once
|
||||
|
||||
tlsConfig *tls.Config
|
||||
}
|
||||
|
||||
func setupTLSConfig(sslOpts *SslOptions) (*tls.Config, error) {
|
||||
// ca cert is optional
|
||||
if sslOpts.CaPath != "" {
|
||||
|
@ -169,313 +57,10 @@ func setupTLSConfig(sslOpts *SslOptions) (*tls.Config, error) {
|
|||
return &sslOpts.Config, nil
|
||||
}
|
||||
|
||||
//NewSimplePool is the function used by gocql to create the simple connection pool.
|
||||
//This is the default if no other pool type is specified.
|
||||
func NewSimplePool(cfg *ClusterConfig) (ConnectionPool, error) {
|
||||
pool := &SimplePool{
|
||||
cfg: cfg,
|
||||
hostPool: NewRoundRobin(),
|
||||
connPool: make(map[string]*RoundRobin),
|
||||
conns: make(map[*Conn]struct{}),
|
||||
quitWait: make(chan bool),
|
||||
cFillingPool: make(chan int, 1),
|
||||
keyspace: cfg.Keyspace,
|
||||
hosts: make(map[string]*HostInfo),
|
||||
}
|
||||
|
||||
for _, host := range cfg.Hosts {
|
||||
// seed hosts have unknown topology
|
||||
// TODO: Handle populating this during SetHosts
|
||||
pool.hosts[host] = &HostInfo{Peer: host}
|
||||
}
|
||||
|
||||
if cfg.SslOpts != nil {
|
||||
config, err := setupTLSConfig(cfg.SslOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool.tlsConfig = config
|
||||
}
|
||||
|
||||
//Walk through connecting to hosts. As soon as one host connects
|
||||
//defer the remaining connections to cluster.fillPool()
|
||||
for i := 0; i < len(cfg.Hosts); i++ {
|
||||
addr := JoinHostPort(cfg.Hosts[i], cfg.Port)
|
||||
|
||||
if pool.connect(addr) == nil {
|
||||
pool.cFillingPool <- 1
|
||||
go pool.fillPool()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func (c *SimplePool) connect(addr string) error {
|
||||
|
||||
cfg := ConnConfig{
|
||||
ProtoVersion: c.cfg.ProtoVersion,
|
||||
CQLVersion: c.cfg.CQLVersion,
|
||||
Timeout: c.cfg.Timeout,
|
||||
NumStreams: c.cfg.NumStreams,
|
||||
Compressor: c.cfg.Compressor,
|
||||
Authenticator: c.cfg.Authenticator,
|
||||
Keepalive: c.cfg.SocketKeepalive,
|
||||
tlsConfig: c.tlsConfig,
|
||||
}
|
||||
|
||||
conn, err := Connect(addr, cfg, c)
|
||||
if err != nil {
|
||||
log.Printf("connect: failed to connect to %q: %v", addr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return c.addConn(conn)
|
||||
}
|
||||
|
||||
func (c *SimplePool) addConn(conn *Conn) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.quit {
|
||||
conn.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
//Set the connection's keyspace if any before adding it to the pool
|
||||
if c.keyspace != "" {
|
||||
if err := conn.UseKeyspace(c.keyspace); err != nil {
|
||||
log.Printf("error setting connection keyspace. %v", err)
|
||||
conn.Close()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
connPool := c.connPool[conn.Address()]
|
||||
if connPool == nil {
|
||||
connPool = NewRoundRobin()
|
||||
c.connPool[conn.Address()] = connPool
|
||||
c.hostPool.AddNode(connPool)
|
||||
}
|
||||
|
||||
connPool.AddNode(conn)
|
||||
c.conns[conn] = struct{}{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//fillPool manages the pool of connections making sure that each host has the correct
|
||||
//amount of connections defined. Also the method will test a host with one connection
|
||||
//instead of flooding the host with number of connections defined in the cluster config
|
||||
func (c *SimplePool) fillPool() {
|
||||
//Debounce large amounts of requests to fill pool
|
||||
select {
|
||||
case <-time.After(1 * time.Millisecond):
|
||||
return
|
||||
case <-c.cFillingPool:
|
||||
defer func() { c.cFillingPool <- 1 }()
|
||||
}
|
||||
|
||||
c.mu.Lock()
|
||||
isClosed := c.quit
|
||||
c.mu.Unlock()
|
||||
//Exit if cluster(session) is closed
|
||||
if isClosed {
|
||||
return
|
||||
}
|
||||
|
||||
c.hostMu.RLock()
|
||||
|
||||
//Walk through list of defined hosts
|
||||
var wg sync.WaitGroup
|
||||
for host := range c.hosts {
|
||||
addr := JoinHostPort(host, c.cfg.Port)
|
||||
|
||||
numConns := 1
|
||||
//See if the host already has connections in the pool
|
||||
c.mu.Lock()
|
||||
conns, ok := c.connPool[addr]
|
||||
c.mu.Unlock()
|
||||
|
||||
if ok {
|
||||
//if the host has enough connections just exit
|
||||
numConns = conns.Size()
|
||||
if numConns >= c.cfg.NumConns {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
//See if the host is reachable
|
||||
if err := c.connect(addr); err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
//This is reached if the host is responsive and needs more connections
|
||||
//Create connections for host synchronously to mitigate flooding the host.
|
||||
wg.Add(1)
|
||||
go func(a string, conns int) {
|
||||
defer wg.Done()
|
||||
for ; conns < c.cfg.NumConns; conns++ {
|
||||
c.connect(a)
|
||||
}
|
||||
}(addr, numConns)
|
||||
}
|
||||
|
||||
c.hostMu.RUnlock()
|
||||
|
||||
//Wait until we're finished connecting to each host before returning
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// Should only be called if c.mu is locked
|
||||
func (c *SimplePool) removeConnLocked(conn *Conn) {
|
||||
conn.Close()
|
||||
connPool := c.connPool[conn.addr]
|
||||
if connPool == nil {
|
||||
return
|
||||
}
|
||||
connPool.RemoveNode(conn)
|
||||
if connPool.Size() == 0 {
|
||||
c.hostPool.RemoveNode(connPool)
|
||||
delete(c.connPool, conn.addr)
|
||||
}
|
||||
delete(c.conns, conn)
|
||||
}
|
||||
|
||||
func (c *SimplePool) removeConn(conn *Conn) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.removeConnLocked(conn)
|
||||
}
|
||||
|
||||
//HandleError is called by a Connection object to report to the pool an error has occured.
|
||||
//Logic is then executed within the pool to clean up the erroroneous connection and try to
|
||||
//top off the pool.
|
||||
func (c *SimplePool) HandleError(conn *Conn, err error, closed bool) {
|
||||
if !closed {
|
||||
// ignore all non-fatal errors
|
||||
return
|
||||
}
|
||||
c.removeConn(conn)
|
||||
c.mu.Lock()
|
||||
poolClosed := c.quit
|
||||
c.mu.Unlock()
|
||||
if !poolClosed {
|
||||
go c.fillPool() // top off pool.
|
||||
}
|
||||
}
|
||||
|
||||
//Pick selects a connection to be used by the query.
|
||||
func (c *SimplePool) Pick(qry *Query) *Conn {
|
||||
//Check if connections are available
|
||||
c.mu.Lock()
|
||||
conns := len(c.conns)
|
||||
c.mu.Unlock()
|
||||
|
||||
if conns == 0 {
|
||||
//try to populate the pool before returning.
|
||||
c.fillPool()
|
||||
}
|
||||
|
||||
return c.hostPool.Pick(qry)
|
||||
}
|
||||
|
||||
//Size returns the number of connections currently active in the pool
|
||||
func (p *SimplePool) Size() int {
|
||||
p.mu.Lock()
|
||||
conns := len(p.conns)
|
||||
p.mu.Unlock()
|
||||
return conns
|
||||
}
|
||||
|
||||
//Close kills the pool and all associated connections.
|
||||
func (c *SimplePool) Close() {
|
||||
c.quitOnce.Do(func() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.quit = true
|
||||
close(c.quitWait)
|
||||
for conn := range c.conns {
|
||||
c.removeConnLocked(conn)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (c *SimplePool) SetHosts(hosts []HostInfo) {
|
||||
|
||||
c.hostMu.Lock()
|
||||
toRemove := make(map[string]struct{})
|
||||
for k := range c.hosts {
|
||||
toRemove[k] = struct{}{}
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
host := host
|
||||
delete(toRemove, host.Peer)
|
||||
// we already have it
|
||||
if _, ok := c.hosts[host.Peer]; ok {
|
||||
// TODO: Check rack, dc, token range is consistent, trigger topology change
|
||||
// update stored host
|
||||
continue
|
||||
}
|
||||
|
||||
c.hosts[host.Peer] = &host
|
||||
}
|
||||
|
||||
// can we hold c.mu whilst iterating this loop?
|
||||
for addr := range toRemove {
|
||||
c.removeHostLocked(addr)
|
||||
}
|
||||
c.hostMu.Unlock()
|
||||
|
||||
c.fillPool()
|
||||
}
|
||||
|
||||
func (c *SimplePool) removeHostLocked(addr string) {
|
||||
if _, ok := c.hosts[addr]; !ok {
|
||||
return
|
||||
}
|
||||
delete(c.hosts, addr)
|
||||
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if _, ok := c.connPool[addr]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
for conn := range c.conns {
|
||||
if conn.Address() == addr {
|
||||
c.removeConnLocked(conn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//NewRoundRobinConnPool creates a connection pool which selects hosts by
|
||||
//round-robin, and then selects a connection for that host by round-robin.
|
||||
func NewRoundRobinConnPool(cfg *ClusterConfig) (ConnectionPool, error) {
|
||||
return NewPolicyConnPool(
|
||||
cfg,
|
||||
NewRoundRobinHostPolicy(),
|
||||
NewRoundRobinConnPolicy,
|
||||
)
|
||||
}
|
||||
|
||||
//NewTokenAwareConnPool creates a connection pool which selects hosts by
|
||||
//a token aware policy, and then selects a connection for that host by
|
||||
//round-robin.
|
||||
func NewTokenAwareConnPool(cfg *ClusterConfig) (ConnectionPool, error) {
|
||||
return NewPolicyConnPool(
|
||||
cfg,
|
||||
NewTokenAwareHostPolicy(NewRoundRobinHostPolicy()),
|
||||
NewRoundRobinConnPolicy,
|
||||
)
|
||||
}
|
||||
|
||||
type policyConnPool struct {
|
||||
port int
|
||||
numConns int
|
||||
connCfg ConnConfig
|
||||
connCfg *ConnConfig
|
||||
keyspace string
|
||||
|
||||
mu sync.RWMutex
|
||||
|
@ -484,18 +69,13 @@ type policyConnPool struct {
|
|||
hostConnPools map[string]*hostConnPool
|
||||
}
|
||||
|
||||
//Creates a policy based connection pool. This func isn't meant to be directly
|
||||
//used as a NewPoolFunc in ClusterConfig, instead a func should be created
|
||||
//which satisfies the NewPoolFunc type, which calls this func with the desired
|
||||
//hostPolicy and connPolicy; see NewRoundRobinConnPool or NewTokenAwareConnPool
|
||||
//for examples.
|
||||
func NewPolicyConnPool(
|
||||
cfg *ClusterConfig,
|
||||
hostPolicy HostSelectionPolicy,
|
||||
connPolicy func() ConnSelectionPolicy,
|
||||
) (ConnectionPool, error) {
|
||||
var err error
|
||||
var tlsConfig *tls.Config
|
||||
func newPolicyConnPool(cfg *ClusterConfig, hostPolicy HostSelectionPolicy,
|
||||
connPolicy func() ConnSelectionPolicy) (*policyConnPool, error) {
|
||||
|
||||
var (
|
||||
err error
|
||||
tlsConfig *tls.Config
|
||||
)
|
||||
|
||||
if cfg.SslOpts != nil {
|
||||
tlsConfig, err = setupTLSConfig(cfg.SslOpts)
|
||||
|
@ -508,7 +88,7 @@ func NewPolicyConnPool(
|
|||
pool := &policyConnPool{
|
||||
port: cfg.Port,
|
||||
numConns: cfg.NumConns,
|
||||
connCfg: ConnConfig{
|
||||
connCfg: &ConnConfig{
|
||||
ProtoVersion: cfg.ProtoVersion,
|
||||
CQLVersion: cfg.CQLVersion,
|
||||
Timeout: cfg.Timeout,
|
||||
|
@ -594,9 +174,12 @@ func (p *policyConnPool) Size() int {
|
|||
func (p *policyConnPool) Pick(qry *Query) *Conn {
|
||||
nextHost := p.hostPolicy.Pick(qry)
|
||||
|
||||
var (
|
||||
host *HostInfo
|
||||
conn *Conn
|
||||
)
|
||||
|
||||
p.mu.RLock()
|
||||
var host *HostInfo
|
||||
var conn *Conn
|
||||
for conn == nil {
|
||||
host = nextHost()
|
||||
if host == nil {
|
||||
|
@ -629,7 +212,7 @@ type hostConnPool struct {
|
|||
port int
|
||||
addr string
|
||||
size int
|
||||
connCfg ConnConfig
|
||||
connCfg *ConnConfig
|
||||
keyspace string
|
||||
policy ConnSelectionPolicy
|
||||
// protection for conns, closed, filling
|
||||
|
@ -639,14 +222,8 @@ type hostConnPool struct {
|
|||
filling bool
|
||||
}
|
||||
|
||||
func newHostConnPool(
|
||||
host string,
|
||||
port int,
|
||||
size int,
|
||||
connCfg ConnConfig,
|
||||
keyspace string,
|
||||
policy ConnSelectionPolicy,
|
||||
) *hostConnPool {
|
||||
func newHostConnPool(host string, port int, size int, connCfg *ConnConfig,
|
||||
keyspace string, policy ConnSelectionPolicy) *hostConnPool {
|
||||
|
||||
pool := &hostConnPool{
|
||||
host: host,
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
package gocql
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type controlConn struct {
|
||||
session *Session
|
||||
|
||||
conn atomic.Value
|
||||
connecting uint64
|
||||
|
||||
retry RetryPolicy
|
||||
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
func createControlConn(session *Session) *controlConn {
|
||||
control := &controlConn{
|
||||
session: session,
|
||||
quit: make(chan struct{}),
|
||||
retry: &SimpleRetryPolicy{NumRetries: 3},
|
||||
}
|
||||
|
||||
control.conn.Store((*Conn)(nil))
|
||||
control.reconnect()
|
||||
go control.heartBeat()
|
||||
|
||||
return control
|
||||
}
|
||||
|
||||
func (c *controlConn) heartBeat() {
|
||||
for {
|
||||
select {
|
||||
case <-c.quit:
|
||||
return
|
||||
case <-time.After(5 * time.Second):
|
||||
}
|
||||
|
||||
resp, err := c.writeFrame(&writeOptionsFrame{})
|
||||
if err != nil {
|
||||
goto reconn
|
||||
}
|
||||
|
||||
switch resp.(type) {
|
||||
case *supportedFrame:
|
||||
continue
|
||||
case error:
|
||||
goto reconn
|
||||
default:
|
||||
panic(fmt.Sprintf("gocql: unknown frame in response to options: %T", resp))
|
||||
}
|
||||
|
||||
reconn:
|
||||
c.reconnect()
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controlConn) reconnect() {
|
||||
if !atomic.CompareAndSwapUint64(&c.connecting, 0, 1) {
|
||||
return
|
||||
}
|
||||
|
||||
success := false
|
||||
defer func() {
|
||||
// debounce reconnect a little
|
||||
if success {
|
||||
go func() {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
atomic.StoreUint64(&c.connecting, 0)
|
||||
}()
|
||||
} else {
|
||||
atomic.StoreUint64(&c.connecting, 0)
|
||||
}
|
||||
}()
|
||||
|
||||
oldConn := c.conn.Load().(*Conn)
|
||||
|
||||
// TODO: should have our own roundrobbin for hosts so that we can try each
|
||||
// in succession and guantee that we get a different host each time.
|
||||
conn := c.session.pool.Pick(nil)
|
||||
if conn == nil {
|
||||
return
|
||||
}
|
||||
|
||||
newConn, err := Connect(conn.addr, conn.cfg, c)
|
||||
if err != nil {
|
||||
// TODO: add log handler for things like this
|
||||
return
|
||||
}
|
||||
|
||||
c.conn.Store(newConn)
|
||||
success = true
|
||||
|
||||
if oldConn != nil {
|
||||
oldConn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controlConn) HandleError(conn *Conn, err error, closed bool) {
|
||||
if !closed {
|
||||
return
|
||||
}
|
||||
|
||||
oldConn := c.conn.Load().(*Conn)
|
||||
if oldConn != conn {
|
||||
return
|
||||
}
|
||||
|
||||
c.reconnect()
|
||||
}
|
||||
|
||||
func (c *controlConn) writeFrame(w frameWriter) (frame, error) {
|
||||
conn := c.conn.Load().(*Conn)
|
||||
if conn == nil {
|
||||
return nil, errNoControl
|
||||
}
|
||||
|
||||
framer, err := conn.exec(w, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return framer.parseFrame()
|
||||
}
|
||||
|
||||
// query will return nil if the connection is closed or nil
|
||||
func (c *controlConn) query(statement string, values ...interface{}) (iter *Iter) {
|
||||
q := c.session.Query(statement, values...).Consistency(One)
|
||||
|
||||
const maxConnectAttempts = 5
|
||||
connectAttempts := 0
|
||||
|
||||
for {
|
||||
conn := c.conn.Load().(*Conn)
|
||||
if conn == nil {
|
||||
if connectAttempts > maxConnectAttempts {
|
||||
return &Iter{err: errNoControl}
|
||||
}
|
||||
|
||||
connectAttempts++
|
||||
|
||||
c.reconnect()
|
||||
continue
|
||||
}
|
||||
|
||||
iter = conn.executeQuery(q)
|
||||
q.attempts++
|
||||
if iter.err == nil || !c.retry.Attempt(q) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *controlConn) awaitSchemaAgreement() (err error) {
|
||||
|
||||
const (
|
||||
// TODO(zariel): if we export this make this configurable
|
||||
maxWaitTime = 60 * time.Second
|
||||
|
||||
peerSchemas = "SELECT schema_version FROM system.peers"
|
||||
localSchemas = "SELECT schema_version FROM system.local WHERE key='local'"
|
||||
)
|
||||
|
||||
endDeadline := time.Now().Add(maxWaitTime)
|
||||
|
||||
for time.Now().Before(endDeadline) {
|
||||
iter := c.query(peerSchemas)
|
||||
|
||||
versions := make(map[string]struct{})
|
||||
|
||||
var schemaVersion string
|
||||
for iter.Scan(&schemaVersion) {
|
||||
versions[schemaVersion] = struct{}{}
|
||||
schemaVersion = ""
|
||||
}
|
||||
|
||||
if err = iter.Close(); err != nil {
|
||||
goto cont
|
||||
}
|
||||
|
||||
iter = c.query(localSchemas)
|
||||
for iter.Scan(&schemaVersion) {
|
||||
versions[schemaVersion] = struct{}{}
|
||||
schemaVersion = ""
|
||||
}
|
||||
|
||||
if err = iter.Close(); err != nil {
|
||||
goto cont
|
||||
}
|
||||
|
||||
if len(versions) <= 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cont:
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// not exported
|
||||
return errors.New("gocql: cluster schema versions not consistent")
|
||||
}
|
||||
func (c *controlConn) close() {
|
||||
// TODO: handle more gracefully
|
||||
close(c.quit)
|
||||
}
|
||||
|
||||
var errNoControl = errors.New("gocql: no controll connection available")
|
|
@ -12,6 +12,7 @@ import (
|
|||
"log"
|
||||
"net"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
@ -179,6 +180,31 @@ func (c Consistency) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
func ParseConsistency(s string) Consistency {
|
||||
switch strings.ToUpper(s) {
|
||||
case "ANY":
|
||||
return Any
|
||||
case "ONE":
|
||||
return One
|
||||
case "TWO":
|
||||
return Two
|
||||
case "THREE":
|
||||
return Three
|
||||
case "QUORUM":
|
||||
return Quorum
|
||||
case "ALL":
|
||||
return All
|
||||
case "LOCAL_QUORUM":
|
||||
return LocalQuorum
|
||||
case "EACH_QUORUM":
|
||||
return EachQuorum
|
||||
case "LOCAL_ONE":
|
||||
return LocalOne
|
||||
default:
|
||||
panic("invalid consistency: " + s)
|
||||
}
|
||||
}
|
||||
|
||||
type SerialConsistency uint16
|
||||
|
||||
const (
|
||||
|
@ -500,7 +526,7 @@ func (f *framer) parseErrorFrame() frame {
|
|||
stmtId := f.readShortBytes()
|
||||
return &RequestErrUnprepared{
|
||||
errorFrame: errD,
|
||||
StatementId: stmtId,
|
||||
StatementId: copyBytes(stmtId), // defensivly copy
|
||||
}
|
||||
case errReadFailure:
|
||||
res := &RequestErrReadFailure{
|
||||
|
@ -1371,6 +1397,17 @@ func (f *framer) writeBatchFrame(streamID int, w *writeBatchFrame) error {
|
|||
return f.finishWrite()
|
||||
}
|
||||
|
||||
type writeOptionsFrame struct{}
|
||||
|
||||
func (w *writeOptionsFrame) writeFrame(framer *framer, streamID int) error {
|
||||
return framer.writeOptionsFrame(streamID, w)
|
||||
}
|
||||
|
||||
func (f *framer) writeOptionsFrame(stream int, _ *writeOptionsFrame) error {
|
||||
f.writeHeader(f.flags, opOptions, stream)
|
||||
return f.finishWrite()
|
||||
}
|
||||
|
||||
func (f *framer) readByte() byte {
|
||||
if len(f.rbuf) < 1 {
|
||||
panic(fmt.Errorf("not enough bytes in buffer to read byte require 1 got: %d", len(f.rbuf)))
|
||||
|
@ -1466,13 +1503,7 @@ func (f *framer) readBytes() []byte {
|
|||
panic(fmt.Errorf("not enough bytes in buffer to read bytes require %d got: %d", size, len(f.rbuf)))
|
||||
}
|
||||
|
||||
// we cant make assumptions about the length of the life of the supplied byte
|
||||
// slice so we defensivly copy it out of the underlying buffer. This has the
|
||||
// downside of increasing allocs per read but will provide much greater memory
|
||||
// safety. The allocs can hopefully be improved in the future.
|
||||
// TODO: dont copy into a new slice
|
||||
l := make([]byte, size)
|
||||
copy(l, f.rbuf[:size])
|
||||
l := f.rbuf[:size]
|
||||
f.rbuf = f.rbuf[size:]
|
||||
|
||||
return l
|
||||
|
@ -1484,8 +1515,7 @@ func (f *framer) readShortBytes() []byte {
|
|||
panic(fmt.Errorf("not enough bytes in buffer to read short bytes: require %d got %d", size, len(f.rbuf)))
|
||||
}
|
||||
|
||||
l := make([]byte, size)
|
||||
copy(l, f.rbuf[:size])
|
||||
l := f.rbuf[:size]
|
||||
f.rbuf = f.rbuf[size:]
|
||||
|
||||
return l
|
||||
|
|
|
@ -180,3 +180,9 @@ func (iter *Iter) MapScan(m map[string]interface{}) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func copyBytes(p []byte) []byte {
|
||||
b := make([]byte, len(p))
|
||||
copy(b, p)
|
||||
return b
|
||||
}
|
||||
|
|
|
@ -24,20 +24,19 @@ type ringDescriber struct {
|
|||
closeChan chan bool
|
||||
}
|
||||
|
||||
func (r *ringDescriber) GetHosts() (
|
||||
hosts []HostInfo,
|
||||
partitioner string,
|
||||
err error,
|
||||
) {
|
||||
func (r *ringDescriber) GetHosts() (hosts []HostInfo, partitioner string, err error) {
|
||||
// we need conn to be the same because we need to query system.peers and system.local
|
||||
// on the same node to get the whole cluster
|
||||
conn := r.session.Pool.Pick(nil)
|
||||
if conn == nil {
|
||||
|
||||
iter := r.session.control.query("SELECT data_center, rack, host_id, tokens, partitioner FROM system.local")
|
||||
if iter == nil {
|
||||
return r.prevHosts, r.prevPartitioner, nil
|
||||
}
|
||||
|
||||
query := r.session.Query("SELECT data_center, rack, host_id, tokens, partitioner FROM system.local")
|
||||
iter := conn.executeQuery(query)
|
||||
conn := r.session.pool.Pick(nil)
|
||||
if conn == nil {
|
||||
return r.prevHosts, r.prevPartitioner, nil
|
||||
}
|
||||
|
||||
host := HostInfo{}
|
||||
iter.Scan(&host.DataCenter, &host.Rack, &host.HostId, &host.Tokens, &partitioner)
|
||||
|
@ -57,8 +56,10 @@ func (r *ringDescriber) GetHosts() (
|
|||
|
||||
hosts = []HostInfo{host}
|
||||
|
||||
query = r.session.Query("SELECT peer, data_center, rack, host_id, tokens FROM system.peers")
|
||||
iter = conn.executeQuery(query)
|
||||
iter = r.session.control.query("SELECT peer, data_center, rack, host_id, tokens FROM system.peers")
|
||||
if iter == nil {
|
||||
return r.prevHosts, r.prevPartitioner, nil
|
||||
}
|
||||
|
||||
host = HostInfo{}
|
||||
for iter.Scan(&host.Peer, &host.DataCenter, &host.Rack, &host.HostId, &host.Tokens) {
|
||||
|
@ -97,21 +98,21 @@ func (h *ringDescriber) run(sleep time.Duration) {
|
|||
}
|
||||
|
||||
for {
|
||||
// if we have 0 hosts this will return the previous list of hosts to
|
||||
// attempt to reconnect to the cluster otherwise we would never find
|
||||
// downed hosts again, could possibly have an optimisation to only
|
||||
// try to add new hosts if GetHosts didnt error and the hosts didnt change.
|
||||
hosts, partitioner, err := h.GetHosts()
|
||||
if err != nil {
|
||||
log.Println("RingDescriber: unable to get ring topology:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
h.session.pool.SetHosts(hosts)
|
||||
h.session.pool.SetPartitioner(partitioner)
|
||||
|
||||
select {
|
||||
case <-time.After(sleep):
|
||||
// if we have 0 hosts this will return the previous list of hosts to
|
||||
// attempt to reconnect to the cluster otherwise we would never find
|
||||
// downed hosts again, could possibly have an optimisation to only
|
||||
// try to add new hosts if GetHosts didnt error and the hosts didnt change.
|
||||
hosts, partitioner, err := h.GetHosts()
|
||||
if err != nil {
|
||||
log.Println("RingDescriber: unable to get ring topology:", err)
|
||||
} else {
|
||||
h.session.Pool.SetHosts(hosts)
|
||||
if v, ok := h.session.Pool.(SetPartitioner); ok {
|
||||
v.SetPartitioner(partitioner)
|
||||
}
|
||||
}
|
||||
case <-h.closeChan:
|
||||
return
|
||||
}
|
||||
|
|
|
@ -40,10 +40,6 @@ function run_tests() {
|
|||
rm -rf $HOME/.ccm/test/node1/data/system_auth
|
||||
fi
|
||||
|
||||
ccm start -v
|
||||
ccm status
|
||||
ccm node1 nodetool status
|
||||
|
||||
local proto=2
|
||||
if [[ $version == 1.2.* ]]; then
|
||||
proto=1
|
||||
|
@ -53,15 +49,20 @@ function run_tests() {
|
|||
proto=3
|
||||
elif [[ $version == 2.2.* ]]; then
|
||||
proto=4
|
||||
ccm updateconf 'enable_user_defined_functions: true'
|
||||
fi
|
||||
|
||||
ccm start -v
|
||||
ccm status
|
||||
ccm node1 nodetool status
|
||||
|
||||
if [ "$auth" = true ]
|
||||
then
|
||||
sleep 30s
|
||||
go test -v . -timeout 15s -run=TestAuthentication -tags integration -runssl -runauth -proto=$proto -cluster=$(ccm liveset) -clusterSize=$clusterSize -autowait=1000ms
|
||||
else
|
||||
|
||||
go test -timeout 5m -tags integration -cover -v -runssl -proto=$proto -rf=3 -cluster=$(ccm liveset) -clusterSize=$clusterSize -autowait=2000ms -compressor=snappy ./... | tee results.txt
|
||||
go test -timeout 5m -tags integration -v -gocql.timeout=10s -runssl -proto=$proto -rf=3 -cluster=$(ccm liveset) -clusterSize=$clusterSize -autowait=2000ms -compressor=snappy ./...
|
||||
|
||||
if [ ${PIPESTATUS[0]} -ne 0 ]; then
|
||||
echo "--- FAIL: ccm status follows:"
|
||||
|
@ -72,13 +73,6 @@ function run_tests() {
|
|||
echo "--- FAIL: Received a non-zero exit code from the go test execution, please investigate this"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cover=`cat results.txt | grep coverage: | grep -o "[0-9]\{1,3\}" | head -n 1`
|
||||
|
||||
if [[ $cover -lt "55" ]]; then
|
||||
echo "--- FAIL: expected coverage of at least 60 %, but coverage was $cover %"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
ccm remove
|
||||
|
|
|
@ -1356,7 +1356,16 @@ func marshalUDT(info TypeInfo, value interface{}) ([]byte, error) {
|
|||
if !f.IsValid() {
|
||||
return nil, marshalErrorf("cannot marshal %T into %s", value, info)
|
||||
} else if f.Kind() == reflect.Ptr {
|
||||
f = f.Elem()
|
||||
if f.IsNil() {
|
||||
n := -1
|
||||
buf = append(buf, byte(n>>24),
|
||||
byte(n>>16),
|
||||
byte(n>>8),
|
||||
byte(n))
|
||||
continue
|
||||
} else {
|
||||
f = f.Elem()
|
||||
}
|
||||
}
|
||||
|
||||
data, err := Marshal(e.Type, f.Interface())
|
||||
|
|
|
@ -335,30 +335,18 @@ func componentColumnCountOfType(columns map[string]*ColumnMetadata, kind string)
|
|||
}
|
||||
|
||||
// query only for the keyspace metadata for the specified keyspace from system.schema_keyspace
|
||||
func getKeyspaceMetadata(
|
||||
session *Session,
|
||||
keyspaceName string,
|
||||
) (*KeyspaceMetadata, error) {
|
||||
query := session.Query(
|
||||
`
|
||||
func getKeyspaceMetadata(session *Session, keyspaceName string) (*KeyspaceMetadata, error) {
|
||||
const stmt = `
|
||||
SELECT durable_writes, strategy_class, strategy_options
|
||||
FROM system.schema_keyspaces
|
||||
WHERE keyspace_name = ?
|
||||
`,
|
||||
keyspaceName,
|
||||
)
|
||||
// Set a routing key to avoid GetRoutingKey from computing the routing key
|
||||
// TODO use a separate connection (pool) for system keyspace queries.
|
||||
query.RoutingKey([]byte{})
|
||||
WHERE keyspace_name = ?`
|
||||
|
||||
keyspace := &KeyspaceMetadata{Name: keyspaceName}
|
||||
var strategyOptionsJSON []byte
|
||||
|
||||
err := query.Scan(
|
||||
&keyspace.DurableWrites,
|
||||
&keyspace.StrategyClass,
|
||||
&strategyOptionsJSON,
|
||||
)
|
||||
iter := session.control.query(stmt, keyspaceName)
|
||||
iter.Scan(&keyspace.DurableWrites, &keyspace.StrategyClass, &strategyOptionsJSON)
|
||||
err := iter.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error querying keyspace schema: %v", err)
|
||||
}
|
||||
|
@ -431,11 +419,7 @@ func getTableMetadata(session *Session, keyspaceName string) ([]TableMetadata, e
|
|||
}
|
||||
}
|
||||
|
||||
// Set a routing key to avoid GetRoutingKey from computing the routing key
|
||||
// TODO use a separate connection (pool) for system keyspace queries.
|
||||
query := session.Query(stmt, keyspaceName)
|
||||
query.RoutingKey([]byte{})
|
||||
iter := query.Iter()
|
||||
iter := session.control.query(stmt, keyspaceName)
|
||||
|
||||
tables := []TableMetadata{}
|
||||
table := TableMetadata{Keyspace: keyspaceName}
|
||||
|
@ -560,11 +544,7 @@ func getColumnMetadata(
|
|||
|
||||
var indexOptionsJSON []byte
|
||||
|
||||
query := session.Query(stmt, keyspaceName)
|
||||
// Set a routing key to avoid GetRoutingKey from computing the routing key
|
||||
// TODO use a separate connection (pool) for system keyspace queries.
|
||||
query.RoutingKey([]byte{})
|
||||
iter := query.Iter()
|
||||
iter := session.control.query(stmt, keyspaceName)
|
||||
|
||||
for scan(iter, &column, &indexOptionsJSON) {
|
||||
var err error
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
"sync/atomic"
|
||||
)
|
||||
|
||||
//RetryableQuery is an interface that represents a query or batch statement that
|
||||
//exposes the correct functions for the retry policy logic to evaluate correctly.
|
||||
// RetryableQuery is an interface that represents a query or batch statement that
|
||||
// exposes the correct functions for the retry policy logic to evaluate correctly.
|
||||
type RetryableQuery interface {
|
||||
Attempts() int
|
||||
GetConsistency() Consistency
|
||||
|
@ -48,8 +48,8 @@ func (s *SimpleRetryPolicy) Attempt(q RetryableQuery) bool {
|
|||
return q.Attempts() <= s.NumRetries
|
||||
}
|
||||
|
||||
//HostSelectionPolicy is an interface for selecting
|
||||
//the most appropriate host to execute a given query.
|
||||
// HostSelectionPolicy is an interface for selecting
|
||||
// the most appropriate host to execute a given query.
|
||||
type HostSelectionPolicy interface {
|
||||
SetHosts
|
||||
SetPartitioner
|
||||
|
@ -57,11 +57,12 @@ type HostSelectionPolicy interface {
|
|||
Pick(*Query) NextHost
|
||||
}
|
||||
|
||||
//NextHost is an iteration function over picked hosts
|
||||
// NextHost is an iteration function over picked hosts
|
||||
type NextHost func() *HostInfo
|
||||
|
||||
//NewRoundRobinHostPolicy is a round-robin load balancing policy
|
||||
func NewRoundRobinHostPolicy() HostSelectionPolicy {
|
||||
// RoundRobinHostPolicy is a round-robin load balancing policy, where each host
|
||||
// is tried sequentially for each query.
|
||||
func RoundRobinHostPolicy() HostSelectionPolicy {
|
||||
return &roundRobinHostPolicy{hosts: []HostInfo{}}
|
||||
}
|
||||
|
||||
|
@ -105,8 +106,10 @@ func (r *roundRobinHostPolicy) Pick(qry *Query) NextHost {
|
|||
}
|
||||
}
|
||||
|
||||
//NewTokenAwareHostPolicy is a token aware host selection policy
|
||||
func NewTokenAwareHostPolicy(fallback HostSelectionPolicy) HostSelectionPolicy {
|
||||
// TokenAwareHostPolicy is a token aware host selection policy, where hosts are
|
||||
// selected based on the partition key, so queries are sent to the host which
|
||||
// owns the partition. Fallback is used when routing information is not available.
|
||||
func TokenAwareHostPolicy(fallback HostSelectionPolicy) HostSelectionPolicy {
|
||||
return &tokenAwareHostPolicy{fallback: fallback, hosts: []HostInfo{}}
|
||||
}
|
||||
|
||||
|
@ -227,8 +230,10 @@ type roundRobinConnPolicy struct {
|
|||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewRoundRobinConnPolicy() ConnSelectionPolicy {
|
||||
return &roundRobinConnPolicy{}
|
||||
func RoundRobinConnPolicy() func() ConnSelectionPolicy {
|
||||
return func() ConnSelectionPolicy {
|
||||
return &roundRobinConnPolicy{}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roundRobinConnPolicy) SetConns(conns []*Conn) {
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
// and automatically sets a default consinstency level on all operations
|
||||
// that do not have a consistency level set.
|
||||
type Session struct {
|
||||
Pool ConnectionPool
|
||||
pool *policyConnPool
|
||||
cons Consistency
|
||||
pageSize int
|
||||
prefetch float64
|
||||
|
@ -38,6 +38,8 @@ type Session struct {
|
|||
hostSource *ringDescriber
|
||||
mu sync.RWMutex
|
||||
|
||||
control *controlConn
|
||||
|
||||
cfg ClusterConfig
|
||||
|
||||
closeMu sync.RWMutex
|
||||
|
@ -60,47 +62,48 @@ func NewSession(cfg ClusterConfig) (*Session, error) {
|
|||
cfg.NumStreams = maxStreams
|
||||
}
|
||||
|
||||
pool, err := cfg.ConnPoolType(&cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//Adjust the size of the prepared statements cache to match the latest configuration
|
||||
stmtsLRU.Lock()
|
||||
initStmtsLRU(cfg.MaxPreparedStmts)
|
||||
stmtsLRU.Unlock()
|
||||
|
||||
s := &Session{
|
||||
Pool: pool,
|
||||
cons: cfg.Consistency,
|
||||
prefetch: 0.25,
|
||||
cfg: cfg,
|
||||
pageSize: cfg.PageSize,
|
||||
}
|
||||
|
||||
pool, err := cfg.PoolConfig.buildPool(&s.cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.pool = pool
|
||||
|
||||
//See if there are any connections in the pool
|
||||
if pool.Size() > 0 {
|
||||
s.routingKeyInfoCache.lru = lru.New(cfg.MaxRoutingKeyInfo)
|
||||
|
||||
s.SetConsistency(cfg.Consistency)
|
||||
s.SetPageSize(cfg.PageSize)
|
||||
|
||||
if cfg.DiscoverHosts {
|
||||
s.hostSource = &ringDescriber{
|
||||
session: s,
|
||||
dcFilter: cfg.Discovery.DcFilter,
|
||||
rackFilter: cfg.Discovery.RackFilter,
|
||||
closeChan: make(chan bool),
|
||||
}
|
||||
|
||||
go s.hostSource.run(cfg.Discovery.Sleep)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
if pool.Size() == 0 {
|
||||
s.Close()
|
||||
return nil, ErrNoConnectionsStarted
|
||||
}
|
||||
|
||||
s.Close()
|
||||
s.routingKeyInfoCache.lru = lru.New(cfg.MaxRoutingKeyInfo)
|
||||
|
||||
return nil, ErrNoConnectionsStarted
|
||||
if !cfg.disableControlConn {
|
||||
s.control = createControlConn(s)
|
||||
}
|
||||
|
||||
if cfg.DiscoverHosts {
|
||||
s.hostSource = &ringDescriber{
|
||||
session: s,
|
||||
dcFilter: cfg.Discovery.DcFilter,
|
||||
rackFilter: cfg.Discovery.RackFilter,
|
||||
closeChan: make(chan bool),
|
||||
}
|
||||
|
||||
go s.hostSource.run(cfg.Discovery.Sleep)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// SetConsistency sets the default consistency level for this session. This
|
||||
|
@ -154,9 +157,10 @@ func (s *Session) Query(stmt string, values ...interface{}) *Query {
|
|||
}
|
||||
|
||||
type QueryInfo struct {
|
||||
Id []byte
|
||||
Args []ColumnInfo
|
||||
Rval []ColumnInfo
|
||||
Id []byte
|
||||
Args []ColumnInfo
|
||||
Rval []ColumnInfo
|
||||
PKeyColumns []int
|
||||
}
|
||||
|
||||
// Bind generates a new query object based on the query statement passed in.
|
||||
|
@ -185,11 +189,15 @@ func (s *Session) Close() {
|
|||
}
|
||||
s.isClosed = true
|
||||
|
||||
s.Pool.Close()
|
||||
s.pool.Close()
|
||||
|
||||
if s.hostSource != nil {
|
||||
close(s.hostSource.closeChan)
|
||||
}
|
||||
|
||||
if s.control != nil {
|
||||
s.control.close()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) Closed() bool {
|
||||
|
@ -210,12 +218,16 @@ func (s *Session) executeQuery(qry *Query) *Iter {
|
|||
qry.attempts = 0
|
||||
qry.totalLatency = 0
|
||||
for {
|
||||
conn := s.Pool.Pick(qry)
|
||||
conn := s.pool.Pick(qry)
|
||||
|
||||
//Assign the error unavailable to the iterator
|
||||
if conn == nil {
|
||||
iter = &Iter{err: ErrNoConnections}
|
||||
break
|
||||
if qry.rt == nil || !qry.rt.Attempt(qry) {
|
||||
iter = &Iter{err: ErrNoConnections}
|
||||
break
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
t := time.Now()
|
||||
|
@ -289,12 +301,12 @@ func (s *Session) routingKeyInfo(stmt string) (*routingKeyInfo, error) {
|
|||
s.routingKeyInfoCache.mu.Unlock()
|
||||
|
||||
var (
|
||||
prepared *resultPreparedFrame
|
||||
info *QueryInfo
|
||||
partitionKey []*ColumnMetadata
|
||||
)
|
||||
|
||||
// get the query info for the statement
|
||||
conn := s.Pool.Pick(nil)
|
||||
conn := s.pool.Pick(nil)
|
||||
if conn == nil {
|
||||
// no connections
|
||||
inflight.err = ErrNoConnections
|
||||
|
@ -303,20 +315,20 @@ func (s *Session) routingKeyInfo(stmt string) (*routingKeyInfo, error) {
|
|||
return nil, inflight.err
|
||||
}
|
||||
|
||||
prepared, inflight.err = conn.prepareStatement(stmt, nil)
|
||||
info, inflight.err = conn.prepareStatement(stmt, nil)
|
||||
if inflight.err != nil {
|
||||
// don't cache this error
|
||||
s.routingKeyInfoCache.Remove(stmt)
|
||||
return nil, inflight.err
|
||||
}
|
||||
|
||||
if len(prepared.reqMeta.columns) == 0 {
|
||||
if len(info.Args) == 0 {
|
||||
// no arguments, no routing key, and no error
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// get the table metadata
|
||||
table := prepared.reqMeta.columns[0].Table
|
||||
table := info.Args[0].Table
|
||||
|
||||
var keyspaceMetadata *KeyspaceMetadata
|
||||
keyspaceMetadata, inflight.err = s.KeyspaceMetadata(s.cfg.Keyspace)
|
||||
|
@ -349,7 +361,7 @@ func (s *Session) routingKeyInfo(stmt string) (*routingKeyInfo, error) {
|
|||
routingKeyInfo.indexes[keyIndex] = -1
|
||||
|
||||
// find the column in the query info
|
||||
for argIndex, boundColumn := range prepared.reqMeta.columns {
|
||||
for argIndex, boundColumn := range info.Args {
|
||||
if keyColumn.Name == boundColumn.Name {
|
||||
// there may be many such bound columns, pick the first
|
||||
routingKeyInfo.indexes[keyIndex] = argIndex
|
||||
|
@ -371,26 +383,25 @@ func (s *Session) routingKeyInfo(stmt string) (*routingKeyInfo, error) {
|
|||
return routingKeyInfo, nil
|
||||
}
|
||||
|
||||
// ExecuteBatch executes a batch operation and returns nil if successful
|
||||
// otherwise an error is returned describing the failure.
|
||||
func (s *Session) ExecuteBatch(batch *Batch) error {
|
||||
func (s *Session) executeBatch(batch *Batch) (*Iter, error) {
|
||||
// fail fast
|
||||
if s.Closed() {
|
||||
return ErrSessionClosed
|
||||
return nil, ErrSessionClosed
|
||||
}
|
||||
|
||||
// Prevent the execution of the batch if greater than the limit
|
||||
// Currently batches have a limit of 65536 queries.
|
||||
// https://datastax-oss.atlassian.net/browse/JAVA-229
|
||||
if batch.Size() > BatchSizeMaximum {
|
||||
return ErrTooManyStmts
|
||||
return nil, ErrTooManyStmts
|
||||
}
|
||||
|
||||
var err error
|
||||
var iter *Iter
|
||||
batch.attempts = 0
|
||||
batch.totalLatency = 0
|
||||
for {
|
||||
conn := s.Pool.Pick(nil)
|
||||
conn := s.pool.Pick(nil)
|
||||
|
||||
//Assign the error unavailable and break loop
|
||||
if conn == nil {
|
||||
|
@ -398,12 +409,12 @@ func (s *Session) ExecuteBatch(batch *Batch) error {
|
|||
break
|
||||
}
|
||||
t := time.Now()
|
||||
err = conn.executeBatch(batch)
|
||||
iter, err = conn.executeBatch(batch)
|
||||
batch.totalLatency += time.Now().Sub(t).Nanoseconds()
|
||||
batch.attempts++
|
||||
//Exit loop if operation executed correctly
|
||||
if err == nil {
|
||||
return nil
|
||||
return iter, err
|
||||
}
|
||||
|
||||
if batch.rt == nil || !batch.rt.Attempt(batch) {
|
||||
|
@ -411,9 +422,59 @@ func (s *Session) ExecuteBatch(batch *Batch) error {
|
|||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ExecuteBatch executes a batch operation and returns nil if successful
|
||||
// otherwise an error is returned describing the failure.
|
||||
func (s *Session) ExecuteBatch(batch *Batch) error {
|
||||
_, err := s.executeBatch(batch)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecuteBatchCAS executes a batch operation and returns nil if successful and
|
||||
// an iterator (to scan aditional rows if more than one conditional statement)
|
||||
// was sent, otherwise an error is returned describing the failure.
|
||||
// Further scans on the interator must also remember to include
|
||||
// the applied boolean as the first argument to *Iter.Scan
|
||||
func (s *Session) ExecuteBatchCAS(batch *Batch, dest ...interface{}) (applied bool, iter *Iter, err error) {
|
||||
if iter, err := s.executeBatch(batch); err == nil {
|
||||
if err := iter.checkErrAndNotFound(); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if len(iter.Columns()) > 1 {
|
||||
dest = append([]interface{}{&applied}, dest...)
|
||||
iter.Scan(dest...)
|
||||
} else {
|
||||
iter.Scan(&applied)
|
||||
}
|
||||
return applied, iter, nil
|
||||
} else {
|
||||
return false, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// MapExecuteBatchCAS executes a batch operation much like ExecuteBatchCAS,
|
||||
// however it accepts a map rather than a list of arguments for the initial
|
||||
// scan.
|
||||
func (s *Session) MapExecuteBatchCAS(batch *Batch, dest map[string]interface{}) (applied bool, iter *Iter, err error) {
|
||||
if iter, err := s.executeBatch(batch); err == nil {
|
||||
if err := iter.checkErrAndNotFound(); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
iter.MapScan(dest)
|
||||
applied = dest["[applied]"].(bool)
|
||||
delete(dest, "[applied]")
|
||||
|
||||
// we usually close here, but instead of closing, just returin an error
|
||||
// if MapScan failed. Although Close just returns err, using Close
|
||||
// here might be confusing as we are not actually closing the iter
|
||||
return applied, iter, iter.err
|
||||
} else {
|
||||
return false, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Query represents a CQL statement that can be executed.
|
||||
type Query struct {
|
||||
stmt string
|
||||
|
@ -717,6 +778,9 @@ type Iter struct {
|
|||
rows [][][]byte
|
||||
meta resultMetadata
|
||||
next *nextIter
|
||||
|
||||
framer *framer
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// Columns returns the name and type of the selected columns.
|
||||
|
@ -790,6 +854,13 @@ func (iter *Iter) Scan(dest ...interface{}) bool {
|
|||
// Close closes the iterator and returns any errors that happened during
|
||||
// the query or the iteration.
|
||||
func (iter *Iter) Close() error {
|
||||
iter.once.Do(func() {
|
||||
if iter.framer != nil {
|
||||
framerPool.Put(iter.framer)
|
||||
iter.framer = nil
|
||||
}
|
||||
})
|
||||
|
||||
return iter.err
|
||||
}
|
||||
|
||||
|
@ -998,29 +1069,40 @@ func (t *traceWriter) Trace(traceId []byte) {
|
|||
coordinator string
|
||||
duration int
|
||||
)
|
||||
t.session.Query(`SELECT coordinator, duration
|
||||
iter := t.session.control.query(`SELECT coordinator, duration
|
||||
FROM system_traces.sessions
|
||||
WHERE session_id = ?`, traceId).
|
||||
Consistency(One).Scan(&coordinator, &duration)
|
||||
WHERE session_id = ?`, traceId)
|
||||
|
||||
iter.Scan(&coordinator, &duration)
|
||||
if err := iter.Close(); err != nil {
|
||||
t.mu.Lock()
|
||||
fmt.Fprintln(t.w, "Error:", err)
|
||||
t.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
iter := t.session.Query(`SELECT event_id, activity, source, source_elapsed
|
||||
FROM system_traces.events
|
||||
WHERE session_id = ?`, traceId).
|
||||
Consistency(One).Iter()
|
||||
var (
|
||||
timestamp time.Time
|
||||
activity string
|
||||
source string
|
||||
elapsed int
|
||||
)
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
fmt.Fprintf(t.w, "Tracing session %016x (coordinator: %s, duration: %v):\n",
|
||||
traceId, coordinator, time.Duration(duration)*time.Microsecond)
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
iter = t.session.control.query(`SELECT event_id, activity, source, source_elapsed
|
||||
FROM system_traces.events
|
||||
WHERE session_id = ?`, traceId)
|
||||
|
||||
for iter.Scan(×tamp, &activity, &source, &elapsed) {
|
||||
fmt.Fprintf(t.w, "%s: %s (source: %s, elapsed: %d)\n",
|
||||
timestamp.Format("2006/01/02 15:04:05.999999"), activity, source, elapsed)
|
||||
}
|
||||
|
||||
if err := iter.Close(); err != nil {
|
||||
fmt.Fprintln(t.w, "Error:", err)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package github
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -211,6 +212,29 @@ func (s *RepositoriesService) GetReleaseAsset(owner, repo string, id int) (*Rele
|
|||
return asset, resp, err
|
||||
}
|
||||
|
||||
// DownloadReleaseAsset downloads a release asset.
|
||||
//
|
||||
// DownloadReleaseAsset returns an io.ReadCloser that reads the contents of the
|
||||
// specified release asset. It is the caller's responsibility to close the ReadCloser.
|
||||
//
|
||||
// GitHub API docs : http://developer.github.com/v3/repos/releases/#get-a-single-release-asset
|
||||
func (s *RepositoriesService) DownloadReleaseAsset(owner, repo string, id int) (io.ReadCloser, error) {
|
||||
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Accept", defaultMediaType)
|
||||
|
||||
resp, err := s.client.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
// EditReleaseAsset edits a repository release asset.
|
||||
//
|
||||
// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release-asset
|
||||
|
|
|
@ -14,6 +14,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
)
|
||||
|
||||
// QueryOptions are used to parameterize a query
|
||||
|
@ -119,7 +121,7 @@ func DefaultConfig() *Config {
|
|||
config := &Config{
|
||||
Address: "127.0.0.1:8500",
|
||||
Scheme: "http",
|
||||
HttpClient: &http.Client{},
|
||||
HttpClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
|
||||
if addr := os.Getenv("CONSUL_HTTP_ADDR"); addr != "" {
|
||||
|
@ -198,12 +200,12 @@ func NewClient(config *Config) (*Client, error) {
|
|||
}
|
||||
|
||||
if parts := strings.SplitN(config.Address, "unix://", 2); len(parts) == 2 {
|
||||
trans := cleanhttp.DefaultTransport()
|
||||
trans.Dial = func(_, _ string) (net.Conn, error) {
|
||||
return net.Dial("unix", parts[1])
|
||||
}
|
||||
config.HttpClient = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Dial: func(_, _ string) (net.Conn, error) {
|
||||
return net.Dial("unix", parts[1])
|
||||
},
|
||||
},
|
||||
Transport: trans,
|
||||
}
|
||||
config.Address = parts[1]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# cleanhttp
|
||||
|
||||
Functions for accessing "clean" Go http.Client values
|
||||
|
||||
-------------
|
||||
|
||||
The Go standard library contains a default `http.Client` called
|
||||
`http.DefaultClient`. It is a common idiom in Go code to start with
|
||||
`http.DefaultClient` and tweak it as necessary, and in fact, this is
|
||||
encouraged; from the `http` package documentation:
|
||||
|
||||
> The Client's Transport typically has internal state (cached TCP connections),
|
||||
so Clients should be reused instead of created as needed. Clients are safe for
|
||||
concurrent use by multiple goroutines.
|
||||
|
||||
Unfortunately, this is a shared value, and it is not uncommon for libraries to
|
||||
assume that they are free to modify it at will. With enough dependencies, it
|
||||
can be very easy to encounter strange problems and race conditions due to
|
||||
manipulation of this shared value across libraries and goroutines (clients are
|
||||
safe for concurrent use, but writing values to the client struct itself is not
|
||||
protected).
|
||||
|
||||
Making things worse is the fact that a bare `http.Client` will use a default
|
||||
`http.Transport` called `http.DefaultTransport`, which is another global value
|
||||
that behaves the same way. So it is not simply enough to replace
|
||||
`http.DefaultClient` with `&http.Client{}`.
|
||||
|
||||
This repository provides some simple functions to get a "clean" `http.Client`
|
||||
-- one that uses the same default values as the Go standard library, but
|
||||
returns a client that does not share any state with other clients.
|
28
Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/cleanhttp.go
generated
vendored
Normal file
28
Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/cleanhttp.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
package cleanhttp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultTransport returns a new http.Transport with the same default values
|
||||
// as http.DefaultTransport
|
||||
func DefaultTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultClient returns a new http.Client with the same default values as
|
||||
// http.Client, but with a non-shared Transport
|
||||
func DefaultClient() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: DefaultTransport(),
|
||||
}
|
||||
}
|
|
@ -215,9 +215,7 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
|
|||
}
|
||||
|
||||
if len(v) == 0 {
|
||||
err = ci.Close()
|
||||
ci.closed = true
|
||||
return nil, err
|
||||
return nil, ci.Close()
|
||||
}
|
||||
|
||||
numValues := len(v)
|
||||
|
@ -240,9 +238,10 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
|
|||
}
|
||||
|
||||
func (ci *copyin) Close() (err error) {
|
||||
if ci.closed {
|
||||
return errCopyInClosed
|
||||
if ci.closed { // Don't do anything, we're already closed
|
||||
return nil
|
||||
}
|
||||
ci.closed = true
|
||||
|
||||
if ci.cn.bad {
|
||||
return driver.ErrBadConn
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
2
Godeps/_workspace/src/golang.org/x/oauth2/clientcredentials/clientcredentials.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/oauth2/clientcredentials/clientcredentials.go
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
|
Loading…
Reference in New Issue